generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 7
/
client.go
75 lines (60 loc) · 2.35 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package observability
import (
"context"
"fmt"
"os"
"strings"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
"github.com/TBD54566975/ftl/internal/log"
)
const schemaURL = semconv.SchemaURL
type ExportOTELFlag bool
func (e *ExportOTELFlag) UnmarshalText(text []byte) error {
// Default behaviour of Kong is to use strconv.ParseBool, but we want to be less strict.
v := strings.ToLower(string(text))
*e = ExportOTELFlag(!(v == "false" || v == "0" || v == "no" || v == ""))
return nil
}
type Config struct {
LogLevel log.Level `default:"error" help:"OTEL log level." env:"FTL_O11Y_LOG_LEVEL"`
ExportOTEL ExportOTELFlag `help:"Export observability data to OTEL." env:"OTEL_EXPORTER_OTLP_ENDPOINT"`
}
func Init(ctx context.Context, serviceName, serviceVersion string, config Config) error {
logger := log.FromContext(ctx)
if !config.ExportOTEL {
logger.Tracef("OTEL export is disabled, set OTEL_EXPORTER_OTLP_ENDPOINT to enable")
return nil
}
logger.Debugf("OTEL is enabled, exporting to %s", os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT"))
otelLogger := NewOtelLogger(logger, config.LogLevel)
otel.SetLogger(otelLogger)
otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { logger.Errorf(err, "OTEL") }))
res, err := resource.Merge(resource.Default(),
resource.NewWithAttributes(
schemaURL,
semconv.ServiceName(serviceName),
semconv.ServiceVersion(serviceVersion),
))
if err != nil {
return fmt.Errorf("failed to create OTEL resource: %w", err)
}
otelMetricExporter, err := otlpmetricgrpc.New(ctx)
if err != nil {
return fmt.Errorf("failed to create OTEL metric exporter: %w", err)
}
meterProvider := metric.NewMeterProvider(metric.WithReader(metric.NewPeriodicReader(otelMetricExporter)), metric.WithResource(res))
otel.SetMeterProvider(meterProvider)
otelTraceExporter, err := otlptracegrpc.New(ctx)
if err != nil {
return fmt.Errorf("failed to create OTEL trace exporter: %w", err)
}
traceProvider := trace.NewTracerProvider(trace.WithBatcher(otelTraceExporter), trace.WithResource(res))
otel.SetTracerProvider(traceProvider)
return nil
}