added event wrappers, bug fixes, API improvements
This commit is contained in:
parent
4f4a7e09c5
commit
076196c03e
@ -8,19 +8,17 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.ma-al.com/gora_filip/observer/pkg/tracer"
|
|
||||||
"git.ma-al.com/gora_filip/pkg/attr/layer_attr"
|
"git.ma-al.com/gora_filip/pkg/attr/layer_attr"
|
||||||
|
"git.ma-al.com/gora_filip/pkg/event"
|
||||||
"git.ma-al.com/gora_filip/pkg/exporters"
|
"git.ma-al.com/gora_filip/pkg/exporters"
|
||||||
tracing "git.ma-al.com/gora_filip/pkg/fiber_tracing"
|
tracing "git.ma-al.com/gora_filip/pkg/fiber_tracing"
|
||||||
"git.ma-al.com/gora_filip/pkg/level"
|
"git.ma-al.com/gora_filip/pkg/level"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
main := fiber.New()
|
||||||
main := fiber.New(fiber.Config{
|
|
||||||
StreamRequestBody: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
exps := make([]exporters.TraceExporter, 0)
|
exps := make([]exporters.TraceExporter, 0)
|
||||||
exps = append(exps, exporters.DevConsoleExporter())
|
exps = append(exps, exporters.DevConsoleExporter())
|
||||||
@ -28,7 +26,7 @@ func main() {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
exps = append(exps, gelfExp)
|
exps = append(exps, gelfExp)
|
||||||
}
|
}
|
||||||
jaegerExp, err := exporters.OtlpHTTPExporter()
|
jaegerExp, err := exporters.OtlpHTTPExporter(otlptracehttp.WithEndpointURL("http://localhost:4318/v1/traces"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
exps = append(exps, jaegerExp)
|
exps = append(exps, jaegerExp)
|
||||||
}
|
}
|
||||||
@ -41,26 +39,7 @@ func main() {
|
|||||||
}))
|
}))
|
||||||
defer tracing.ShutdownTracer()
|
defer tracing.ShutdownTracer()
|
||||||
|
|
||||||
main.Get("/", func(c *fiber.Ctx) error {
|
main.Get("/", Handler)
|
||||||
ctx, span := tracing.FStart(c, layer_attr.Handler{
|
|
||||||
Level: level.DEBUG,
|
|
||||||
}.AsOpts())
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
span.AddEvent(
|
|
||||||
"smthing is happening",
|
|
||||||
layer_attr.Handler{
|
|
||||||
Level: level.INFO,
|
|
||||||
}.AsOpts(),
|
|
||||||
)
|
|
||||||
|
|
||||||
err := Serv(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return tracer.RecordError(span, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.SendString("xd")
|
|
||||||
})
|
|
||||||
|
|
||||||
// handle interrupts (shutdown)
|
// handle interrupts (shutdown)
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
@ -77,8 +56,29 @@ func main() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Handler(c *fiber.Ctx) error {
|
||||||
|
ctx, span := tracing.FStart(c, layer_attr.Handler{
|
||||||
|
Level: level.DEBUG,
|
||||||
|
}.AsOpts())
|
||||||
|
defer span.End()
|
||||||
|
event.NewInSpan(event.Event{
|
||||||
|
Level: level.WARN,
|
||||||
|
ShortMessage: "a warning event",
|
||||||
|
}, span)
|
||||||
|
|
||||||
|
err := Serv(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return event.NewErrInSpan(event.Error{Err: err, Level: level.ERR}, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.SendStatus(fiber.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
func Serv(ctx context.Context) *fiber.Error {
|
func Serv(ctx context.Context) *fiber.Error {
|
||||||
ctx, span := tracer.Service(ctx, "service", "service span")
|
ctx, span := tracing.Start(ctx, "service span", layer_attr.Service{
|
||||||
|
Level: level.INFO,
|
||||||
|
Name: "some service",
|
||||||
|
}.AsOpts())
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
for range []int{1, 2, 3} {
|
for range []int{1, 2, 3} {
|
||||||
@ -94,7 +94,10 @@ func Serv(ctx context.Context) *fiber.Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Repo(ctx context.Context) error {
|
func Repo(ctx context.Context) error {
|
||||||
ctx, span := tracer.Repository(ctx, "repo", "repo span")
|
ctx, span := tracing.Start(ctx, "repo span", layer_attr.Repo{
|
||||||
|
Level: level.DEBUG,
|
||||||
|
Name: "some repo",
|
||||||
|
}.AsOpts())
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
for range []int{1, 2, 3} {
|
for range []int{1, 2, 3} {
|
||||||
|
@ -51,6 +51,7 @@ const (
|
|||||||
SessionCurrencyIdKey = attribute.Key("session.currency_id")
|
SessionCurrencyIdKey = attribute.Key("session.currency_id")
|
||||||
ProcessThreadsAvailableKey = attribute.Key("process.threads_available")
|
ProcessThreadsAvailableKey = attribute.Key("process.threads_available")
|
||||||
ServiceLayerKey = attribute.Key("service.layer")
|
ServiceLayerKey = attribute.Key("service.layer")
|
||||||
|
ServiceLayerNameKey = attribute.Key("service.layer_name")
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServiceArchitectureLayer string
|
type ServiceArchitectureLayer string
|
||||||
@ -244,3 +245,10 @@ func ServiceLayer(layer ServiceArchitectureLayer) attribute.KeyValue {
|
|||||||
Value: attribute.StringValue(string(layer)),
|
Value: attribute.StringValue(string(layer)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ServiceLayerName(name string) attribute.KeyValue {
|
||||||
|
return attribute.KeyValue{
|
||||||
|
Key: ServiceLayerNameKey,
|
||||||
|
Value: attribute.StringValue(name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ type Handler struct {
|
|||||||
// Extra attributes to be attached. Can be also added with [Handler.CustomAttrs] method.
|
// Extra attributes to be attached. Can be also added with [Handler.CustomAttrs] method.
|
||||||
Attributes []attribute.KeyValue
|
Attributes []attribute.KeyValue
|
||||||
Level level.SeverityLevel
|
Level level.SeverityLevel
|
||||||
|
Name string
|
||||||
extraSkipInStack int
|
extraSkipInStack int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,6 +19,9 @@ func (h Handler) IntoTraceAttributes() []attribute.KeyValue {
|
|||||||
attrs := make([]attribute.KeyValue, 5+len(h.Attributes))
|
attrs := make([]attribute.KeyValue, 5+len(h.Attributes))
|
||||||
attrs = append(attrs, attr.SourceCodeLocation(1+h.extraSkipInStack)...) // 3 attrs added here
|
attrs = append(attrs, attr.SourceCodeLocation(1+h.extraSkipInStack)...) // 3 attrs added here
|
||||||
attrs = append(attrs, attr.ServiceLayer(attr.LayerHandler), attr.SeverityLevel(h.Level))
|
attrs = append(attrs, attr.ServiceLayer(attr.LayerHandler), attr.SeverityLevel(h.Level))
|
||||||
|
if len(h.Name) > 0 {
|
||||||
|
attrs = append(attrs, attr.ServiceLayerName(h.Name))
|
||||||
|
}
|
||||||
attrs = append(attrs, h.Attributes...)
|
attrs = append(attrs, h.Attributes...)
|
||||||
return attrs
|
return attrs
|
||||||
}
|
}
|
||||||
@ -31,6 +35,12 @@ func (h *Handler) SkipMoreInCallStack(skip int) {
|
|||||||
h.extraSkipInStack += skip
|
h.extraSkipInStack += skip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Works the same as [Handler.IntoTraceAttributes]
|
||||||
|
func (h Handler) AsAttrs() []attribute.KeyValue {
|
||||||
|
h.extraSkipInStack += 1
|
||||||
|
return h.IntoTraceAttributes()
|
||||||
|
}
|
||||||
|
|
||||||
func (h Handler) AsOpts() trace.SpanStartEventOption {
|
func (h Handler) AsOpts() trace.SpanStartEventOption {
|
||||||
h.extraSkipInStack += 1
|
h.extraSkipInStack += 1
|
||||||
return trace.WithAttributes(h.IntoTraceAttributes()...)
|
return trace.WithAttributes(h.IntoTraceAttributes()...)
|
||||||
@ -40,17 +50,27 @@ type Service struct {
|
|||||||
// Extra attributes to be attached. Can be also added with [Service.CustomAttrs] method.
|
// Extra attributes to be attached. Can be also added with [Service.CustomAttrs] method.
|
||||||
Attributes []attribute.KeyValue
|
Attributes []attribute.KeyValue
|
||||||
Level level.SeverityLevel
|
Level level.SeverityLevel
|
||||||
|
Name string
|
||||||
extraSkipInStack int
|
extraSkipInStack int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Service) IntoTraceAttributes() []attribute.KeyValue {
|
func (s Service) IntoTraceAttributes() []attribute.KeyValue {
|
||||||
attrs := make([]attribute.KeyValue, 5+len(s.Attributes))
|
attrs := make([]attribute.KeyValue, 6+len(s.Attributes))
|
||||||
attrs = append(attrs, attr.SourceCodeLocation(1+s.extraSkipInStack)...)
|
attrs = append(attrs, attr.SourceCodeLocation(1+s.extraSkipInStack)...)
|
||||||
attrs = append(attrs, attr.ServiceLayer(attr.LayerService), attr.SeverityLevel(s.Level))
|
attrs = append(attrs, attr.ServiceLayer(attr.LayerService), attr.SeverityLevel(s.Level))
|
||||||
|
if len(s.Name) > 0 {
|
||||||
|
attrs = append(attrs, attr.ServiceLayerName(s.Name))
|
||||||
|
}
|
||||||
attrs = append(attrs, s.Attributes...)
|
attrs = append(attrs, s.Attributes...)
|
||||||
return attrs
|
return attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Works the same as [Service.IntoTraceAttributes]
|
||||||
|
func (s Service) AsAttrs() []attribute.KeyValue {
|
||||||
|
s.extraSkipInStack += 1
|
||||||
|
return s.IntoTraceAttributes()
|
||||||
|
}
|
||||||
|
|
||||||
func (s Service) CustomAttrs(attrs ...interface{}) Service {
|
func (s Service) CustomAttrs(attrs ...interface{}) Service {
|
||||||
s.Attributes = append(s.Attributes, attr.CollectAttributes(attrs...)...)
|
s.Attributes = append(s.Attributes, attr.CollectAttributes(attrs...)...)
|
||||||
return s
|
return s
|
||||||
@ -69,17 +89,27 @@ type Repo struct {
|
|||||||
// Extra attributes to be attached. Can be also added with [Repo.CustomAttrs] method
|
// Extra attributes to be attached. Can be also added with [Repo.CustomAttrs] method
|
||||||
Attributes []attribute.KeyValue
|
Attributes []attribute.KeyValue
|
||||||
Level level.SeverityLevel
|
Level level.SeverityLevel
|
||||||
|
Name string
|
||||||
extraSkipInStack int
|
extraSkipInStack int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Repo) IntoTraceAttributes() []attribute.KeyValue {
|
func (r Repo) IntoTraceAttributes() []attribute.KeyValue {
|
||||||
attrs := make([]attribute.KeyValue, 5+len(r.Attributes))
|
attrs := make([]attribute.KeyValue, 6+len(r.Attributes))
|
||||||
attrs = append(attrs, attr.SourceCodeLocation(1+r.extraSkipInStack)...)
|
attrs = append(attrs, attr.SourceCodeLocation(1+r.extraSkipInStack)...)
|
||||||
attrs = append(attrs, attr.ServiceLayer(attr.LayerRepository), attr.SeverityLevel(r.Level))
|
attrs = append(attrs, attr.ServiceLayer(attr.LayerRepository), attr.SeverityLevel(r.Level))
|
||||||
|
if len(r.Name) > 0 {
|
||||||
|
attrs = append(attrs, attr.ServiceLayerName(r.Name))
|
||||||
|
}
|
||||||
attrs = append(attrs, r.Attributes...)
|
attrs = append(attrs, r.Attributes...)
|
||||||
return attrs
|
return attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Works the same as [Repo.IntoTraceAttributes]
|
||||||
|
func (r Repo) AsAttrs() []attribute.KeyValue {
|
||||||
|
r.extraSkipInStack += 1
|
||||||
|
return r.IntoTraceAttributes()
|
||||||
|
}
|
||||||
|
|
||||||
func (r Repo) CustomAttrs(attrs ...interface{}) Repo {
|
func (r Repo) CustomAttrs(attrs ...interface{}) Repo {
|
||||||
r.Attributes = append(r.Attributes, attr.CollectAttributes(attrs...)...)
|
r.Attributes = append(r.Attributes, attr.CollectAttributes(attrs...)...)
|
||||||
return r
|
return r
|
||||||
|
101
pkg/event/event.go
Normal file
101
pkg/event/event.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package event
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.ma-al.com/gora_filip/pkg/attr"
|
||||||
|
"git.ma-al.com/gora_filip/pkg/level"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An event that maps well to a log message
|
||||||
|
type Event struct {
|
||||||
|
FullMessage string
|
||||||
|
ShortMessage string
|
||||||
|
Attributes []attribute.KeyValue
|
||||||
|
// Defaults to INFO when converted into attributes and unset
|
||||||
|
Level level.SeverityLevel
|
||||||
|
extraSkipInStack int
|
||||||
|
}
|
||||||
|
|
||||||
|
type IntoEvent interface {
|
||||||
|
IntoEvent() Event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Event) IntoEvent() Event {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Event) IntoTraceAttributes() []attribute.KeyValue {
|
||||||
|
attrs := make([]attribute.KeyValue, 0)
|
||||||
|
attrs = append(attrs, attr.SourceCodeLocation(1+e.extraSkipInStack)...)
|
||||||
|
attrs = append(attrs, e.Attributes...)
|
||||||
|
if len(e.FullMessage) > 0 {
|
||||||
|
attrs = append(attrs, attr.LogMessageLong(e.FullMessage))
|
||||||
|
}
|
||||||
|
if len(e.ShortMessage) > 0 {
|
||||||
|
attrs = append(attrs, attr.LogMessageShort(e.ShortMessage))
|
||||||
|
}
|
||||||
|
if e.Level == 0 {
|
||||||
|
e.Level = level.INFO
|
||||||
|
}
|
||||||
|
attrs = append(attrs, attr.SeverityLevel(e.Level))
|
||||||
|
return attrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Event) AsOpts() trace.EventOption {
|
||||||
|
e.extraSkipInStack += 1
|
||||||
|
return trace.WithAttributes(e.IntoTraceAttributes()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInSpan[E IntoEvent](ev E, span trace.Span) {
|
||||||
|
event := ev.IntoEvent()
|
||||||
|
event.extraSkipInStack += 1
|
||||||
|
span.AddEvent(event.ShortMessage, trace.WithAttributes(event.IntoTraceAttributes()...))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
Err error
|
||||||
|
ExtendedMessage string
|
||||||
|
// Defaults to ALERT when converted into attributes and unset
|
||||||
|
Level level.SeverityLevel
|
||||||
|
Attributes []attribute.KeyValue
|
||||||
|
extraSkipInStack int
|
||||||
|
}
|
||||||
|
|
||||||
|
type IntoErrorEvent interface {
|
||||||
|
IntoErrorEvent() Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Error() string {
|
||||||
|
return e.Err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) IntoErrorEvent() Error {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) IntoTraceAttributes() []attribute.KeyValue {
|
||||||
|
attrs := make([]attribute.KeyValue, 0)
|
||||||
|
attrs = append(attrs, e.Attributes...)
|
||||||
|
if len(e.ExtendedMessage) > 0 {
|
||||||
|
attrs = append(attrs, attr.LogMessageLong(e.ExtendedMessage))
|
||||||
|
}
|
||||||
|
if e.Level == 0 {
|
||||||
|
e.Level = level.ALERT
|
||||||
|
}
|
||||||
|
attrs = append(attrs, attr.SeverityLevel(e.Level), attr.LogMessageShort(e.Err.Error()))
|
||||||
|
attrs = append(attrs, attr.SourceCodeLocation(1+e.extraSkipInStack)...)
|
||||||
|
return attrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) AsOpts() trace.EventOption {
|
||||||
|
e.extraSkipInStack += 1
|
||||||
|
return trace.WithAttributes(e.IntoTraceAttributes()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrInSpan[E IntoErrorEvent](err E, span trace.Span) E {
|
||||||
|
er := err.IntoErrorEvent()
|
||||||
|
er.extraSkipInStack += 1
|
||||||
|
span.RecordError(er.Err, er.AsOpts())
|
||||||
|
return err
|
||||||
|
}
|
@ -14,7 +14,7 @@ import (
|
|||||||
type TraceFormatter interface {
|
type TraceFormatter interface {
|
||||||
FormatSpanStart(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error)
|
FormatSpanStart(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error)
|
||||||
FormatSpanEnd(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error)
|
FormatSpanEnd(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error)
|
||||||
FormatEvent(event trace.Event, selectedAttr []attribute.KeyValue, lvl level.SeverityLevel) (string, error)
|
FormatEvent(event trace.Event, span trace.ReadOnlySpan, selectedAttr []attribute.KeyValue, lvl level.SeverityLevel) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration for the exporter.
|
// Configuration for the exporter.
|
||||||
@ -57,7 +57,7 @@ type Processor struct {
|
|||||||
|
|
||||||
// NOTE: The configuration might change in future releases
|
// NOTE: The configuration might change in future releases
|
||||||
func DefaultConsoleExportProcessor() trace.SpanProcessor {
|
func DefaultConsoleExportProcessor() trace.SpanProcessor {
|
||||||
fmt := NewMultilineFormatter()
|
fmt := NewPrettyMultilineFormatter()
|
||||||
return NewProcessor(ProcessorOptions{
|
return NewProcessor(ProcessorOptions{
|
||||||
FilterFromEnvVar: nil,
|
FilterFromEnvVar: nil,
|
||||||
FilterOutFields: []attribute.Key{},
|
FilterOutFields: []attribute.Key{},
|
||||||
@ -85,15 +85,16 @@ func NewProcessor(opts ProcessorOptions) trace.SpanProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &Processor{
|
return &Processor{
|
||||||
traceFormatter: formatter,
|
traceFormatter: formatter,
|
||||||
removedFields: opts.FilterOutFields,
|
removedFields: opts.FilterOutFields,
|
||||||
addTraceId: opts.AddTraceId,
|
addTraceId: opts.AddTraceId,
|
||||||
onlyEvents: opts.EmitEventsOnly,
|
onlyEvents: opts.EmitEventsOnly,
|
||||||
onlyErrs: opts.SkipNonErrors,
|
onlyErrs: opts.SkipNonErrors,
|
||||||
skipSpanStart: opts.SkipEmittingOnSpanStart,
|
skipSpanStart: opts.SkipEmittingOnSpanStart,
|
||||||
skipSpanEnd: opts.SkipEmittingOnSpanEnd,
|
skipSpanEnd: opts.SkipEmittingOnSpanEnd,
|
||||||
skipAttrsOnSpanEnd: opts.SkipAttributesOnSpanEnd,
|
skipAttrsOnSpanEnd: opts.SkipAttributesOnSpanEnd,
|
||||||
lvl: lvl,
|
skipAttrsOnSpanStart: opts.SkippAttributesOnSpanStart,
|
||||||
|
lvl: lvl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +152,7 @@ func (e *Processor) OnEnd(span trace.ReadOnlySpan) {
|
|||||||
filteredAttrs = append(filteredAttrs, attribute.String("trace_id", span.SpanContext().TraceID().String()))
|
filteredAttrs = append(filteredAttrs, attribute.String("trace_id", span.SpanContext().TraceID().String()))
|
||||||
}
|
}
|
||||||
if severityLvl <= e.lvl {
|
if severityLvl <= e.lvl {
|
||||||
eventString, err := e.traceFormatter.FormatEvent(event, filteredAttrs, severityLvl)
|
eventString, err := e.traceFormatter.FormatEvent(event, span, filteredAttrs, severityLvl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("FAILED TO FORMAT TRACE EVENT")
|
fmt.Println("FAILED TO FORMAT TRACE EVENT")
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,6 +2,7 @@ package console_exporter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"git.ma-al.com/gora_filip/pkg/console_fmt"
|
"git.ma-al.com/gora_filip/pkg/console_fmt"
|
||||||
"git.ma-al.com/gora_filip/pkg/level"
|
"git.ma-al.com/gora_filip/pkg/level"
|
||||||
@ -9,16 +10,24 @@ import (
|
|||||||
"go.opentelemetry.io/otel/sdk/trace"
|
"go.opentelemetry.io/otel/sdk/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewMultilineFormatter() TraceFormatter {
|
func NewPrettyMultilineFormatter() TraceFormatter {
|
||||||
return &MultilineFormatter{}
|
return &PrettyMultilineFormatter{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A formatter that will print only events using a multiline format with colors.
|
// A formatter that will print only events using a multiline format with colors.
|
||||||
// It uses attributes from the [attr] and [semconv] packages.
|
// It uses attributes from the [attr] and [semconv] packages.
|
||||||
type MultilineFormatter struct{}
|
type PrettyMultilineFormatter struct{}
|
||||||
|
|
||||||
func (f *MultilineFormatter) FormatSpanStart(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
|
func (f *PrettyMultilineFormatter) FormatSpanStart(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
|
||||||
attrs := ""
|
attrs := ""
|
||||||
|
slices.SortFunc(selectedAttrs, func(a, b attribute.KeyValue) int {
|
||||||
|
if a.Key > b.Key {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
for _, kv := range selectedAttrs {
|
for _, kv := range selectedAttrs {
|
||||||
if len(kv.Key) > 0 {
|
if len(kv.Key) > 0 {
|
||||||
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), kv.Value.AsString())
|
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), kv.Value.AsString())
|
||||||
@ -33,8 +42,16 @@ func (f *MultilineFormatter) FormatSpanStart(span trace.ReadOnlySpan, selectedAt
|
|||||||
|
|
||||||
return formattedSpanString, nil
|
return formattedSpanString, nil
|
||||||
}
|
}
|
||||||
func (f *MultilineFormatter) FormatSpanEnd(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
|
func (f *PrettyMultilineFormatter) FormatSpanEnd(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
|
||||||
attrs := ""
|
attrs := ""
|
||||||
|
slices.SortFunc(selectedAttrs, func(a, b attribute.KeyValue) int {
|
||||||
|
if a.Key > b.Key {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
for _, kv := range selectedAttrs {
|
for _, kv := range selectedAttrs {
|
||||||
if len(kv.Key) > 0 {
|
if len(kv.Key) > 0 {
|
||||||
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), kv.Value.AsString())
|
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), kv.Value.AsString())
|
||||||
@ -50,8 +67,16 @@ func (f *MultilineFormatter) FormatSpanEnd(span trace.ReadOnlySpan, selectedAttr
|
|||||||
return formattedSpanString, nil
|
return formattedSpanString, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
func (f *MultilineFormatter) FormatEvent(event trace.Event, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
|
func (f *PrettyMultilineFormatter) FormatEvent(event trace.Event, span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
|
||||||
attrs := ""
|
attrs := ""
|
||||||
|
slices.SortFunc(selectedAttrs, func(a, b attribute.KeyValue) int {
|
||||||
|
if a.Key > b.Key {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
for _, kv := range selectedAttrs {
|
for _, kv := range selectedAttrs {
|
||||||
if len(kv.Key) > 0 {
|
if len(kv.Key) > 0 {
|
||||||
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), kv.Value.AsString())
|
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), kv.Value.AsString())
|
||||||
|
@ -45,7 +45,8 @@ func Start(ctx context.Context, spanName string, opts ...trace.SpanStartOption)
|
|||||||
|
|
||||||
// NOTE: You can use [trace.WithAttributes] as a parameter to opts argument
|
// NOTE: You can use [trace.WithAttributes] as a parameter to opts argument
|
||||||
func FStart(c *fiber.Ctx, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
func FStart(c *fiber.Ctx, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
||||||
return fiberOpentelemetry.Tracer.Start(c.UserContext(), c.Method()+" "+c.Path(), opts...)
|
ctx := fiberOpentelemetry.FromCtx(c)
|
||||||
|
return fiberOpentelemetry.Tracer.Start(ctx, c.Method()+" "+c.Path(), opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMiddleware(config Config) func(*fiber.Ctx) error {
|
func NewMiddleware(config Config) func(*fiber.Ctx) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user