Skip to content

Commit

Permalink
Merge pull request #1335 from Permify/ufuk/otelhistogram
Browse files Browse the repository at this point in the history
feat: histograms added
  • Loading branch information
tolgaOzen authored Jul 7, 2024
2 parents b5d61de + 500b83f commit 0d5e570
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 20 deletions.
26 changes: 20 additions & 6 deletions internal/engines/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ type CheckEngineWithCache struct {
cache cache.Cache

// Metrics
cacheCounter api.Int64Counter
cacheCounter api.Int64Counter
cacheHitDurationHistogram api.Int64Histogram
}

// NewCheckEngineWithCache creates a new instance of EngineKeyManager by initializing an EngineKeys
Expand All @@ -43,11 +44,22 @@ func NewCheckEngineWithCache(
panic(err)
}

// Cache Hit Duration Histogram
cacheHitDurationHistogram, err := meter.Int64Histogram(
"cache_hit_duration",
api.WithUnit("microseconds"),
api.WithDescription("Duration of cache hits in microseconds"),
)
if err != nil {
panic(err)
}

return &CheckEngineWithCache{
schemaReader: schemaReader,
checker: checker,
cache: cache,
cacheCounter: cacheCounter,
schemaReader: schemaReader,
checker: checker,
cache: cache,
cacheCounter: cacheCounter,
cacheHitDurationHistogram: cacheHitDurationHistogram,
}
}

Expand Down Expand Up @@ -77,6 +89,7 @@ func (c *CheckEngineWithCache) Check(ctx context.Context, request *base.Permissi

// Increase the check count in the metrics.
c.cacheCounter.Add(ctx, 1)

// If the request doesn't have the exclusion flag set, return the cached result.
return &base.PermissionCheckResponse{
Can: res.GetCan(),
Expand All @@ -96,11 +109,12 @@ func (c *CheckEngineWithCache) Check(ctx context.Context, request *base.Permissi
}, err
}

// Add to histogram the response

c.setCheckKey(request, &base.PermissionCheckResponse{
Can: cres.GetCan(),
Metadata: &base.PermissionCheckResponseMetadata{},
}, isRelational)

// Return the result of the permission check.
return cres, err
}
Expand Down
106 changes: 92 additions & 14 deletions internal/invoke/invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package invoke

import (
"context"
"time"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
Expand Down Expand Up @@ -73,6 +74,11 @@ type DirectInvoker struct {
lookupEntityCounter api.Int64Counter
lookupSubjectCounter api.Int64Counter
subjectPermissionCounter api.Int64Counter

checkDurationHistogram api.Int64Histogram
lookupEntityDurationHistogram api.Int64Histogram
lookupSubjectDurationHistogram api.Int64Histogram
subjectPermissionDurationHistogram api.Int64Histogram
}

// NewDirectInvoker is a constructor for DirectInvoker.
Expand Down Expand Up @@ -110,17 +116,57 @@ func NewDirectInvoker(
panic(err)
}

checkDurationHistogram, err := meter.Int64Histogram(
"check_duration",
api.WithUnit("microseconds"),
api.WithDescription("Duration of check duration in microseconds"),
)
if err != nil {
panic(err)
}

lookupEntityDurationHistogram, err := meter.Int64Histogram(
"lookup_entity_duration",
api.WithUnit("microseconds"),
api.WithDescription("Duration of lookup entity duration in microseconds"),
)
if err != nil {
panic(err)
}

lookupSubjectDurationHistogram, err := meter.Int64Histogram(
"lookup_subject_duration",
api.WithUnit("microseconds"),
api.WithDescription("Duration of lookup subject duration in microseconds"),
)
if err != nil {
panic(err)
}

subjectPermissionDurationHistogram, err := meter.Int64Histogram(
"subject_permission_duration",
api.WithUnit("microseconds"),
api.WithDescription("Duration of subject permission duration in microseconds"),
)
if err != nil {
panic(err)
}

return &DirectInvoker{
schemaReader: schemaReader,
dataReader: dataReader,
cc: cc,
ec: ec,
lo: lo,
sp: sp,
checkCounter: checkCounter,
lookupEntityCounter: lookupEntityCounter,
lookupSubjectCounter: lookupSubjectCounter,
subjectPermissionCounter: subjectPermissionCounter,
schemaReader: schemaReader,
dataReader: dataReader,
cc: cc,
ec: ec,
lo: lo,
sp: sp,
checkCounter: checkCounter,
lookupEntityCounter: lookupEntityCounter,
lookupSubjectCounter: lookupSubjectCounter,
subjectPermissionCounter: subjectPermissionCounter,
checkDurationHistogram: checkDurationHistogram,
lookupEntityDurationHistogram: lookupEntityDurationHistogram,
lookupSubjectDurationHistogram: lookupSubjectDurationHistogram,
subjectPermissionDurationHistogram: subjectPermissionDurationHistogram,
}
}

Expand All @@ -136,6 +182,8 @@ func (invoker *DirectInvoker) Check(ctx context.Context, request *base.Permissio
))
defer span.End()

start := time.Now()

// Validate the depth of the request.
err = checkDepth(request)
if err != nil {
Expand Down Expand Up @@ -200,6 +248,9 @@ func (invoker *DirectInvoker) Check(ctx context.Context, request *base.Permissio
},
}, err
}
duration := time.Now().Sub(start)

invoker.checkDurationHistogram.Record(ctx, duration.Microseconds())

// Increase the check count in the response metadata.
response.Metadata = increaseCheckCount(response.Metadata)
Expand Down Expand Up @@ -257,6 +308,8 @@ func (invoker *DirectInvoker) LookupEntity(ctx context.Context, request *base.Pe
))
defer span.End()

start := time.Now()

// Set SnapToken if not provided
if request.GetMetadata().GetSnapToken() == "" { // Check if the request has a SnapToken.
var st token.SnapToken
Expand All @@ -279,10 +332,15 @@ func (invoker *DirectInvoker) LookupEntity(ctx context.Context, request *base.Pe
}
}

resp, err := invoker.lo.LookupEntity(ctx, request)

duration := time.Now().Sub(start)
invoker.lookupEntityDurationHistogram.Record(ctx, duration.Microseconds())

// Increase the lookup entity count in the metrics.
invoker.lookupEntityCounter.Add(ctx, 1)

return invoker.lo.LookupEntity(ctx, request)
return resp, err
}

// LookupEntityStream is a method that implements the LookupEntityStream interface.
Expand All @@ -297,6 +355,8 @@ func (invoker *DirectInvoker) LookupEntityStream(ctx context.Context, request *b
))
defer span.End()

start := time.Now()

// Set SnapToken if not provided
if request.GetMetadata().GetSnapToken() == "" { // Check if the request has a SnapToken.
var st token.SnapToken
Expand All @@ -319,10 +379,15 @@ func (invoker *DirectInvoker) LookupEntityStream(ctx context.Context, request *b
}
}

resp := invoker.lo.LookupEntityStream(ctx, request, server)

duration := time.Now().Sub(start)
invoker.lookupEntityDurationHistogram.Record(ctx, duration.Microseconds())

// Increase the lookup entity count in the metrics.
invoker.lookupEntityCounter.Add(ctx, 1)

return invoker.lo.LookupEntityStream(ctx, request, server)
return resp
}

// LookupSubject is a method of the DirectInvoker structure. It handles the task of looking up subjects
Expand All @@ -336,6 +401,8 @@ func (invoker *DirectInvoker) LookupSubject(ctx context.Context, request *base.P
))
defer span.End()

start := time.Now()

// Check if the request has a SnapToken. If not, a SnapToken is set.
if request.GetMetadata().GetSnapToken() == "" {
// Create an instance of SnapToken
Expand Down Expand Up @@ -364,12 +431,17 @@ func (invoker *DirectInvoker) LookupSubject(ctx context.Context, request *base.P
}
}

resp, err := invoker.lo.LookupSubject(ctx, request)

duration := time.Now().Sub(start)
invoker.lookupSubjectDurationHistogram.Record(ctx, duration.Microseconds())

// Increase the lookup subject count in the metrics.
invoker.lookupSubjectCounter.Add(ctx, 1)

// Call the LookupSubject function of the ls field in the invoker, pass the context and request,
// and return its response and error
return invoker.lo.LookupSubject(ctx, request)
return resp, err
}

// SubjectPermission is a method of the DirectInvoker structure. It handles the task of subject's permissions
Expand All @@ -382,6 +454,8 @@ func (invoker *DirectInvoker) SubjectPermission(ctx context.Context, request *ba
))
defer span.End()

start := time.Now()

// Check if the request has a SnapToken. If not, a SnapToken is set.
if request.GetMetadata().GetSnapToken() == "" {
// Create an instance of SnapToken
Expand Down Expand Up @@ -409,11 +483,15 @@ func (invoker *DirectInvoker) SubjectPermission(ctx context.Context, request *ba
return response, err
}
}
resp, err := invoker.sp.SubjectPermission(ctx, request)

duration := time.Now().Sub(start)
invoker.subjectPermissionDurationHistogram.Record(ctx, duration.Microseconds())

// Increase the subject permission count in the metrics.
invoker.subjectPermissionCounter.Add(ctx, 1)

// Call the SubjectPermission function of the ls field in the invoker, pass the context and request,
// and return its response and error
return invoker.sp.SubjectPermission(ctx, request)
return resp, err
}

0 comments on commit 0d5e570

Please sign in to comment.