Skip to content

Commit

Permalink
internal/appsec/waf: retrieve and store WAF metrics for grpc
Browse files Browse the repository at this point in the history
  • Loading branch information
Hellzy committed Mar 31, 2022
1 parent 37877aa commit e3ccfa0
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
20 changes: 18 additions & 2 deletions internal/appsec/waf.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,11 @@ func newGRPCWAFEventListener(handle *waf.Handle, _ []string, timeout time.Durati
// receive unlimited number of messages where we could find security events
const maxWAFEventsPerRequest = 10
var (
nbEvents uint32
logOnce sync.Once
nbEvents uint32
logOnce sync.Once
metricsOnce sync.Once
wafRunDuration waf.AtomicDuration
wafBindingsRunDuration waf.AtomicDuration

events []json.RawMessage
mu sync.Mutex
Expand Down Expand Up @@ -199,7 +202,10 @@ func newGRPCWAFEventListener(handle *waf.Handle, _ []string, timeout time.Durati
if md := handlerArgs.Metadata; len(md) > 0 {
values[grpcServerRequestMetadata] = md
}
now := time.Now()
event := runWAF(wafCtx, values, timeout)
wafRunDuration.Add(wafCtx.TotalRuntime())
wafBindingsRunDuration.Add(uint64(time.Since(now).Nanoseconds()))
if len(event) == 0 {
return
}
Expand All @@ -210,6 +216,16 @@ func newGRPCWAFEventListener(handle *waf.Handle, _ []string, timeout time.Durati
mu.Unlock()
}))
op.On(grpcsec.OnHandlerOperationFinish(func(op *grpcsec.HandlerOperation, _ grpcsec.HandlerOperationRes) {
op.AddMetric("_dd.appsec.waf.duration", float64(wafRunDuration/1e3))
op.AddMetric("_dd.appsec.waf.duration_ext", float64(wafBindingsRunDuration/1e3))

metricsOnce.Do(func() {
rInfo := handle.RulesetInfo()
op.AddMetric("_dd.appsec.event_rules.version", rInfo.Version)
op.AddMetric("_dd.appsec.event_rules.errors", rInfo.Errors)
op.AddMetric("_dd.appsec.event_rules.loaded", float64(rInfo.Loaded))
op.AddMetric("_dd.appsec.event_rules.error_count", float64(rInfo.Failed))
})
if len(events) > 0 && limiter.Allow() {
op.AddSecurityEvents(events...)
}
Expand Down
13 changes: 9 additions & 4 deletions internal/appsec/waf/waf.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ import (
// Version wrapper type of the WAF version.
type Version C.ddwaf_version

type atomicDuration uint64
// AtomicDuration can be used to perform atomic duration sums thanks to AtomicDuration.Add.
type AtomicDuration uint64

func (d *atomicDuration) add(ns uint64) {
// Add atomically sums the current duration value with `ns` to create a new duration value.
func (d *AtomicDuration) Add(ns uint64) {
atomic.AddUint64((*uint64)(d), ns)
}

Expand Down Expand Up @@ -188,6 +190,7 @@ func (waf *Handle) Addresses() []string {
return waf.addresses
}

// RulesetInfo returns the rules initialization metrics for the current WAF handle
func (waf *Handle) RulesetInfo() RulesetInfo {
rInfo, _ := waf.rulesetInfo.Load().(RulesetInfo)
return rInfo
Expand All @@ -210,7 +213,7 @@ func (waf *Handle) Close() {
// become available. Each request must have its own Context.
type Context struct {
waf *Handle
totalRuntimeNs atomicDuration
totalRuntimeNs AtomicDuration

context C.ddwaf_context
// Mutex protecting the use of context which is not thread-safe.
Expand Down Expand Up @@ -260,7 +263,7 @@ func (c *Context) runWAF(data *wafObject, timeout time.Duration) (matches []byte
// TODO(Julio-Guerra): avoid calling result_free when there's no result
defer C.ddwaf_result_free(&result)
rc := C.ddwaf_run(c.context, data.ctype(), &result, C.uint64_t(timeout/time.Microsecond))
c.totalRuntimeNs.add(uint64(result.total_runtime))
c.totalRuntimeNs.Add(uint64(result.total_runtime))
return goReturnValues(rc, &result)
}

Expand All @@ -273,6 +276,8 @@ func (c *Context) Close() {
decNbLiveCObjects()
}

// TotalRuntime returns the cumulated waf runtime across various run calls within the same WAF context.
// Returned time is in nanoseconds.
func (c *Context) TotalRuntime() uint64 {
return uint64(c.totalRuntimeNs)
}
Expand Down

0 comments on commit e3ccfa0

Please sign in to comment.