mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 14:31:02 +00:00 
			
		
		
		
	This PR adds opentelemetry and chi wrapper to have basic instrumentation <!--start release-notes-assistant--> ## Draft release notes <!--URL:https://codeberg.org/forgejo/forgejo--> - Features - [PR](https://codeberg.org/forgejo/forgejo/pulls/3972): <!--number 3972 --><!--line 0 --><!--description YWRkIHN1cHBvcnQgZm9yIGJhc2ljIHJlcXVlc3QgdHJhY2luZyB3aXRoIG9wZW50ZWxlbWV0cnk=-->add support for basic request tracing with opentelemetry<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3972 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Co-authored-by: TheFox0x7 <thefox0x7@gmail.com> Co-committed-by: TheFox0x7 <thefox0x7@gmail.com>
		
			
				
	
	
		
			98 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2024 TheFox0x7. All rights reserved.
 | |
| // SPDX-License-Identifier: EUPL-1.2
 | |
| 
 | |
| package opentelemetry
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"crypto/tls"
 | |
| 
 | |
| 	"code.gitea.io/gitea/modules/setting"
 | |
| 
 | |
| 	"go.opentelemetry.io/otel"
 | |
| 	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
 | |
| 	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
 | |
| 	"go.opentelemetry.io/otel/sdk/resource"
 | |
| 	sdktrace "go.opentelemetry.io/otel/sdk/trace"
 | |
| 	"google.golang.org/grpc/credentials"
 | |
| )
 | |
| 
 | |
| func newGrpcExporter(ctx context.Context) (sdktrace.SpanExporter, error) {
 | |
| 	endpoint := setting.OpenTelemetry.OtelTraces.Endpoint
 | |
| 
 | |
| 	opts := []otlptracegrpc.Option{}
 | |
| 
 | |
| 	tlsConf := &tls.Config{}
 | |
| 	opts = append(opts, otlptracegrpc.WithEndpoint(endpoint.Host))
 | |
| 	opts = append(opts, otlptracegrpc.WithTimeout(setting.OpenTelemetry.OtelTraces.Timeout))
 | |
| 	switch setting.OpenTelemetry.OtelTraces.Endpoint.Scheme {
 | |
| 	case "http", "unix":
 | |
| 		opts = append(opts, otlptracegrpc.WithInsecure())
 | |
| 	}
 | |
| 
 | |
| 	if setting.OpenTelemetry.OtelTraces.Compression != "" {
 | |
| 		opts = append(opts, otlptracegrpc.WithCompressor(setting.OpenTelemetry.OtelTraces.Compression))
 | |
| 	}
 | |
| 	withCertPool(setting.OpenTelemetry.OtelTraces.Certificate, tlsConf)
 | |
| 	withClientCert(setting.OpenTelemetry.OtelTraces.ClientCertificate, setting.OpenTelemetry.OtelTraces.ClientKey, tlsConf)
 | |
| 	if tlsConf.RootCAs != nil || len(tlsConf.Certificates) > 0 {
 | |
| 		opts = append(opts, otlptracegrpc.WithTLSCredentials(
 | |
| 			credentials.NewTLS(tlsConf),
 | |
| 		))
 | |
| 	}
 | |
| 	opts = append(opts, otlptracegrpc.WithHeaders(setting.OpenTelemetry.OtelTraces.Headers))
 | |
| 
 | |
| 	return otlptracegrpc.New(ctx, opts...)
 | |
| }
 | |
| 
 | |
| func newHTTPExporter(ctx context.Context) (sdktrace.SpanExporter, error) {
 | |
| 	endpoint := setting.OpenTelemetry.OtelTraces.Endpoint
 | |
| 	opts := []otlptracehttp.Option{}
 | |
| 	tlsConf := &tls.Config{}
 | |
| 	opts = append(opts, otlptracehttp.WithEndpoint(endpoint.Host))
 | |
| 	switch setting.OpenTelemetry.OtelTraces.Endpoint.Scheme {
 | |
| 	case "http", "unix":
 | |
| 		opts = append(opts, otlptracehttp.WithInsecure())
 | |
| 	}
 | |
| 	switch setting.OpenTelemetry.OtelTraces.Compression {
 | |
| 	case "gzip":
 | |
| 		opts = append(opts, otlptracehttp.WithCompression(otlptracehttp.GzipCompression))
 | |
| 	default:
 | |
| 		opts = append(opts, otlptracehttp.WithCompression(otlptracehttp.NoCompression))
 | |
| 	}
 | |
| 	withCertPool(setting.OpenTelemetry.OtelTraces.Certificate, tlsConf)
 | |
| 	withClientCert(setting.OpenTelemetry.OtelTraces.ClientCertificate, setting.OpenTelemetry.OtelTraces.ClientKey, tlsConf)
 | |
| 	if tlsConf.RootCAs != nil || len(tlsConf.Certificates) > 0 {
 | |
| 		opts = append(opts, otlptracehttp.WithTLSClientConfig(tlsConf))
 | |
| 	}
 | |
| 	opts = append(opts, otlptracehttp.WithHeaders(setting.OpenTelemetry.OtelTraces.Headers))
 | |
| 
 | |
| 	return otlptracehttp.New(ctx, opts...)
 | |
| }
 | |
| 
 | |
| var exporter = map[string]func(context.Context) (sdktrace.SpanExporter, error){
 | |
| 	"http/protobuf": newHTTPExporter,
 | |
| 	"grpc":          newGrpcExporter,
 | |
| }
 | |
| 
 | |
| // Create new and register trace provider from user defined configuration
 | |
| func setupTraceProvider(ctx context.Context, r *resource.Resource) (func(context.Context) error, error) {
 | |
| 	var shutdown func(context.Context) error
 | |
| 	switch setting.OpenTelemetry.Traces {
 | |
| 	case "otlp":
 | |
| 		traceExporter, err := exporter[setting.OpenTelemetry.OtelTraces.Protocol](ctx)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		traceProvider := sdktrace.NewTracerProvider(
 | |
| 			sdktrace.WithSampler(setting.OpenTelemetry.Sampler),
 | |
| 			sdktrace.WithBatcher(traceExporter),
 | |
| 			sdktrace.WithResource(r),
 | |
| 		)
 | |
| 		otel.SetTracerProvider(traceProvider)
 | |
| 		shutdown = traceProvider.Shutdown
 | |
| 	default:
 | |
| 		shutdown = func(ctx context.Context) error { return nil }
 | |
| 	}
 | |
| 	return shutdown, nil
 | |
| }
 |