g3

telemetry

import "github.com/afreidah/g3/internal/telemetry"

Index

Constants

TracerName identifies the tracer in OpenTelemetry output.

const TracerName = "g3"

Variables

var (
    AttrRequestID   = attribute.Key("g3.request_id")
    AttrBucket      = attribute.Key("g3.bucket")
    AttrObjectKey   = attribute.Key("g3.key")
    AttrOperation   = attribute.Key("g3.operation")
    AttrObjectSize  = attribute.Key("g3.object.size")
    AttrContentType = attribute.Key("g3.object.content_type")
    AttrGmailMsgID  = attribute.Key("g3.gmail.message_id")
    AttrDriveFileID = attribute.Key("g3.drive.file_id")
    AttrCacheHit    = attribute.Key("g3.cache_hit")
    AttrLabelID     = attribute.Key("g3.gmail.label_id")
    AttrUploadID    = attribute.Key("g3.upload_id")
    AttrPartNumber  = attribute.Key("g3.part_number")
    AttrChunkCount  = attribute.Key("g3.chunk.count")
    AttrChunkIndex  = attribute.Key("g3.chunk.index")
)

AuditEventsTotal counts audit events by event name.

var AuditEventsTotal = promauto.NewCounterVec(
    prometheus.CounterOpts{
        Name: "g3_audit_events_total",
        Help: "Total number of audit events",
    },
    []string{"event"},
)

AuthFailuresTotal counts authentication failures.

var AuthFailuresTotal = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_auth_failures_total",
        Help: "Total number of authentication failures",
    },
)

BackendDuration observes backend operation latency by operation name.

var BackendDuration = promauto.NewHistogramVec(
    prometheus.HistogramOpts{
        Name:    "g3_backend_duration_seconds",
        Help:    "Backend operation latency in seconds",
        Buckets: []float64{.01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10, 30, 60, 120},
    },
    []string{"operation"},
)

BackendRequestsTotal counts backend operations by operation and status.

var BackendRequestsTotal = promauto.NewCounterVec(
    prometheus.CounterOpts{
        Name: "g3_backend_requests_total",
        Help: "Total number of backend operations",
    },
    []string{"operation", "status"},
)

BuildInfo exposes build metadata as a constant gauge.

var BuildInfo = promauto.NewGaugeVec(
    prometheus.GaugeOpts{
        Name: "g3_build_info",
        Help: "Build information",
    },
    []string{"version", "go_version"},
)

DriveAPIDuration observes Drive API request latency by operation.

var DriveAPIDuration = promauto.NewHistogramVec(
    prometheus.HistogramOpts{
        Name:    "g3_drive_api_duration_seconds",
        Help:    "Google Drive API request latency in seconds",
        Buckets: []float64{.05, .1, .25, .5, 1, 2.5, 5, 10, 30, 60},
    },
    []string{"operation"},
)

DriveAPIRequestsTotal counts Drive API calls by operation and status.

var DriveAPIRequestsTotal = promauto.NewCounterVec(
    prometheus.CounterOpts{
        Name: "g3_drive_api_requests_total",
        Help: "Total number of Google Drive API requests",
    },
    []string{"operation", "status"},
)

GmailAPIDuration observes Gmail API request latency by operation.

var GmailAPIDuration = promauto.NewHistogramVec(
    prometheus.HistogramOpts{
        Name:    "g3_gmail_api_duration_seconds",
        Help:    "Gmail API request latency in seconds",
        Buckets: []float64{.05, .1, .25, .5, 1, 2.5, 5, 10, 30},
    },
    []string{"operation"},
)

GmailAPIRequestsTotal counts Gmail API calls by operation and status.

var GmailAPIRequestsTotal = promauto.NewCounterVec(
    prometheus.CounterOpts{
        Name: "g3_gmail_api_requests_total",
        Help: "Total number of Gmail API requests",
    },
    []string{"operation", "status"},
)

GmailStorageBytes tracks estimated storage usage in Gmail.

var GmailStorageBytes = promauto.NewGauge(
    prometheus.GaugeOpts{
        Name: "g3_gmail_storage_bytes",
        Help: "Estimated storage used in Gmail",
    },
)

InflightRequests tracks the number of requests currently being processed.

var InflightRequests = promauto.NewGaugeVec(
    prometheus.GaugeOpts{
        Name: "g3_inflight_requests",
        Help: "Number of requests currently being processed",
    },
    []string{"method"},
)

LabelCacheHitsTotal counts label cache hits.

var LabelCacheHitsTotal = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_label_cache_hits_total",
        Help: "Total label cache hits",
    },
)

LabelCacheMissesTotal counts label cache misses.

var LabelCacheMissesTotal = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_label_cache_misses_total",
        Help: "Total label cache misses",
    },
)

MultipartUploadsAbortedTotal counts multipart uploads aborted.

var MultipartUploadsAbortedTotal = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_multipart_uploads_aborted_total",
        Help: "Total multipart uploads aborted",
    },
)

MultipartUploadsActive tracks the current number of in-progress uploads.

var MultipartUploadsActive = promauto.NewGauge(
    prometheus.GaugeOpts{
        Name: "g3_multipart_uploads_active",
        Help: "Number of in-progress multipart uploads",
    },
)

MultipartUploadsCompletedTotal counts multipart uploads completed.

var MultipartUploadsCompletedTotal = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_multipart_uploads_completed_total",
        Help: "Total multipart uploads completed",
    },
)

MultipartUploadsCreatedTotal counts multipart uploads initiated.

var MultipartUploadsCreatedTotal = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_multipart_uploads_created_total",
        Help: "Total multipart uploads created",
    },
)

MultipartUploadsExpiredTotal counts multipart uploads expired by cleanup.

var MultipartUploadsExpiredTotal = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_multipart_uploads_expired_total",
        Help: "Total multipart uploads expired by cleanup",
    },
)

ObjectBytesDownloaded tracks total bytes downloaded from storage.

var ObjectBytesDownloaded = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_object_bytes_downloaded_total",
        Help: "Total bytes downloaded from storage",
    },
)

ObjectBytesUploaded tracks total bytes uploaded to storage.

var ObjectBytesUploaded = promauto.NewCounter(
    prometheus.CounterOpts{
        Name: "g3_object_bytes_uploaded_total",
        Help: "Total bytes uploaded to storage",
    },
)

ObjectsTotal tracks the number of objects per bucket.

var ObjectsTotal = promauto.NewGaugeVec(
    prometheus.GaugeOpts{
        Name: "g3_objects_total",
        Help: "Number of objects per bucket",
    },
    []string{"bucket"},
)

RequestDuration observes HTTP request latency in seconds by method.

var RequestDuration = promauto.NewHistogramVec(
    prometheus.HistogramOpts{
        Name:    "g3_request_duration_seconds",
        Help:    "HTTP request latency in seconds",
        Buckets: []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10, 30, 60},
    },
    []string{"method"},
)

RequestSize observes HTTP request body sizes in bytes.

var RequestSize = promauto.NewHistogramVec(
    prometheus.HistogramOpts{
        Name:    "g3_request_size_bytes",
        Help:    "HTTP request body size in bytes",
        Buckets: prometheus.ExponentialBuckets(1024, 4, 10),
    },
    []string{"method"},
)

RequestsTotal counts total HTTP requests by method and status code.

var RequestsTotal = promauto.NewCounterVec(
    prometheus.CounterOpts{
        Name: "g3_requests_total",
        Help: "Total number of HTTP requests processed",
    },
    []string{"method", "status_code"},
)

ResponseSize observes HTTP response body sizes in bytes.

var ResponseSize = promauto.NewHistogramVec(
    prometheus.HistogramOpts{
        Name:    "g3_response_size_bytes",
        Help:    "HTTP response body size in bytes",
        Buckets: prometheus.ExponentialBuckets(1024, 4, 10),
    },
    []string{"method"},
)

SQLiteDuration observes SQLite query latency by operation.

var SQLiteDuration = promauto.NewHistogramVec(
    prometheus.HistogramOpts{
        Name:    "g3_sqlite_duration_seconds",
        Help:    "SQLite query latency in seconds",
        Buckets: []float64{.0001, .0005, .001, .005, .01, .05, .1},
    },
    []string{"operation"},
)

SQLiteQueriesTotal counts SQLite queries by operation.

var SQLiteQueriesTotal = promauto.NewCounterVec(
    prometheus.CounterOpts{
        Name: "g3_sqlite_queries_total",
        Help: "Total SQLite queries",
    },
    []string{"operation"},
)

Version is set at build time via ldflags.

var Version = "dev"

func GmailAttributes

func GmailAttributes(operation, bucket, key string) []attribute.KeyValue

GmailAttributes builds attributes for a Gmail API operation.

func InitTracer

func InitTracer(ctx context.Context, cfg TracingConfig) (func(context.Context) error, error)

InitTracer initializes the OpenTelemetry tracer provider and returns a shutdown function. If tracing is disabled, the shutdown function is a no-op.

func RequestAttributes

func RequestAttributes(method, path, bucket, key, clientIP string) []attribute.KeyValue

RequestAttributes builds common attributes for an incoming S3 request.

func StartClientSpan

func StartClientSpan(ctx context.Context, name string, attrs ...attribute.KeyValue) (context.Context, trace.Span)

StartClientSpan creates a new client-kind span for outgoing Gmail API calls.

func StartServerSpan

func StartServerSpan(ctx context.Context, name string, attrs ...attribute.KeyValue) (context.Context, trace.Span)

StartServerSpan creates a new server-kind span for incoming HTTP requests.

func StartSpan

func StartSpan(ctx context.Context, name string, attrs ...attribute.KeyValue) (context.Context, trace.Span)

StartSpan creates a new span with the given name and attributes.

func Tracer

func Tracer() trace.Tracer

Tracer returns the global tracer for g3.

type LogBuffer

LogBuffer is a thread-safe circular buffer of recent log entries.

type LogBuffer struct {
    // contains filtered or unexported fields
}

func NewLogBuffer

func NewLogBuffer() *LogBuffer

NewLogBuffer creates a LogBuffer with a fixed capacity of 5000 entries.

func (*LogBuffer) Add

func (b *LogBuffer) Add(entry LogEntry)

Add appends a log entry to the buffer, overwriting the oldest entry when the buffer is full.

func (*LogBuffer) Entries

func (b *LogBuffer) Entries(count int) []LogEntry

Entries returns buffered log entries in chronological order, limited to the most recent count entries. Pass 0 for all buffered entries.

type LogEntry

LogEntry represents a single buffered log record with extracted attributes.

type LogEntry struct {
    Time    time.Time      `json:"time"`
    Level   string         `json:"level"`
    Message string         `json:"message"`
    Attrs   map[string]any `json:"attrs,omitempty"`
}

type TeeHandler

TeeHandler fans slog output to both a primary handler and a LogBuffer.

type TeeHandler struct {
    // contains filtered or unexported fields
}

func NewTeeHandler

func NewTeeHandler(primary slog.Handler, buf *LogBuffer) *TeeHandler

NewTeeHandler creates a handler that writes to both the primary handler and the log buffer.

func (*TeeHandler) Enabled

func (h *TeeHandler) Enabled(ctx context.Context, level slog.Level) bool

Enabled delegates to the primary handler.

func (*TeeHandler) Handle

func (h *TeeHandler) Handle(ctx context.Context, r slog.Record) error

Handle writes to both the primary handler and the log buffer.

func (*TeeHandler) WithAttrs

func (h *TeeHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new TeeHandler with additional attributes.

func (*TeeHandler) WithGroup

func (h *TeeHandler) WithGroup(name string) slog.Handler

WithGroup returns a new TeeHandler with a group prefix.

type TraceHandler

TraceHandler wraps an inner slog.Handler to inject trace context fields.

type TraceHandler struct {
    // contains filtered or unexported fields
}

func NewTraceHandler

func NewTraceHandler(inner slog.Handler) *TraceHandler

NewTraceHandler creates a TraceHandler that decorates log records with trace_id and span_id when an active OpenTelemetry span exists in context.

func (*TraceHandler) Enabled

func (h *TraceHandler) Enabled(ctx context.Context, level slog.Level) bool

Enabled delegates to the inner handler.

func (*TraceHandler) Handle

func (h *TraceHandler) Handle(ctx context.Context, r slog.Record) error

Handle injects trace_id and span_id into the record if the context carries a valid span, then delegates to the inner handler.

func (*TraceHandler) WithAttrs

func (h *TraceHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new TraceHandler wrapping the inner handler with additional attributes.

func (*TraceHandler) WithGroup

func (h *TraceHandler) WithGroup(name string) slog.Handler

WithGroup returns a new TraceHandler wrapping the inner handler with a group prefix.

type TracingConfig

TracingConfig holds configuration for OpenTelemetry tracing.

type TracingConfig struct {
    Enabled    bool    `yaml:"enabled"`
    Endpoint   string  `yaml:"endpoint"`
    Insecure   bool    `yaml:"insecure"`
    SampleRate float64 `yaml:"sample_rate"`
}

Generated by gomarkdoc