Giter Site home page Giter Site logo

Comments (6)

MrAlias avatar MrAlias commented on July 16, 2024 1

Can you provide a minimal example to reproduce the issue?

from opentelemetry-go.

zergeborg avatar zergeborg commented on July 16, 2024

I tried to put an example together. I created a completely new go project and the symptom is the same:

package main

import (
	"context"
	"errors"
	"net/http"
	"time"

	texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"github.com/uptrace/opentelemetry-go-extra/otelzap"
	"go.opentelemetry.io/contrib/detectors/gcp"
	"go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
	"go.opentelemetry.io/otel/trace"
	"go.uber.org/zap"
)

var otellogger *otelzap.Logger

func main() {

	ctx, _ := context.WithCancel(context.Background())

	logger := zap.NewNop()

	exporter, err := texporter.New(texporter.WithProjectID("YOUR-GCP-PROJECT-ID"))
	if err != nil {
		logger.Fatal("texporter.New: ", zap.Error(err))
	}

	// Identify your application using resource detection
	res, err := resource.New(ctx,
		// Use the GCP resource detector to detect information about the GCP platform
		resource.WithDetectors(gcp.NewDetector()),
		// Keep the default detectors
		resource.WithTelemetrySDK(),
		// Add your own custom attributes to identify your application
		resource.WithAttributes(
			semconv.ServiceNameKey.String("any-service"),
		),
	)
	if errors.Is(err, resource.ErrPartialResource) || errors.Is(err, resource.ErrSchemaURLConflict) {
		logger.Info("error: ", zap.Error(err))
	} else if err != nil {
		logger.Fatal("resource.New: ", zap.Error(err))
	}

	// Create trace provider with the exporter.
	//
	// By default it uses AlwaysSample() which samples all traces.
	// In a production environment or high QPS setup please use
	// probabilistic sampling.
	// Example:
	//   tp := sdktrace.NewTracerProvider(sdktrace.WithSampler(sdktrace.TraceIDRatioBased(0.0001)), ...)
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
		sdktrace.WithResource(res),
	)
	defer tp.Shutdown(ctx) // flushes any pending spans, and closes connections.
	otel.SetTracerProvider(tp)

	otellogger = otelzap.New(logger,
		otelzap.WithMinLevel(zap.DebugLevel),
		otelzap.WithErrorStatusLevel(zap.ErrorLevel),
	)

	server := echo.New()

	server.Use(middleware.Logger())
	server.Use(otelecho.Middleware("any-service-echo"))

	server.Use(middleware.RequestID())

	server.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			timeoutCtx, cancel := context.WithTimeout(c.Request().Context(), time.Duration(600)*time.Second)
			c.SetRequest(c.Request().WithContext(timeoutCtx))
			defer cancel()
			return next(c)
		}
	})

	server.POST("/", HandleRequest)

	defer server.Close()

	server.Start(":8080")
}

func HandleRequest(c echo.Context) error {
	requestTrackingID := c.Response().Header().Get(echo.HeaderXRequestID)

	tracer := otel.GetTracerProvider().Tracer("any-service-trace")

	origCtx := c.Request().Context()

	ctx, span := tracer.Start(origCtx, "HandleRequest",
		trace.WithAttributes(attribute.String(echo.HeaderXRequestID, requestTrackingID)),
		trace.WithNewRoot(),
	)
	defer span.End()

	otellogger.Ctx(ctx).Info("Handling request")

	return c.Blob(http.StatusOK, "text/plain", []byte("Here is a result...."))
}

You can test this locally by sending any POST request to port 8080. I hope this helps

from opentelemetry-go.

pellared avatar pellared commented on July 16, 2024

You have forgotten to set the https://pkg.go.dev/github.com/uptrace/opentelemetry-go-extra/otelzap#WithLoggerProvider option.

from opentelemetry-go.

zergeborg avatar zergeborg commented on July 16, 2024

@pellared Thank you for your quick response.

I tried your suggestion, but it didn't change anything. Now my code creates the zap logger as follows:

	otellogger = otelzap.New(logger,
		otelzap.WithMinLevel(zap.DebugLevel),
		otelzap.WithErrorStatusLevel(zap.ErrorLevel),
		otelzap.WithLoggerProvider(global.GetLoggerProvider()),
	)

But the bug remains the same. The delegate stays unloaded and the logger never emits

from opentelemetry-go.

dmathieu avatar dmathieu commented on July 16, 2024

otelzap.WithLoggerProvider(global.GetLoggerProvider())

This does nothing. It uses the global logger provided, which is not set.
Also, if you look at the doc for WithLoggerProvider, you will see that this option defaults to the global logger provider already.

You need to create and configure a logger provider.

func newLoggerProvider() (*log.LoggerProvider, error) {
logExporter, err := stdoutlog.New()
if err != nil {
return nil, err
}
loggerProvider := log.NewLoggerProvider(
log.WithProcessor(log.NewBatchProcessor(logExporter)),
)
return loggerProvider, nil
}

The provider is this example is configured to send its data to stdout, but you will be able to configure the otlp exporter once it is available if you wish.

And then, either set it as global, or pass it to otelzap with WithLoggerProvider.

global.SetLoggerProvider(loggerProvider)

from opentelemetry-go.

zergeborg avatar zergeborg commented on July 16, 2024

Thank you @dmathieu Indeed that was the problem. After I applied your suggestion, the logs started working, I can see the output in stdout, so I will close the issue.

from opentelemetry-go.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.