-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This MR Adds OpenTelemetry based tracing to Protect. It uses [autoprop](https://pkg.go.dev/go.opentelemetry.io/contrib/propagators/autoprop) and [autoexport](https://pkg.go.dev/go.opentelemetry.io/contrib/exporters/autoexport). This makes it configurable with the OTEL SDK configuration properties. This maybe makes it a bit harder to configure as configuration is not done via protect.yml, but it does allow automatic instrumentation if the OTEL environment variables are set in the runtime environments. If desired, I can also remove the autoconfiguration and make it all dependant on protect.yml, but this will extend the config by quite a bit and we will have to keep updating the config and code with newer options that we don't necessarily use for our own usecase.
- Loading branch information
Showing
9 changed files
with
251 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Tracing | ||
|
||
Graphql Protect now supports OpenTelemetry-based tracing, enhancing observability and monitoring capabilities. | ||
Although the instrumentation is currently limited, it enables the creation of new spans that can be exported to | ||
any OTLP-compatible exporter. | ||
|
||
## Exporting Traces | ||
|
||
Tracing data exporting relies on [autoexport](https://pkg.go.dev/go.opentelemetry.io/contrib/exporters/autoexport#NewSpanExporter). | ||
Configuration is done via environment variables `OTEL_TRACES_EXPORTER` and `OTEL_EXPORTER_OTLP_PROTOCOL`, which | ||
determine how trace data is exported. For example, setting `OTEL_EXPORTER_OTLP_PROTOCOL` to `grpc` enables gRPC protocol | ||
for exporting data. | ||
|
||
## Header Propagation | ||
|
||
The system uses [autoprop](https://pkg.go.dev/go.opentelemetry.io/contrib/propagators/autoprop) for header propagation, | ||
configured through the `OTEL_PROPAGATORS` environment variable. Supported propagators include tracecontext, baggage, b3, | ||
and others. This configuration determines how trace context is maintained across different service calls. | ||
|
||
## Redacting headers | ||
OpenTelemetry might collect HTTP headers that contain sensitive information or PII which are usually not desirable to be | ||
logged in the traces. By default, OpenTelemetry redacts the following headers: `Authorization, WWW-Authenticate, Proxy-Authenticate | ||
Proxy-Authorization, Cookie, Set-Cookie`. | ||
If desired, additional headers can be redacted in `config.yml`. | ||
```yaml | ||
target: | ||
redacted_headers: | ||
- Some-Private-Header | ||
- Some-Other-Private-Header | ||
``` | ||
### Kubernetes Configuration Example | ||
Below is an example configuration for Kubernetes, replace v0.11.0 with the version of Graphql Protect you are using. | ||
```yaml | ||
... | ||
spec: | ||
template: | ||
spec: | ||
containers: | ||
- name: graphql-protect | ||
image: eu.gcr.io/bolcom-stg-shop-api-a1c/graphql-protect:latest # Replace with the appropriate version | ||
env: | ||
- name: OTEL_EXPORTER_OTLP_PROTOCOL | ||
value: grpc | ||
- name: OTEL_PROPAGATORS | ||
value: b3multi,tracecontext,baggage | ||
... | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package otel | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"go.opentelemetry.io/contrib/exporters/autoexport" | ||
"go.opentelemetry.io/contrib/propagators/autoprop" | ||
"go.opentelemetry.io/otel" | ||
"go.opentelemetry.io/otel/sdk/resource" | ||
"go.opentelemetry.io/otel/sdk/trace" | ||
semconv "go.opentelemetry.io/otel/semconv/v1.24.0" | ||
) | ||
|
||
func SetupOTELSDK(ctx context.Context, version string) (shutdown func(context.Context) error, err error) { | ||
var shutdownFuncs []func(context.Context) error | ||
// shutdown calls cleanup functions registered via shutdownFuncs. | ||
// The errors from the calls are joined. | ||
// Each registered cleanup will be invoked once. | ||
shutdown = func(ctx context.Context) error { | ||
var err error | ||
for _, fn := range shutdownFuncs { | ||
err = errors.Join(err, fn(ctx)) | ||
} | ||
shutdownFuncs = nil | ||
return err | ||
} | ||
|
||
// handleErr calls shutdown for cleanup and makes sure that all errors are returned. | ||
handleErr := func(inErr error) { | ||
err = errors.Join(inErr, shutdown(ctx)) | ||
} | ||
|
||
// NewTextMapPropagator returns a TraceContext and Baggage propagator by | ||
// default. The response of this function can be directly registered with | ||
// the go.opentelemetry.io/otel package. | ||
otel.SetTextMapPropagator(autoprop.NewTextMapPropagator()) | ||
|
||
// Set up trace provider. | ||
tracerProvider, err := newTraceProvider(ctx, version) | ||
if err != nil { | ||
handleErr(err) | ||
return | ||
} | ||
shutdownFuncs = append(shutdownFuncs, tracerProvider.Shutdown) | ||
otel.SetTracerProvider(tracerProvider) | ||
|
||
return | ||
} | ||
|
||
func newTraceProvider(ctx context.Context, version string) (*trace.TracerProvider, error) { | ||
traceExporter, err := autoexport.NewSpanExporter(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
traceProvider := trace.NewTracerProvider( | ||
trace.WithBatcher(traceExporter), | ||
trace.WithResource(resource.NewWithAttributes( | ||
semconv.SchemaURL, | ||
semconv.ServiceVersionKey.String(version), | ||
)), | ||
) | ||
return traceProvider, nil | ||
} |
Oops, something went wrong.