Adding metrics¶
In this lab, we'll add a metric (counter) that increments each time the incoming requests include a header called hello.
Configuring the pluginContext¶
First, let's open main.go and update the pluginContext to include the helloHeaderCounter:
type pluginContext struct {
  // Embed the default plugin context here,
  // so that we don't need to reimplement all the methods.
  types.DefaultPluginContext
  additionalHeaders  map[string]string
  contextID          uint32
  helloHeaderCounter proxywasm.MetricCounter
}
Creating the metric¶
With the metric counter in the struct, we can now create it in the NewPluginContext function. We'll call the metric hello_header_counter.
func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext {
  return &pluginContext{contextID: contextID, additionalHeaders: map[string]string{}, helloHeaderCounter: proxywasm.DefineCounterMetric("hello_header_counter")}
}
Since we need to check the incoming request headers to decide whether to increment the counter, we need to add the helloHeaderCounter to the httpContext struct as well:
type httpContext struct {
  // Embed the default http context here,
  // so that we don't need to reimplement all the methods.
  types.DefaultHttpContext
  contextID          uint32
  additionalHeaders  map[string]string
  helloHeaderCounter proxywasm.MetricCounter
}
Also, we need to get the counter from the pluginContext and set it when we're creating the new HTTP context:
// Override types.DefaultPluginContext.
func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext {
  return &httpContext{contextID: contextID, additionalHeaders: ctx.additionalHeaders, helloHeaderCounter: ctx.helloHeaderCounter}
}
Incrementing the counter¶
Now that we've piped the helloHeaderCounter all the way through to the httpContext, we can use it in the OnHttpRequestHeaders function:
func (ctx *httpContext) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action {
  proxywasm.LogInfo("OnHttpRequestHeaders")
  _, err := proxywasm.GetHttpRequestHeader("hello") // (1)
  if err != nil {
    // Ignore if header is not set
    return types.ActionContinue
  }
  ctx.helloHeaderCounter.Increment(1) // (2)
  proxywasm.LogInfo("hello_header_counter incremented")
  return types.ActionContinue
}
- 
Retrieving the header called
helloand ignoring the errors if the header is not set - 
Incrementing the
helloHeaderCounterif thehelloheader was present in the request 
Here, we're checking if the "hello" request header is defined (note that we don't care about the header value), and if it's defined, we call the Increment function on the counter instance. Otherwise, we'll ignore it and return ActionContinue if we get an error from the GetHttpRequestHeader call.
Complete main.go
| main.go | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103  |  | 
Let's rebuild the extension again:
We can remove the configuration for the second-extension from the Envoy config and then re-run the Envoy proxy using func-e run -c envoy.yaml &.
Make a couple of requests like this:
You'll notice the log Envoy log entry like this one:
You can also use the admin address on port 8001 to check that Envoy tracks the metric: