fxtrace

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2024 License: MIT Imports: 11 Imported by: 1

README

Fx Trace Module

ci go report codecov Deps PkgGoDev

Fx module for trace.

Installation

go get github.com/ankorstore/yokai/fxtrace

Documentation

Dependencies

This module is intended to be used alongside the fxconfig module.

Loading

To load the module in your Fx application:

package main

import (
	"context"

	"github.com/ankorstore/yokai/config"
	"github.com/ankorstore/yokai/fxconfig"
	"github.com/ankorstore/yokai/fxtrace"
	oteltrace "go.opentelemetry.io/otel/trace"
	"go.uber.org/fx"
)

func main() {
	fx.New(
		fxconfig.FxConfigModule, // load the module dependency
		fxtrace.FxTraceModule,   // load the module
		fx.Invoke(func(tracerProvider oteltrace.TracerProvider) {
			// invoke the tracer provider to create a span
			_, span := tracerProvider.Tracer("some tracer").Start(context.Background(), "some span")
			defer span.End()
		}),
	).Run()
}
Configuration

This module provides the possibility to configure the processor:

  • noop: to async void traces (default and fallback)
  • stdout: to async print traces to stdout
  • otlp-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 the sampler:

  • parent-based-always-on: always on depending on parent (default)
  • parent-based-always-off: always off depending on parent
  • parent-based-trace-id-ratio: trace id ratio based depending on parent
  • always-on: always on
  • always-off: always off
  • trace-id-ratio: trace id ratio based

Example with stdout processor (with pretty print) and parent-based-trace-id-ratio sampler (ratio=0.5):

# ./configs/config.yaml
app:
  name: app
  env: dev
  version: 0.1.0
  debug: false
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 (on jaeger:4317 host) and always-on sampler:

# ./configs/config.yaml
app:
  name: app
  env: dev
  version: 0.1.0
  debug: false
modules:
  trace:
    processor:
      type: otlp-grpc
      options:
        host: jaeger:4317
    sampler:
      type: always-on
Override

By default, the oteltrace.TracerProvider is created by the DefaultTracerProviderFactory.

If needed, you can provide your own factory and override the module:

package main

import (
	"context"

	"github.com/ankorstore/yokai/fxconfig"
	"github.com/ankorstore/yokai/fxtrace"
	"github.com/ankorstore/yokai/trace"
	otelsdktrace "go.opentelemetry.io/otel/sdk/trace"
	oteltrace "go.opentelemetry.io/otel/trace"
	"go.uber.org/fx"
)

type CustomTracerProviderFactory struct{}

func NewCustomTracerProviderFactory() trace.TracerProviderFactory {
	return &CustomTracerProviderFactory{}
}

func (f *CustomTracerProviderFactory) Create(options ...trace.TracerProviderOption) (*otelsdktrace.TracerProvider, error) {
	return &otelsdktrace.TracerProvider{...}, nil
}

func main() {
	fx.New(
		fxconfig.FxConfigModule,                     // load the module dependency
		fxtrace.FxTraceModule,                       // load the module
		fx.Decorate(NewCustomTracerProviderFactory), // override the module with a custom factory
		fx.Invoke(func(tracerProvider oteltrace.TracerProvider) { // invoke the custom tracer provider
			_, span := tracerProvider.Tracer("custom tracer").Start(context.Background(), "custom span")
			defer span.End()
		}),
	).Run()
}
Testing

This module provides the possibility to easily test your trace spans, using the TestTraceExporter with modules.trace.processor.type=test.

# ./configs/config.test.yaml
modules:
  trace:
    processor:
      type: test # to send traces to test buffer

You can then test:

package main_test

import (
	"context"
	"testing"

	"github.com/ankorstore/yokai/fxconfig"
	"github.com/ankorstore/yokai/fxtrace"
	"github.com/ankorstore/yokai/trace/tracetest"
	"go.opentelemetry.io/otel/attribute"
	oteltrace "go.opentelemetry.io/otel/trace"
	"go.uber.org/fx"
	"go.uber.org/fx/fxtest"
)

func TestTracerProvider(t *testing.T) {
	t.Setenv("APP_NAME", "test")
	t.Setenv("APP_ENV", "test")

	var exporter tracetest.TestTraceExporter

	fxtest.New(
		t,
		fx.NopLogger,
		fxconfig.FxConfigModule,
		fxtrace.FxTraceModule,
		fx.Invoke(func(tracerProvider oteltrace.TracerProvider) {
			_, span := tracerProvider.Tracer("some tracer").Start(
				context.Background(),
				"some span",
				oteltrace.WithAttributes(attribute.String("some attribute name", "some attribute value")),
			)
			defer span.End()
		}),
		fx.Populate(&exporter), // extracts the TestTraceExporter from the Fx container
	).RequireStart().RequireStop()

	// assertion success
	tracetest.AssertHasTraceSpan(t, exporter, "some span", attribute.String("some attribute name", "some attribute value"))
}

See the trace module testing documentation for more details.

Documentation

Index

Constants

View Source
const ModuleName = "trace"

ModuleName is the module name.

Variables

FxTraceModule is the Fx trace module.

Functions

func NewFxTracerProvider

func NewFxTracerProvider(p FxTraceParam) (*otelsdktrace.TracerProvider, error)

NewFxTracerProvider returns a otelsdktrace.TracerProvider.

Types

type FxTraceParam

type FxTraceParam struct {
	fx.In
	LifeCycle fx.Lifecycle
	Factory   trace.TracerProviderFactory
	Exporter  tracetest.TestTraceExporter
	Config    *config.Config
}

FxTraceParam allows injection of the required dependencies in NewFxTracerProvider.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL