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()) }