Trace Module
Overview
Yokai provides a fxtrace module, allowing your application to produce traces.
It wraps the trace module, based on OpenTelemetry.
Installation
The fxtrace module is automatically loaded by Yokai's core.
When you use a Yokai application template
, you have nothing to install, it's ready to use.
Configuration
This module provides the possibility to configure a processor
:
noop
: to async void traces (default and fallback)stdout
: to async print traces to stdoutotlp-grpc
: to async send traces to OTLP/gRPC collectors (ex: Jaeger, Grafana, etc.)test
: to sync store traces in memory (for testing assertions)
If an error occurs while creating the processor (for example failing OTLP/gRPC connection), the noop
processor will be
used as safety fallback (to prevent outages).
This module also provides possibility to configure a sampler
:
parent-based-always-on
: always on depending on parent (default)parent-based-always-off
: always off depending on parentparent-based-trace-id-ratio
: trace id ratio based depending on parentalways-on
: always onalways-off
: always offtrace-id-ratio
: trace id ratio based
Example with stdout
processor (with pretty print) and parent-based-trace-id-ratio
sampler (ratio=0.5):
modules:
trace:
processor:
type: stdout
options:
pretty: true
sampler:
type: parent-based-trace-id-ratio
options:
ratio: 0.5
Another example with otlp-grpc
processor (sending on jaeger:4317) and always-on
sampler:
modules:
trace:
processor:
type: otlp-grpc
options:
host: jaeger:4317
sampler:
type: always-on
Usage
This module makes available the TracerProvider in Yokai dependency injection system.
It is built on top of OpenTelemetry
, see its documentation for more details about available methods.
You can inject the tracer provider where needed, but it's recommended to use the one carried by the context.Context
when possible (for automatic traces correlation).
Testing
This module provides the possibility to easily test your trace spans, using the TestTraceExporter with modules.trace.processor.type=test
.
You can use the provided test assertion helpers in your tests:
AssertHasTraceSpan
: to assert on exact name and exact attributes matchAssertHasNotTraceSpan
: to assert on exact name and exact attributes non matchAssertContainTraceSpan
: to assert on exact name and partial attributes matchAssertContainNotTraceSpan
: to assert on exact name and partial attributes non match
and use Dump()
to print the current content of the TestTraceExporter.
For example:
package internal_test
import (
"context"
"testing"
"github.com/ankorstore/yokai/trace/tracetest"
"github.com/foo/bar/internal"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"go.uber.org/fx"
)
func TestExample(t *testing.T) {
var traceExporter tracetest.TestTraceExporter
internal.RunTest(
t,
fx.Populate(&traceExporter),
fx.Invoke(func(tracerProvider trace.TracerProvider) {
_, span := tracerProvider.Tracer("example tracer").Start(
context.Background(),
"example span",
trace.WithAttributes(attribute.String("example name", "example value")),
)
defer span.End()
}),
)
//dump spans
traceExporter.Dump()
// trace assertion example
tracetest.AssertHasTraceSpan(
t,
traceExporter,
"example span",
attribute.String("example name", "example value"),
)
}