Skip to content

Latest commit

 

History

History
123 lines (95 loc) · 3.28 KB

File metadata and controls

123 lines (95 loc) · 3.28 KB

observability

Tier: Platform · Status: Full · Java original: firefly-otel-spring-boot-starter · .NET project: FireflyFramework.Observability

Overview

observability provides three orthogonal concerns:

  1. Structured logging — a slog.Logger builder that auto-enriches every record with the correlation id from kernel.WithCorrelationID.
  2. Health indicators — composable Indicator values with a Composite aggregator producing the canonical UP / DEGRADED / DOWN / UNKNOWN rollup.
  3. Startup banner — the ASCII Firefly banner + version + runtime identifying line.

OpenTelemetry SDK wiring (exporters, sampling, resource attributes) is left to the application's main.go — this module exposes only the building blocks that compose with go.opentelemetry.io/otel.

Public surface

Logging

type LogConfig struct {
    Level   slog.Level
    Output  io.Writer
    Service string
    Format  string  // "json" | "text"
}
func DefaultLogConfig() LogConfig
func NewLogger(cfg LogConfig) *slog.Logger

The returned logger wraps a CorrelationHandler so every record gets a correlationId attribute when one is on the context.

Health

type Status string  // StatusUp | StatusDegraded | StatusDown | StatusUnknown

type HealthResult struct {
    Status   Status
    Message  string
    Details  map[string]any
    Duration time.Duration
    Time     time.Time
}

type Indicator interface {
    Name() string
    Check(ctx context.Context) HealthResult
}

type IndicatorFunc struct {
    NameValue string
    Fn        func(ctx context.Context) HealthResult
}

type Composite struct{ ... }
func NewComposite() *Composite
func (*Composite) Add(Indicator)
func (*Composite) CheckAll(ctx) (Status, map[string]HealthResult)

The composite rollup is DOWN if any indicator is DOWN, else DEGRADED if any is DEGRADED, else UP.

Banner

func PrintBanner(w io.Writer, starter, app string)

Emits the ASCII art + framework version + runtime identifier. Called by startercore.Core.PrintBanner() on startup.

Quick start

import (
    "context"
    "log/slog"
    "github.com/fireflyframework/fireflyframework-go/kernel"
    "github.com/fireflyframework/fireflyframework-go/observability"
)

log := observability.NewLogger(observability.LogConfig{
    Service: "orders",
    Format:  "json",
    Level:   slog.LevelInfo,
})

ctx := kernel.WithCorrelationID(context.Background(), "abc-123")
log.InfoContext(ctx, "placed order", "id", "42")
// {"time":"…","level":"INFO","msg":"placed order","service":"orders","correlationId":"abc-123","id":"42"}

health := observability.NewComposite()
health.Add(observability.IndicatorFunc{
    NameValue: "db",
    Fn: func(ctx context.Context) observability.HealthResult {
        if err := db.PingContext(ctx); err != nil {
            return observability.HealthResult{Status: observability.StatusDown, Message: err.Error()}
        }
        return observability.HealthResult{Status: observability.StatusUp}
    },
})
overall, results := health.CheckAll(ctx)

The actuator module mounts this Composite on /actuator/health.

Testing

cd observability
go test ./...

Covers JSON-format correlation-id emission, the degraded ⊕ up overall computation, and banner content.