mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
feat: boxo tracing and traceparent support (#9811)
https://www.w3.org/TR/trace-context/ https://github.com/ipfs/bifrost-gateway/issues/68
This commit is contained in:
parent
03a98280e3
commit
f7cab554f9
@ -164,74 +164,5 @@ and outputs it to `rcmgr.json.gz`
|
||||
Default: disabled (not set)
|
||||
|
||||
# Tracing
|
||||
For advanced configuration (e.g. ratio-based sampling), see also: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md
|
||||
|
||||
## `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`
|
||||
- `file` -- appends traces to a JSON file on the filesystem
|
||||
|
||||
Setting this enables OpenTelemetry tracing.
|
||||
|
||||
**NOTE** Tracing support is experimental: releases may contain tracing-related breaking changes.
|
||||
|
||||
Default: "" (no exporters)
|
||||
|
||||
## `OTLP Exporter`
|
||||
Unless specified in this section, the OTLP exporter uses the environment variables documented here: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md
|
||||
|
||||
### `OTEL_EXPORTER_OTLP_PROTOCOL`
|
||||
Specifies the OTLP protocol to use, which is one of:
|
||||
|
||||
- `grpc`
|
||||
- `http/protobuf`
|
||||
|
||||
Default: "grpc"
|
||||
|
||||
## `Jaeger Exporter`
|
||||
|
||||
See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#jaeger-exporter
|
||||
|
||||
## `Zipkin Exporter`
|
||||
See: 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"
|
||||
|
||||
### How to use Jaeger UI
|
||||
|
||||
One can use the `jaegertracing/all-in-one` Docker image to run a full Jaeger
|
||||
stack and configure Kubo 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 Kubo with Jaeger tracing enabled:
|
||||
```
|
||||
$ OTEL_TRACES_EXPORTER=jaeger ipfs daemon
|
||||
```
|
||||
|
||||
Finally, the [Jaeger UI](https://github.com/jaegertracing/jaeger-ui#readme) is available at http://localhost:16686
|
||||
|
||||
## `OTEL_PROPAGATORS`
|
||||
|
||||
See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration
|
||||
For tracing configuration, please check: https://github.com/ipfs/boxo/blob/main/docs/tracing.md
|
||||
|
||||
@ -7,7 +7,7 @@ go 1.18
|
||||
replace github.com/ipfs/kubo => ./../../..
|
||||
|
||||
require (
|
||||
github.com/ipfs/boxo v0.8.0
|
||||
github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e
|
||||
github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
|
||||
github.com/libp2p/go-libp2p v0.27.0
|
||||
github.com/multiformats/go-multiaddr v0.9.0
|
||||
|
||||
@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs=
|
||||
github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA=
|
||||
github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw=
|
||||
github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
|
||||
|
||||
12
go.mod
12
go.mod
@ -16,7 +16,7 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/ipfs/boxo v0.8.0
|
||||
github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e
|
||||
github.com/ipfs/go-block-format v0.1.2
|
||||
github.com/ipfs/go-cid v0.4.1
|
||||
github.com/ipfs/go-cidutil v0.1.0
|
||||
@ -75,11 +75,6 @@ require (
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0
|
||||
go.opentelemetry.io/contrib/propagators/autoprop v0.40.0
|
||||
go.opentelemetry.io/otel v1.14.0
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.14.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.14.0
|
||||
go.opentelemetry.io/otel/sdk v1.14.0
|
||||
go.opentelemetry.io/otel/trace v1.14.0
|
||||
go.uber.org/dig v1.16.1
|
||||
@ -208,8 +203,13 @@ require (
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.15.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.15.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/ot v1.15.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v0.37.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||
github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs=
|
||||
github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA=
|
||||
github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e h1:8wmBhjwJk2drWZjNwoN7uc+IkG+N93laIhjY69rjMqw=
|
||||
github.com/ipfs/boxo v0.8.1-0.20230411232920-5d6c73c8e35e/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI=
|
||||
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
|
||||
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
|
||||
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
|
||||
"go.opentelemetry.io/otel/sdk/trace"
|
||||
)
|
||||
|
||||
// fileExporter wraps a file-writing exporter and closes the file when the exporter is shutdown.
|
||||
type fileExporter struct {
|
||||
file *os.File
|
||||
writerExporter *stdouttrace.Exporter
|
||||
}
|
||||
|
||||
func newFileExporter(file string) (*fileExporter, error) {
|
||||
f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening '%s' for OpenTelemetry file exporter: %w", file, err)
|
||||
}
|
||||
stdoutExporter, err := stdouttrace.New(stdouttrace.WithWriter(f))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &fileExporter{
|
||||
writerExporter: stdoutExporter,
|
||||
file: f,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *fileExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {
|
||||
return e.writerExporter.ExportSpans(ctx, spans)
|
||||
}
|
||||
|
||||
func (e *fileExporter) Shutdown(ctx context.Context) error {
|
||||
if err := e.writerExporter.Shutdown(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.file.Close(); err != nil {
|
||||
return fmt.Errorf("closing trace file: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -3,16 +3,10 @@ package tracing
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/ipfs/boxo/tracing"
|
||||
version "github.com/ipfs/kubo"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/jaeger"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||||
"go.opentelemetry.io/otel/exporters/zipkin"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
"go.opentelemetry.io/otel/sdk/trace"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
||||
@ -33,87 +27,9 @@ type noopShutdownTracerProvider struct{ traceapi.TracerProvider }
|
||||
|
||||
func (n *noopShutdownTracerProvider) Shutdown(ctx context.Context) error { return nil }
|
||||
|
||||
func buildExporters(ctx context.Context) ([]trace.SpanExporter, error) {
|
||||
// These env vars are standardized but not yet supported by opentelemetry-go.
|
||||
// Once supported, we can remove most of this code.
|
||||
//
|
||||
// Specs:
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#exporter-selection
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md
|
||||
var exporters []trace.SpanExporter
|
||||
for _, exporterStr := range strings.Split(os.Getenv("OTEL_TRACES_EXPORTER"), ",") {
|
||||
switch exporterStr {
|
||||
case "otlp":
|
||||
protocol := "http/protobuf"
|
||||
if v := os.Getenv("OTEL_EXPORTER_OTLP_PROTOCOL"); v != "" {
|
||||
protocol = v
|
||||
}
|
||||
if v := os.Getenv("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"); v != "" {
|
||||
protocol = v
|
||||
}
|
||||
|
||||
switch protocol {
|
||||
case "http/protobuf":
|
||||
exporter, err := otlptracehttp.New(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("building OTLP HTTP exporter: %w", err)
|
||||
}
|
||||
exporters = append(exporters, exporter)
|
||||
case "grpc":
|
||||
exporter, err := otlptracegrpc.New(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("building OTLP gRPC exporter: %w", err)
|
||||
}
|
||||
exporters = append(exporters, exporter)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown or unsupported OTLP exporter '%s'", exporterStr)
|
||||
}
|
||||
case "jaeger":
|
||||
exporter, err := jaeger.New(jaeger.WithCollectorEndpoint())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("building Jaeger exporter: %w", err)
|
||||
}
|
||||
exporters = append(exporters, exporter)
|
||||
case "zipkin":
|
||||
exporter, err := zipkin.New("")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("building Zipkin exporter: %w", err)
|
||||
}
|
||||
exporters = append(exporters, exporter)
|
||||
case "file":
|
||||
// This is not part of the spec, but provided for convenience
|
||||
// so that you don't have to setup a collector,
|
||||
// and because we don't support the stdout exporter.
|
||||
filePath := os.Getenv("OTEL_EXPORTER_FILE_PATH")
|
||||
if filePath == "" {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("finding working directory for the OpenTelemetry file exporter: %w", err)
|
||||
}
|
||||
filePath = path.Join(cwd, "traces.json")
|
||||
}
|
||||
exporter, err := newFileExporter(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
exporters = append(exporters, exporter)
|
||||
case "none":
|
||||
continue
|
||||
case "":
|
||||
continue
|
||||
case "stdout":
|
||||
// stdout is already used for certain kinds of logging, so we don't support this
|
||||
fallthrough
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown or unsupported exporter '%s'", exporterStr)
|
||||
}
|
||||
}
|
||||
return exporters, nil
|
||||
}
|
||||
|
||||
// NewTracerProvider creates and configures a TracerProvider.
|
||||
func NewTracerProvider(ctx context.Context) (shutdownTracerProvider, error) {
|
||||
exporters, err := buildExporters(ctx)
|
||||
exporters, err := tracing.NewSpanExporters(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user