Files

82 lines
1.6 KiB
Go

package tracing
import (
"context"
"fmt"
"time"
)
// Tracer provides distributed tracing
type Tracer struct {
serviceName string
}
// NewTracer creates a new tracer
func NewTracer(serviceName string) *Tracer {
return &Tracer{serviceName: serviceName}
}
// Span represents a trace span
type Span struct {
TraceID string
SpanID string
ParentID string
Name string
StartTime time.Time
EndTime time.Time
Tags map[string]string
Logs []LogEntry
}
// LogEntry represents a log entry in a span
type LogEntry struct {
Timestamp time.Time
Fields map[string]interface{}
}
// StartSpan starts a new span
func (t *Tracer) StartSpan(ctx context.Context, name string) (*Span, context.Context) {
traceID := generateID()
spanID := generateID()
span := &Span{
TraceID: traceID,
SpanID: spanID,
Name: name,
StartTime: time.Now(),
Tags: make(map[string]string),
Logs: []LogEntry{},
}
// Add to context
ctx = context.WithValue(ctx, "trace_id", traceID)
ctx = context.WithValue(ctx, "span_id", spanID)
return span, ctx
}
// Finish finishes a span
func (s *Span) Finish() {
s.EndTime = time.Now()
// In production, this would send span to tracing backend
}
// SetTag sets a tag on the span
func (s *Span) SetTag(key, value string) {
s.Tags[key] = value
}
// Log adds a log entry to the span
func (s *Span) Log(fields map[string]interface{}) {
s.Logs = append(s.Logs, LogEntry{
Timestamp: time.Now(),
Fields: fields,
})
}
// generateID generates a random ID
func generateID() string {
return fmt.Sprintf("%x", time.Now().UnixNano())
}