generated from ipfs/ipfs-repository-template
-
Notifications
You must be signed in to change notification settings - Fork 148
feat(gateway): trace context header support #256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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,142 @@ | ||
| # Tracing | ||
|
|
||
| Tracing across the stack follows, as much as possible, the [Open Telemetry] | ||
| specifications. Configuration environment variables are specified in the | ||
| [OpenTelemetry Environment Variable Specification]. | ||
|
|
||
| We use the [opentelemtry-go] package, which currently does not have default support | ||
| for the `OTEL_TRACES_EXPORTER` environment variables. Therefore, we provide some | ||
| helper functions under [`boxo/tracing`](../tracing/) to support these. | ||
|
|
||
| In this document, we document the quirks of our custom support for the `OTEL_TRACES_EXPORTER`, | ||
| as well as examples on how to use tracing, create traceable headers, and how | ||
| to use the Jaeger UI. The [Gateway examples](../examples/gateway/) fully support Tracing. | ||
|
|
||
| - [Environment Variables](#environment-variables) | ||
| - [`OTEL_TRACES_EXPORTER`](#otel_traces_exporter) | ||
| - [`OTLP Exporter`](#otlp-exporter) | ||
| - [`Jaeger Exporter`](#jaeger-exporter) | ||
| - [`Zipkin Exporter`](#zipkin-exporter) | ||
| - [`File Exporter`](#file-exporter) | ||
| - [`OTEL_PROPAGATORS`](#otel_propagators) | ||
| - [Using Jaeger UI](#using-jaeger-ui) | ||
| - [Generate `traceparent` Header](#generate-traceparent-header) | ||
|
|
||
| ## Environment Variables | ||
|
|
||
| For advanced configurations, such as ratio-based sampling, please see also the | ||
| [OpenTelemetry Environment Variable Specification]. | ||
|
|
||
| ### `OTEL_TRACES_EXPORTER` | ||
|
|
||
| Specifies the exporters to use as a comma-separated string. Each exporter has a | ||
| set of additional environment variables used to configure it. The following values | ||
| are supported: | ||
|
|
||
| - `otlp` | ||
| - `jaeger` | ||
| - `zipkin` | ||
| - `stdout` | ||
| - `file` -- appends traces to a JSON file on the filesystem | ||
|
|
||
| Default: `""` (no exporters) | ||
|
|
||
| ### `OTLP Exporter` | ||
|
|
||
| Unless specified in this section, the OTLP exporter uses the environment variables | ||
| documented in [OpenTelemetry Protocol Exporter]. | ||
|
|
||
| #### `OTEL_EXPORTER_OTLP_PROTOCOL` | ||
| Specifies the OTLP protocol to use, which is one of: | ||
|
|
||
| - `grpc` | ||
| - `http/protobuf` | ||
|
|
||
| Default: `"grpc"` | ||
|
|
||
| ### `Jaeger Exporter` | ||
|
|
||
| See [Jaeger Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#jaeger-exporter). | ||
|
|
||
| ### `Zipkin Exporter` | ||
|
|
||
| See [Zipkin Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#zipkin-exporter). | ||
|
|
||
| ### `File Exporter` | ||
|
|
||
| #### `OTEL_EXPORTER_FILE_PATH` | ||
|
|
||
| Specifies the filesystem path for the JSON file. | ||
|
|
||
| Default: `"$PWD/traces.json"` | ||
|
|
||
| ### `OTEL_PROPAGATORS` | ||
|
|
||
| See [General SDK Configuration](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration). | ||
|
|
||
| ## Using Jaeger UI | ||
|
|
||
| One can use the `jaegertracing/all-in-one` Docker image to run a full Jaeger stack | ||
| and configure the Kubo daemon, or gateway examples, to publish traces to it. Here, in an | ||
| ephemeral container: | ||
|
|
||
| ```console | ||
| $ docker run --rm -it --name jaeger \ | ||
| -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ | ||
| -p 5775:5775/udp \ | ||
| -p 6831:6831/udp \ | ||
| -p 6832:6832/udp \ | ||
| -p 5778:5778 \ | ||
| -p 16686:16686 \ | ||
| -p 14268:14268 \ | ||
| -p 14269:14269 \ | ||
| -p 14250:14250 \ | ||
| -p 9411:9411 \ | ||
| jaegertracing/all-in-one | ||
| ``` | ||
|
|
||
| Then, in other terminal, start the app that uses `boxo/tracing` internally (e.g., a Kubo daemon), with Jaeger exporter enabled: | ||
|
|
||
| ``` | ||
| $ OTEL_TRACES_EXPORTER=jaeger ipfs daemon | ||
| ``` | ||
|
|
||
| Finally, the [Jaeger UI] is available at http://localhost:16686. | ||
|
|
||
| ## Generate `traceparent` Header | ||
|
|
||
| If you want to trace a specific request and want to have its tracing ID, you can | ||
| generate a `Traceparent` header. According to the [Trace Context] specification, | ||
hacdias marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| the header is formed as follows: | ||
|
|
||
| > ``` | ||
| > version-format = trace-id "-" parent-id "-" trace-flags | ||
| > trace-id = 32HEXDIGLC ; 16 bytes array identifier. All zeroes forbidden | ||
| > parent-id = 16HEXDIGLC ; 8 bytes array identifier. All zeroes forbidden | ||
| > trace-flags = 2HEXDIGLC ; 8 bit flags. Currently, only one bit is used. See below for details | ||
| > ``` | ||
|
|
||
| To generate a valid `Traceparent` header value, the following script can be used: | ||
|
|
||
| ```bash | ||
| version="00" # fixed in spec at 00 | ||
| trace_id="$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 32 | head -n 1)" | ||
| parent_id="00$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 14 | head -n 1)" | ||
| trace_flag="01" # sampled | ||
| traceparent="$version-$trace_id-$parent_id-$trace_flag" | ||
| echo $traceparent | ||
| ``` | ||
|
|
||
| **NOTE**: the `tr` command behaves differently on macOS. You may want to install | ||
| the GNU `tr` (`gtr`) and use it instead. | ||
|
|
||
| Then, the value can be passed onto the request with `curl -H "Traceparent: $traceparent" URL`. | ||
| If using Jaeger, you can now search by the trace with ID `$trace_id` and see | ||
| the complete trace of this request. | ||
|
|
||
| [Open Telemetry]: https://opentelemetry.io/ | ||
| [opentelemetry-go]: https://github.com/open-telemetry/opentelemetry-go | ||
| [Trace Context]: https://www.w3.org/TR/trace-context | ||
| [OpenTelemetry Environment Variable Specification]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md | ||
| [OpenTelemetry Protocol Exporter]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md | ||
| [Jaeger UI]: https://github.com/jaegertracing/jaeger-ui | ||
This file contains hidden or 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 hidden or 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 hidden or 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,61 @@ | ||
| package common | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "github.com/ipfs/boxo/tracing" | ||
| "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.4.0" | ||
| ) | ||
|
|
||
| // SetupTracing sets up the tracing based on the OTEL_* environment variables, | ||
| // and the provided service name. It returns a trace.TracerProvider. | ||
| func SetupTracing(ctx context.Context, serviceName string) (*trace.TracerProvider, error) { | ||
| tp, err := NewTracerProvider(ctx, serviceName) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| // Sets the default trace provider for this process. If this is not done, tracing | ||
| // will not be enabled. Please note that this will apply to the entire process | ||
| // as it is set as the default tracer, as per OTel recommendations. | ||
| otel.SetTracerProvider(tp) | ||
|
|
||
| // Configures the default propagators used by the Open Telemetry library. By | ||
| // using autoprop.NewTextMapPropagator, we ensure the value of the environmental | ||
| // variable OTEL_PROPAGATORS is respected, if set. By default, Trace Context | ||
| // and Baggage are used. More details on: | ||
| // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md | ||
| otel.SetTextMapPropagator(autoprop.NewTextMapPropagator()) | ||
|
|
||
| return tp, nil | ||
| } | ||
|
|
||
| // NewTracerProvider creates and configures a TracerProvider. | ||
| func NewTracerProvider(ctx context.Context, serviceName string) (*trace.TracerProvider, error) { | ||
| exporters, err := tracing.NewSpanExporters(ctx) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| options := []trace.TracerProviderOption{} | ||
|
|
||
| for _, exporter := range exporters { | ||
| options = append(options, trace.WithBatcher(exporter)) | ||
| } | ||
|
|
||
| r, err := resource.Merge( | ||
| resource.Default(), | ||
| resource.NewSchemaless( | ||
| semconv.ServiceNameKey.String(serviceName), | ||
| ), | ||
| ) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| options = append(options, trace.WithResource(r)) | ||
| return trace.NewTracerProvider(options...), nil | ||
| } |
This file contains hidden or 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 hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.