126 lines
3.0 KiB
Go
126 lines
3.0 KiB
Go
package console_exporter
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"git.ma-al.com/gora_filip/pkg/level"
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/sdk/trace"
|
|
)
|
|
|
|
type TraceFormatter interface {
|
|
FormatSpans(spans []trace.ReadOnlySpan, removeFields []attribute.Key, verbosityLevel level.SeverityLevel, addTraceId bool, onlyErrors bool) (string, error)
|
|
}
|
|
|
|
// Configuration for the exporter.
|
|
//
|
|
// Most of options are passed to the formatter.
|
|
type ExporterOptions struct {
|
|
// Try to parse filters from an environment variable with a name provided by this field.
|
|
// Result will only by applied to unset options. NOT IMPLEMENTED!
|
|
FilterFromEnvVar *string
|
|
// Filter the output based on the [level.SeverityLevel].
|
|
FilterOnLevel *level.SeverityLevel
|
|
// Fields that should be removed from the output.
|
|
FilterOutFields []attribute.Key
|
|
// Print only trace events instead of whole traces.
|
|
EmitEventsOnly bool
|
|
// Add trace id to output
|
|
EmitTraceId bool
|
|
// Print output only when an error is found
|
|
EmitOnlyOnError bool
|
|
// Used only when `EmitEventsOnly` is set to true.
|
|
TraceFormatter *TraceFormatter
|
|
}
|
|
|
|
type Exporter struct {
|
|
lvl level.SeverityLevel
|
|
removedFields []attribute.Key
|
|
addTraceId bool
|
|
onlyErrs bool
|
|
traceFormatter TraceFormatter
|
|
printerMu sync.Mutex
|
|
stoppedMu sync.RWMutex
|
|
stopped bool
|
|
}
|
|
|
|
// NOTE: The configuration might change in future releases
|
|
func DefaultConsoleExporter() trace.SpanExporter {
|
|
lvl := level.DEBUG
|
|
fmt := NewEventsOnlyFormatter()
|
|
return NewExporter(ExporterOptions{
|
|
FilterFromEnvVar: nil,
|
|
FilterOnLevel: &lvl,
|
|
FilterOutFields: []attribute.Key{},
|
|
EmitEventsOnly: false,
|
|
EmitTraceId: true,
|
|
EmitOnlyOnError: false,
|
|
TraceFormatter: &fmt,
|
|
})
|
|
}
|
|
|
|
func NewExporter(opts ExporterOptions) trace.SpanExporter {
|
|
var formatter TraceFormatter
|
|
var lvl level.SeverityLevel
|
|
|
|
if opts.TraceFormatter != nil {
|
|
formatter = *opts.TraceFormatter
|
|
} else {
|
|
formatter = TraceFormatter(&EventsOnlyFormatter{})
|
|
}
|
|
if opts.FilterOnLevel != nil {
|
|
lvl = *opts.FilterOnLevel
|
|
} else {
|
|
lvl = level.TRACE
|
|
}
|
|
|
|
return &Exporter{
|
|
traceFormatter: formatter,
|
|
removedFields: opts.FilterOutFields,
|
|
addTraceId: opts.EmitTraceId,
|
|
onlyErrs: opts.EmitOnlyOnError,
|
|
lvl: lvl,
|
|
}
|
|
}
|
|
|
|
// Implements [trace.SpanExporter]
|
|
func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {
|
|
e.stoppedMu.RLock()
|
|
stopped := e.stopped
|
|
e.stoppedMu.RUnlock()
|
|
if stopped {
|
|
return nil
|
|
}
|
|
if len(spans) == 0 {
|
|
return nil
|
|
}
|
|
|
|
e.printerMu.Lock()
|
|
defer e.printerMu.Unlock()
|
|
printLine, err := e.traceFormatter.FormatSpans(spans, e.removedFields, e.lvl, e.addTraceId, e.onlyErrs)
|
|
if err != nil {
|
|
fmt.Printf("FAILED TO FORMAT A TRACE WITH ERR: %#v\n", err)
|
|
}
|
|
if len(printLine) > 0 {
|
|
fmt.Println(printLine)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Implements [trace.SpanExporter]
|
|
func (e *Exporter) Shutdown(ctx context.Context) error {
|
|
e.stoppedMu.Lock()
|
|
e.stopped = true
|
|
e.stoppedMu.Unlock()
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
default:
|
|
}
|
|
return nil
|
|
}
|