Skip to content

Commit

Permalink
Merge pull request #27 from krakend/static_labels
Browse files Browse the repository at this point in the history
Static labels
  • Loading branch information
dhontecillas authored May 24, 2024
2 parents f01fb8f + 73d1a28 commit 543a5d9
Show file tree
Hide file tree
Showing 15 changed files with 560 additions and 57 deletions.
18 changes: 11 additions & 7 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,22 @@ type LayersOpts struct {
// We can select if we want to disable the metrics,
// the traces, and / or the trace propagation.
type GlobalOpts struct {
DisableMetrics bool `json:"disable_metrics"`
DisableTraces bool `json:"disable_traces"`
DisablePropagation bool `json:"disable_propagation"`
ReportHeaders bool `json:"report_headers"`
DisableMetrics bool `json:"disable_metrics"`
DisableTraces bool `json:"disable_traces"`
DisablePropagation bool `json:"disable_propagation"`
ReportHeaders bool `json:"report_headers"`
MetricsStaticAttributes Attributes `json:"metrics_static_attributes"`
TracesStaticAttributes Attributes `json:"traces_static_attributes"`
}

// PipeOpts has the options for the KrakenD pipe stage
// to disable metrics and traces.
type PipeOpts struct {
DisableMetrics bool `json:"disable_metrics"`
DisableTraces bool `json:"disable_traces"`
ReportHeaders bool `json:"report_headers"`
DisableMetrics bool `json:"disable_metrics"`
DisableTraces bool `json:"disable_traces"`
ReportHeaders bool `json:"report_headers"`
MetricsStaticAttributes Attributes `json:"metrics_static_attributes"`
TracesStaticAttributes Attributes `json:"traces_static_attributes"`
}

// Enabled returns if either metrics or traces are enabled
Expand Down
31 changes: 23 additions & 8 deletions config/lura.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,8 @@ var ErrNoConfig = errors.New("no config found for opentelemetry")
// In case no "Layers" config is provided, a set of defaults with
// everything enabled will be used.
func FromLura(srvCfg luraconfig.ServiceConfig) (*ConfigData, error) {
cfg := new(ConfigData)
tmp, ok := srvCfg.ExtraConfig[Namespace]
if !ok {
return nil, ErrNoConfig
}
buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(tmp)
if err := json.NewDecoder(buf).Decode(cfg); err != nil {
cfg, err := LuraExtraCfg(srvCfg.ExtraConfig)
if err != nil {
return nil, err
}

Expand All @@ -46,3 +40,24 @@ func FromLura(srvCfg luraconfig.ServiceConfig) (*ConfigData, error) {
cfg.UnsetFieldsToDefaults()
return cfg, nil
}

// LuraExtraCfg extracts the extra config field for the namespace if
// provided
func LuraExtraCfg(extraCfg luraconfig.ExtraConfig) (*ConfigData, error) {
tmp, ok := extraCfg[Namespace]
if !ok {
return nil, ErrNoConfig
}

buf := new(bytes.Buffer)
if err := json.NewEncoder(buf).Encode(tmp); err != nil {
return nil, err
}

cfg := new(ConfigData)
if err := json.NewDecoder(buf).Decode(cfg); err != nil {
return nil, err
}

return cfg, nil
}
4 changes: 2 additions & 2 deletions example/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
KRAKEND_LOCAL_IP ?= 192.168.1.12

build:
srv:
go build -o srv ./server
.PHONY: build
.PHONY: srv

image:
docker build -f ./server/Dockerfile -t krakend-otel-example:latest ..
Expand Down
96 changes: 89 additions & 7 deletions example/docker_compose/conf/krakend_back/configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,40 @@
},
{
"endpoint": "/back_combination/{id}",
"extra_config": {
"telemetry/opentelemetry": {
"layers": {
"global": {
"metrics_static_attributes": [
{
"key": "my_metric_global_override_attr",
"value": "my_metric_global_override_val"
}
],
"traces_static_attributes": [
{
"key": "my_trace_global_override_attr",
"value": "my_trace_global_override_val"
}
]
},
"proxy": {
"metrics_static_attributes": [
{
"key": "my_metric_proxy_override_attr",
"value": "my_metric_proxy_override_val"
}
],
,
"traces_static_attributes": [
{
"key": "my_trace_proxy_override_attr",
"value": "my_trace_proxy_override_val"
}
]
}
}
},
"backend": [
{
"host": [
Expand All @@ -37,6 +71,30 @@
"is_collection": true,
"mapping": {
"collection": "posts"
},
"extra_config": {
"telemetry/opentelemetry": {
"layers": {
"backend": {
"metrics": {
"static_attributes": [
{
"key": "my_metric_backend_override_attr",
"value": "my_metric_backend_override_val"
}
]
},
"traces": {
"static_attributes": [
{
"key": "my_trace_backend_override_attr",
"value": "my_trace_backend_override_val"
}
]
}
}
}
}
}
},
{
Expand All @@ -60,12 +118,36 @@
"global": {
"disable_metrics": false,
"disable_traces": false,
"disable_propagation": false
"disable_propagation": false,
"metrics_static_attributes": [
{
"key": "my_metric_global_attr",
"value": "my_metric_global_val"
}
],
"traces_static_attributes": [
{
"key": "my_trace_global_attr",
"value": "my_trace_global_val"
}
]
},
"proxy": {
"disable_metrics": false,
"disable_traces": false
},
"disable_traces": false,
"metrics_static_attributes": [
{
"key": "my_metric_proxy_attr",
"value": "my_metric_proxy_val"
}
],
"traces_static_attributes": [
{
"key": "my_trace_proxy_attr",
"value": "my_trace_proxy_val"
}
]
},
"backend": {
"metrics": {
"disable_stage": false,
Expand All @@ -74,8 +156,8 @@
"detailed_connection": true,
"static_attributes": [
{
"key": "my_metric_attr",
"value": "my_metric_val"
"key": "my_metric_backend_attr",
"value": "my_metric_backend_val"
}
]
},
Expand All @@ -86,8 +168,8 @@
"detailed_connection": true,
"static_attributes": [
{
"key": "my_trace_attr",
"value": "my_trace_val"
"key": "my_trace_backend_attr",
"value": "my_trace_backend_val"
}
]
}
Expand Down
12 changes: 6 additions & 6 deletions http/server/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/semconv/v1.21.0"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"

kotelconfig "github.com/krakend/krakend-otel/config"
)
Expand Down Expand Up @@ -36,11 +36,11 @@ func (m *metricsHTTP) report(t *tracking, r *http.Request) {
if m == nil || m.latency == nil {
return
}
dynAttrsOpts := metric.WithAttributes(
semconv.HTTPRoute(t.EndpointPattern()),
semconv.HTTPRequestMethodKey.String(r.Method),
semconv.HTTPResponseStatusCode(t.responseStatus),
)
dynAttrs := t.metricsStaticAttrs
dynAttrs = append(dynAttrs, semconv.HTTPRoute(t.EndpointPattern()))
dynAttrs = append(dynAttrs, semconv.HTTPRequestMethodKey.String(r.Method))
dynAttrs = append(dynAttrs, semconv.HTTPResponseStatusCode(t.responseStatus))
dynAttrsOpts := metric.WithAttributes(dynAttrs...)
m.latency.Record(t.ctx, t.latencyInSecs, m.fixedAttrsOpts, dynAttrsOpts)
m.size.Record(t.ctx, int64(t.responseSize), m.fixedAttrsOpts, dynAttrsOpts)
}
20 changes: 16 additions & 4 deletions http/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,26 @@ func NewTrackingHandler(next http.Handler) http.Handler {

var m *metricsHTTP
if !gCfg.DisableMetrics {
m = newMetricsHTTP(s.Meter(), []attribute.KeyValue{})
var metricsAttrs []attribute.KeyValue
for _, kv := range gCfg.MetricsStaticAttributes {
if len(kv.Key) > 0 && len(kv.Value) > 0 {
metricsAttrs = append(metricsAttrs, attribute.String(kv.Key, kv.Value))
}
}

m = newMetricsHTTP(s.Meter(), metricsAttrs)
}

var t *tracesHTTP
if !gCfg.DisableTraces {
t = newTracesHTTP(s.Tracer(), []attribute.KeyValue{
attribute.String("krakend.stage", "global"),
}, gCfg.ReportHeaders)
tracesAttrs := []attribute.KeyValue{attribute.String("krakend.stage", "global")}
for _, kv := range gCfg.TracesStaticAttributes {
if len(kv.Key) > 0 && len(kv.Value) > 0 {
tracesAttrs = append(tracesAttrs, attribute.String(kv.Key, kv.Value))
}
}

t = newTracesHTTP(s.Tracer(), tracesAttrs, gCfg.ReportHeaders)
}

return &trackingHandler{
Expand Down
3 changes: 2 additions & 1 deletion http/server/traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/semconv/v1.21.0"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
"go.opentelemetry.io/otel/trace"

otelhttp "github.com/krakend/krakend-otel/http"
Expand Down Expand Up @@ -71,6 +71,7 @@ func (t *tracesHTTP) end(tr *tracking) {
semconv.HTTPRoute(tr.EndpointPattern()),
semconv.HTTPResponseStatusCode(tr.responseStatus),
semconv.HTTPResponseBodySize(tr.responseSize))
tr.span.SetAttributes(tr.tracesStaticAttrs...)

if tr.responseHeaders != nil {
// report all incoming headers
Expand Down
36 changes: 28 additions & 8 deletions http/server/tracking.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"time"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)

Expand All @@ -21,14 +22,16 @@ type tracking struct {
ctx context.Context
span trace.Span

latencyInSecs float64
responseSize int
responseStatus int
responseHeaders map[string][]string
writeErrs []error
endpointPattern string
isHijacked bool
hijackedErr error
latencyInSecs float64
responseSize int
responseStatus int
responseHeaders map[string][]string
writeErrs []error
endpointPattern string
isHijacked bool
metricsStaticAttrs []attribute.KeyValue
tracesStaticAttrs []attribute.KeyValue
hijackedErr error
}

func (t *tracking) EndpointPattern() string {
Expand All @@ -41,6 +44,14 @@ func (t *tracking) EndpointPattern() string {
return t.endpointPattern
}

func (t *tracking) MetricsStaticAttributes() []attribute.KeyValue {
return t.metricsStaticAttrs
}

func (t *tracking) TracesStaticAttributes() []attribute.KeyValue {
return t.tracesStaticAttrs
}

func newTracking() *tracking {
return &tracking{
responseStatus: 200,
Expand All @@ -64,6 +75,15 @@ func SetEndpointPattern(ctx context.Context, endpointPattern string) {
}
}

// SetStaticAttributtes allows to set metrics and traces static attributes in
// the request context
func SetStaticAttributtes(ctx context.Context, metricAttrs, tracesAttrs []attribute.KeyValue) {
if t := fromContext(ctx); t != nil {
t.metricsStaticAttrs = metricAttrs
t.tracesStaticAttrs = tracesAttrs
}
}

func (t *tracking) Start() {
t.startTime = time.Now()
}
Expand Down
Loading

0 comments on commit 543a5d9

Please sign in to comment.