Skip to content
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

[Page Feedback]: Please add Go examples of how to create LoggerProvider for doing recording and asserting in unit tests #6110

Open
jcranfordbeyondtrust opened this issue Jan 29, 2025 · 4 comments
Labels

Comments

@jcranfordbeyondtrust
Copy link

URL

https://opentelemetry.io/docs/specs/otel/logs/sdk_exporters/

Description

Need example of how to create an in-memory log.NewLoggerProvider, for use in unit tests.

Only a stdout exporter is present in the docs.

@jcranfordbeyondtrust
Copy link
Author

I am trying to create otel providers for unit testing, to record in-memory metrics, spans, and logs for doing assertions.

In my example below, I am trying to create them to use in gofiber unit test, but the same use case for recording all 3 probably applies to other libs that support otel instrumentation too.

I found working code for creating TextMapPropagator, MeterProvider, and TracerProvider suitable for unit testing here:

However, there are no examples for recording logs and asserting.

I did a lot of googling, looking through otel docs and code, but I can't find any working code examples for how to create LoggerProvider for capturing logs, and using it for assertions in unit testing.

package main

import (
	"github.com/gofiber/contrib/otelfiber/v2"
	"github.com/gofiber/fiber/v2"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/log/logtest"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/log"
	"go.opentelemetry.io/otel/sdk/metric"
	"go.opentelemetry.io/otel/sdk/trace"
	"go.opentelemetry.io/otel/sdk/trace/tracetest"
	"testing"
)

func TestOtelMetersTracersLoggers(t *testing.T) {
	metricReader := metric.NewManualReader()
	spanRecorder := tracetest.NewSpanRecorder()
	logRecorder := logtest.NewRecorder()

	// Create otel providers suitable for unit testing
	TextMapPropagator := propagation.TraceContext{}
	MeterProvider := metric.NewMeterProvider(metric.WithReader(metricReader))
	TracerProvider := trace.NewTracerProvider(trace.WithSpanProcessor(spanRecorder))
	LoggerProvider := log.NewLoggerProvider(log.WithProcessor(logRecorder)) // COMPILE ERROR: Cannot use logRecorder (type *Recorder) as the type Processor Type does not implement Processor as some methods are missing
	otel.SetTextMapPropagator(TextMapPropagator)
	otel.SetMeterProvider(MeterProvider)
	otel.SetTracerProvider(TracerProvider)
	otel.SetLogger(LoggerProvider) // COMPILE ERROR: Cannot use 'LoggerProvider' (type *LoggerProvider) as the type logr. Logger

	// Try using the above Otel providers in a library
	app := fiber.New()
	app.Use(
		otelfiber.Middleware(
			otelfiber.WithServerName("localhost"),
			otelfiber.WithPort(8080),
			otelfiber.WithCollectClientIP(true),
			otelfiber.WithPropagators(TextMapPropagator),
			otelfiber.WithTracerProvider(TracerProvider),
			otelfiber.WithMeterProvider(MeterProvider),
			otelfiber.WithLoggerProvider(LoggerProvider), // COMPILE ERROR: Unresolved reference 'WithLoggerProvider'
		),
	)
}

It would be great if otel Go docs (and source) could include examples for how to create each of the providers suitable for unit testing. Thank you.

@jcranfordbeyondtrust jcranfordbeyondtrust changed the title [Page Feedback]: summary of your feedback [Page feedback]: ADD A SUMMARY OF YOUR FEEDBACK HERE [Page Feedback]: Please add Go examples of how to create LoggerProvider for doing recording and asserting in unit tests Jan 29, 2025
@jcranfordbeyondtrust
Copy link
Author

jcranfordbeyondtrust commented Jan 29, 2025

Note, https://opentelemetry.io/docs/specs/otel/logs/sdk_exporters/ only lists a Standard output exporter for logger. Unfortunately that isn't what I need.


For tracing, there is a tracetest.NewSpanRecorder. It is suitable for passing into trace.WithSpanProcessor.

TracerProvider := trace.NewTracerProvider(trace.WithSpanProcessor(spanRecorder)) // Compiles OK

For logger, there is a logtest.NewRecorder. That name is similar to tracetest.NewSpanRecorder.

I had hoped logtest.NewRecorder might be usable as log.Processor, but no luck. Unfortunately, I can't seem to use logtest.NewRecorder as a log.Processor or log.Exporter because:

  • logtest.NewRecorder doesn't implement log.Processor methods, so I can't pass it into log.WithProcessor
LoggerProvider := log.NewLoggerProvider(log.WithProcessor(logRecorder)) // Compile fails
  • logtest.NewRecorder doesn't implement log.Exporter methods, so I can't pass it into log.NewSimpleProcessor or log.NewBatchProcessor
LoggerProvider := log.NewLoggerProvider(log.WithProcessor(log.NewSimpleProcessor(logRecorder))) // Compile fails
LoggerProvider := log.NewLoggerProvider(log.WithProcessor(log.NewBatchProcessor(logRecorder))) // Compile fails

@svrnm svrnm added the sig:go label Jan 30, 2025
@svrnm
Copy link
Member

svrnm commented Jan 30, 2025

@open-telemetry/go-approvers PTAL

@pellared
Copy link
Member

pellared commented Feb 13, 2025

@jcranfordbeyondtrust
In otel.io you should check: https://opentelemetry.io/docs/languages/go/instrumentation/#logs-sdk
Then when reading the packages documentation would find two packages that facilitate unit testing:

Probably you want https://pkg.go.dev/go.opentelemetry.io/otel/log/logtest#Recorder for testing instrumentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants