Documentation
¶
Overview ¶
Package otel provides OpenTelemetry instrumentation for Deputy. It handles SDK initialization, shutdown, and provides helpers for traces, metrics, and log correlation.
Package otel provides OpenTelemetry instrumentation for Deputy.
This package handles initialization and configuration of OpenTelemetry tracing and metrics. When enabled, it exports telemetry data to an OTLP-compatible collector.
Configuration ¶
Enable OpenTelemetry via environment variables:
export DEPUTY_OTEL_ENABLED=true export OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317
Or via configuration file (.deputy.yaml):
otel: enabled: true endpoint: localhost:4317 insecure: true
Initialization ¶
Initialize OpenTelemetry early in program startup:
provider, err := otel.Init(ctx, cfg)
if err != nil {
log.Warn("failed to initialize OpenTelemetry", "error", err)
}
defer provider.Shutdown(context.Background())
Creating Spans ¶
Use StartSpan to create traced operations:
ctx, span := otel.StartSpan(ctx, "deputy.scan",
trace.WithAttributes(
attribute.String("target", target),
))
defer span.End()
// ... do work ...
otel.SetSpanOK(span) // or otel.SetSpanError(span, err)
HTTP Instrumentation ¶
Wrap HTTP handlers for automatic tracing:
handler := otel.WrapHandler(myHandler, "my-handler")
Checking Status ¶
Check if OpenTelemetry is enabled:
if otel.IsEnabled() {
// Include trace context in logs
}
Index ¶
- Constants
- Variables
- func AddSpanEvent(span trace.Span, name string, attrs ...attribute.KeyValue)
- func CacheTypeAttr(cacheType string) attribute.KeyValue
- func ClientSpanNameFormatter(service string) func(string, *http.Request) string
- func EcosystemAttr(ecosystem string) attribute.KeyValue
- func ImageTransportAttr(transport string) attribute.KeyValue
- func InstrumentedHandler(handler http.Handler, operation string, opts ...otelhttp.Option) http.Handler
- func InstrumentedMiddleware(operation string, opts ...otelhttp.Option) func(http.Handler) http.Handler
- func InstrumentedTransport(base http.RoundTripper, opts ...otelhttp.Option) http.RoundTripper
- func IsEnabled() bool
- func LogWithTrace(ctx context.Context) []any
- func Meter(name string) metric.Meter
- func NewOTelHandler(name string) slog.Handler
- func ProxySpanNameFormatter(ecosystem string) func(string, *http.Request) string
- func RecordCacheAccess(span trace.Span, cacheType string, hit bool, key string)
- func RecordCacheEviction(ctx context.Context, cacheType string)
- func RecordCacheExpiration(ctx context.Context, cacheType string)
- func RecordCacheHit(ctx context.Context, cacheType string)
- func RecordCacheMiss(ctx context.Context, cacheType string)
- func RecordCacheStats(ctx context.Context, cacheType string, stats CacheStats)
- func RecordImageScanMetrics(ctx context.Context, duration float64, transport string, registry string, ...)
- func RecordMCPToolCall(ctx context.Context, toolName string, duration float64, success bool)
- func RecordOSVCacheAccess(ctx context.Context, hit bool)
- func RecordOSVQuery(ctx context.Context, duration float64, queryType string, success bool)
- func RecordPolicyEvaluation(ctx context.Context, duration float64, result string)
- func RecordPolicyResult(span trace.Span, policyName, action string)
- func RecordProxyAuth(ctx context.Context, result string, errorCode string)
- func RecordProxyPolicyDenial(ctx context.Context, ecosystem, policyName string)
- func RecordProxyRequest(ctx context.Context, duration float64, ecosystem string, statusCode int)
- func RecordSandboxExecution(ctx context.Context, info SandboxExecutionInfo)
- func RecordSandboxPolicyDenial(ctx context.Context, runtime, policyName string)
- func RecordScanCompletion(ctx context.Context, c ScanCompletion)
- func RecordScanMetrics(ctx context.Context, duration float64, ecosystem string, ...)
- func RecordScanResults(span trace.Span, pkgCount, vulnCount, critical, high, medium, low int)
- func RequestAttributes(r *http.Request) []attribute.KeyValue
- func ResponseAttributes(statusCode int, contentLength int64) []attribute.KeyValue
- func SandboxNetworkModeAttr(mode string) attribute.KeyValue
- func SandboxPluginAttr(pluginName string) attribute.KeyValue
- func SandboxRuntimeAttr(runtime string) attribute.KeyValue
- func SandboxWorkspaceIsolationAttr(isolation string) attribute.KeyValue
- func SetSpanError(span trace.Span, err error)
- func SetSpanOK(span trace.Span)
- func SeverityAttr(severity string) attribute.KeyValue
- func SpanFromContext(ctx context.Context) trace.Span
- func SpanIDFromContext(ctx context.Context) string
- func StartSpan(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span)
- func TraceIDFromContext(ctx context.Context) string
- func Tracer(name string) trace.Tracer
- func WithCommandAttrs(command string) trace.SpanStartOption
- func WithEcosystemAttr(ecosystem string) trace.SpanStartOption
- func WithOSVAttrs(batchSize int, queryType string) trace.SpanStartOption
- func WithPolicyAttrs(name, entrypoint string) trace.SpanStartOption
- func WithPropagators(p propagation.TextMapPropagator) otelhttp.Option
- func WithProxyAttrs(listener, ecosystem, pkg, version string) trace.SpanStartOption
- func WithPublicEndpoint() otelhttp.Option
- func WithPublicEndpointFn(fn func(r *http.Request) bool) otelhttp.Option
- func WithServiceName(name string) otelhttp.Option
- func WithSpanNameFormatter(fn func(operation string, r *http.Request) string) otelhttp.Option
- func WithTargetAttrs(path, ref string, isRemote bool) trace.SpanStartOption
- func WrapHandler(h slog.Handler) slog.Handler
- type AuditHandler
- type CacheStats
- type Config
- type ExporterConfig
- type LogsConfig
- type Metrics
- type MetricsConfig
- type MultiHandler
- type Provider
- type SandboxExecutionInfo
- type ScanCompletion
- type SeverityCounts
- type TraceContextHandler
- type TracesConfig
Constants ¶
const (
// MeterName is the default meter name for Deputy metrics.
MeterName = "github.com/temporalio/deputy"
)
const (
// TracerName is the default tracer name for Deputy spans.
TracerName = "github.com/temporalio/deputy"
)
Variables ¶
var ( // Ecosystem attributes - using deputy.ecosystem for consistency with traces AttrEcosystemGo = attribute.String("deputy.ecosystem", "go") AttrEcosystemNpm = attribute.String("deputy.ecosystem", "npm") AttrEcosystemPyPI = attribute.String("deputy.ecosystem", "pypi") AttrEcosystemRuby = attribute.String("deputy.ecosystem", "ruby") AttrEcosystemCargo = attribute.String("deputy.ecosystem", "cargo") AttrEcosystemMaven = attribute.String("deputy.ecosystem", "maven") AttrEcosystemNuget = attribute.String("deputy.ecosystem", "nuget") // Severity attributes AttrSeverityCritical = attribute.String("severity", "CRITICAL") AttrSeverityHigh = attribute.String("severity", "HIGH") AttrSeverityMedium = attribute.String("severity", "MEDIUM") AttrSeverityLow = attribute.String("severity", "LOW") AttrSeverityUnknown = attribute.String("severity", "UNKNOWN") // Status attributes AttrStatusSuccess = attribute.String("status", "success") AttrStatusError = attribute.String("status", "error") // Policy result attributes AttrPolicyResultAllow = attribute.String("result", "allow") AttrPolicyResultDeny = attribute.String("result", "deny") AttrPolicyResultWarn = attribute.String("result", "warn") // Auth result attributes AttrAuthResultSuccess = attribute.String("result", "success") AttrAuthResultAnonymous = attribute.String("result", "anonymous") AttrAuthResultRejected = attribute.String("result", "rejected") // Cache type attributes - using deputy.cache.type for consistency with trace attributes AttrCacheTypeOSV = attribute.String("deputy.cache.type", "osv") AttrCacheTypeKEV = attribute.String("deputy.cache.type", "kev") AttrCacheTypeEPSS = attribute.String("deputy.cache.type", "epss") AttrCacheTypeLicense = attribute.String("deputy.cache.type", "license") AttrCacheTypeDisk = attribute.String("deputy.cache.type", "disk") AttrCacheTypeImage = attribute.String("deputy.cache.type", "image_scan") AttrCacheTypeDepsDev = attribute.String("deputy.cache.type", "depsdev") AttrCacheTypeGoProxy = attribute.String("deputy.cache.type", "goproxy") AttrCacheTypeGraph = attribute.String("deputy.cache.type", "graph") AttrCacheTypeGit = attribute.String("deputy.cache.type", "git") // Image transport attributes for container image scans AttrImageTransportRemote = attribute.String("deputy.image.transport", "remote") AttrImageTransportDaemon = attribute.String("deputy.image.transport", "docker-daemon") AttrImageTransportTarball = attribute.String("deputy.image.transport", "tarball") AttrImageTransportOCILayout = attribute.String("deputy.image.transport", "oci-layout") // Sandbox runtime attributes AttrSandboxRuntimeNone = attribute.String("deputy.sandbox.runtime", "none") AttrSandboxRuntimeDocker = attribute.String("deputy.sandbox.runtime", "docker") AttrSandboxRuntimeGVisor = attribute.String("deputy.sandbox.runtime", "gvisor") AttrSandboxRuntimeSandboxExec = attribute.String("deputy.sandbox.runtime", "sandbox-exec") AttrSandboxRuntimePlugin = attribute.String("deputy.sandbox.runtime", "plugin") // Sandbox network mode attributes AttrSandboxNetworkNone = attribute.String("deputy.sandbox.network_mode", "none") AttrSandboxNetworkHost = attribute.String("deputy.sandbox.network_mode", "host") AttrSandboxNetworkBridge = attribute.String("deputy.sandbox.network_mode", "bridge") AttrSandboxNetworkAllowlist = attribute.String("deputy.sandbox.network_mode", "allowlist") // Sandbox workspace isolation attributes AttrSandboxIsolationDirect = attribute.String("deputy.sandbox.workspace_isolation", "direct") AttrSandboxIsolationOverlay = attribute.String("deputy.sandbox.workspace_isolation", "overlay") AttrSandboxIsolationSnapshot = attribute.String("deputy.sandbox.workspace_isolation", "snapshot") AttrSandboxIsolationTmpfs = attribute.String("deputy.sandbox.workspace_isolation", "tmpfs") )
Common attribute values for metrics. Note: Attribute keys use the "deputy." namespace to match trace attributes for cross-signal correlation. The OTel SDK automatically converts dots to underscores for Prometheus export (e.g., "deputy.ecosystem" -> "deputy_ecosystem").
var ( // Command attributes AttrCommand = attribute.Key("deputy.command") AttrSubcommand = attribute.Key("deputy.subcommand") AttrTargetPath = attribute.Key("deputy.target.path") AttrTargetRef = attribute.Key("deputy.target.ref") AttrTargetRemote = attribute.Key("deputy.target.remote") // Scan attributes AttrEcosystem = attribute.Key("deputy.ecosystem") AttrPackageCount = attribute.Key("deputy.package.count") AttrVulnerabilityCount = attribute.Key("deputy.vulnerability.count") AttrVulnerabilityCritical = attribute.Key("deputy.vulnerability.critical") AttrVulnerabilityHigh = attribute.Key("deputy.vulnerability.high") AttrVulnerabilityMedium = attribute.Key("deputy.vulnerability.medium") AttrVulnerabilityLow = attribute.Key("deputy.vulnerability.low") AttrDirectDepsOnly = attribute.Key("deputy.direct_deps_only") AttrPolicyEvaluated = attribute.Key("deputy.policy.evaluated") AttrPolicyPassed = attribute.Key("deputy.policy.passed") // OSV attributes AttrOSVBatchSize = attribute.Key("deputy.osv.batch_size") AttrOSVCacheHit = attribute.Key("deputy.osv.cache_hit") AttrOSVVulnerabilityID = attribute.Key("deputy.osv.vulnerability_id") AttrOSVQueryType = attribute.Key("deputy.osv.query_type") AttrOSVResponseLen = attribute.Key("deputy.osv.response_len") AttrOSVDroppedNoVersion = attribute.Key("deputy.osv.dropped_no_version") AttrOSVDroppedNoIdentifier = attribute.Key("deputy.osv.dropped_no_identifier") // Policy attributes AttrPolicyName = attribute.Key("deputy.policy.name") AttrPolicyAction = attribute.Key("deputy.policy.action") AttrPolicyEntrypoint = attribute.Key("deputy.policy.entrypoint") // Proxy attributes AttrProxyListener = attribute.Key("deputy.proxy.listener") AttrProxyUpstream = attribute.Key("deputy.proxy.upstream") AttrProxyPackage = attribute.Key("deputy.proxy.package") AttrProxyVersion = attribute.Key("deputy.proxy.version") AttrProxyOperation = attribute.Key("deputy.proxy.operation") AttrProxyBlocked = attribute.Key("deputy.proxy.blocked") // Auth attributes AttrAuthMode = attribute.Key("deputy.auth.mode") AttrAuthResult = attribute.Key("deputy.auth.result") AttrAuthSubject = attribute.Key("deputy.auth.subject") AttrAuthErrorCode = attribute.Key("deputy.auth.error_code") // Cache attributes AttrCacheType = attribute.Key("deputy.cache.type") AttrCacheHit = attribute.Key("deputy.cache.hit") AttrCacheKey = attribute.Key("deputy.cache.key") // MCP attributes AttrMCPTool = attribute.Key("deputy.mcp.tool") AttrMCPVulnerabilityID = attribute.Key("deputy.mcp.vulnerability_id") AttrMCPVulnerabilityCount = attribute.Key("deputy.mcp.vulnerability_count") AttrMCPPackageCount = attribute.Key("deputy.mcp.package_count") AttrMCPImage = attribute.Key("deputy.mcp.image") AttrMCPBaseRef = attribute.Key("deputy.mcp.base_ref") AttrMCPTargetRef = attribute.Key("deputy.mcp.target_ref") AttrMCPChangeCount = attribute.Key("deputy.mcp.change_count") AttrMCPTriageCount = attribute.Key("deputy.mcp.triage_count") AttrMCPGraphPackage = attribute.Key("deputy.mcp.graph_package") AttrMCPGraphFound = attribute.Key("deputy.mcp.graph_found") AttrMCPGraphDirect = attribute.Key("deputy.mcp.graph_direct") AttrMCPGraphPathCount = attribute.Key("deputy.mcp.graph_path_count") )
Common attribute keys for Deputy spans.
Functions ¶
func AddSpanEvent ¶
AddSpanEvent adds an event to the span with optional attributes. Use events for discrete occurrences within a span (e.g., cache hits, policy evaluations). For continuous data, use span attributes instead.
func CacheTypeAttr ¶
CacheTypeAttr returns a cache type attribute for the given cache name.
func ClientSpanNameFormatter ¶
ClientSpanNameFormatter returns a span name formatter for outgoing HTTP client requests.
func EcosystemAttr ¶
EcosystemAttr returns an ecosystem attribute for the given ecosystem string. Uses "deputy.ecosystem" key for consistency with trace attributes.
func ImageTransportAttr ¶
ImageTransportAttr returns an image transport attribute for the given transport string.
func InstrumentedHandler ¶
func InstrumentedHandler(handler http.Handler, operation string, opts ...otelhttp.Option) http.Handler
InstrumentedHandler wraps an http.Handler with OpenTelemetry tracing. Creates server spans for incoming HTTP requests.
func InstrumentedMiddleware ¶
func InstrumentedMiddleware(operation string, opts ...otelhttp.Option) func(http.Handler) http.Handler
InstrumentedMiddleware returns middleware that wraps handlers with OTel tracing.
func InstrumentedTransport ¶
func InstrumentedTransport(base http.RoundTripper, opts ...otelhttp.Option) http.RoundTripper
InstrumentedTransport wraps an http.RoundTripper with OpenTelemetry tracing. Creates client spans for outgoing HTTP requests with proper context propagation.
func LogWithTrace ¶
LogWithTrace creates log attributes for trace context. Useful for manually adding trace context to log calls.
func Meter ¶
Meter returns a named meter for recording metrics. Returns a no-op meter if OTel is disabled.
func NewOTelHandler ¶
NewOTelHandler creates an slog handler that exports logs via OpenTelemetry. The handler sends logs to the configured OTel collector endpoint. Use this as a base handler wrapped with TraceContextHandler for full correlation.
func ProxySpanNameFormatter ¶
ProxySpanNameFormatter returns a span name formatter suitable for proxy requests.
func RecordCacheAccess ¶
RecordCacheAccess adds a cache access event to a span.
func RecordCacheEviction ¶
RecordCacheEviction records a single cache eviction event.
func RecordCacheExpiration ¶
RecordCacheExpiration records a single cache expiration event.
func RecordCacheHit ¶
RecordCacheHit records a single cache hit event.
func RecordCacheMiss ¶
RecordCacheMiss records a single cache miss event.
func RecordCacheStats ¶
func RecordCacheStats(ctx context.Context, cacheType string, stats CacheStats)
RecordCacheStats records cache statistics for a named cache. The cacheType parameter should identify the cache (e.g., "depsdev", "goproxy", "osv"). Use this function with stats from memory.TTLCache.Stats().
func RecordImageScanMetrics ¶
func RecordImageScanMetrics(ctx context.Context, duration float64, transport string, registry string, pkgCount, layerCount int)
RecordImageScanMetrics records metrics for a completed container image scan.
func RecordMCPToolCall ¶
RecordMCPToolCall records an MCP tool invocation.
func RecordOSVCacheAccess ¶
RecordOSVCacheAccess records an OSV cache access.
func RecordOSVQuery ¶
RecordOSVQuery records an OSV query.
func RecordPolicyEvaluation ¶
RecordPolicyEvaluation records a policy evaluation.
func RecordPolicyResult ¶
RecordPolicyResult adds a policy evaluation result event to a span. Called by the policy engine after each policy is evaluated to provide per-policy trace visibility. The action should be "allow", "deny", or "warn".
func RecordProxyAuth ¶
RecordProxyAuth records a proxy authentication attempt.
func RecordProxyPolicyDenial ¶
RecordProxyPolicyDenial records a policy denial in the proxy.
func RecordProxyRequest ¶
RecordProxyRequest records a proxy request.
func RecordSandboxExecution ¶
func RecordSandboxExecution(ctx context.Context, info SandboxExecutionInfo)
RecordSandboxExecution records metrics for a completed sandbox execution.
func RecordSandboxPolicyDenial ¶
RecordSandboxPolicyDenial records a sandbox execution denied by policy.
func RecordScanCompletion ¶
func RecordScanCompletion(ctx context.Context, c ScanCompletion)
RecordScanCompletion records scan results on both the span (trace) and metrics. This provides a single call to update both observability signals consistently, avoiding duplication and ensuring trace attributes and metrics stay in sync.
Note: This does NOT call SetSpanOK - the caller should still explicitly mark the span status after this call.
func RecordScanMetrics ¶
func RecordScanMetrics(ctx context.Context, duration float64, ecosystem string, pkgCount, vulnCount int, severity map[string]int)
RecordScanMetrics records metrics for a completed scan.
func RecordScanResults ¶
RecordScanResults adds scan result attributes to a span.
func RequestAttributes ¶
RequestAttributes returns common attributes for HTTP request spans.
func ResponseAttributes ¶
ResponseAttributes returns common attributes for HTTP response spans.
func SandboxNetworkModeAttr ¶
SandboxNetworkModeAttr returns a sandbox network mode attribute.
func SandboxPluginAttr ¶
SandboxPluginAttr returns a sandbox plugin name attribute.
func SandboxRuntimeAttr ¶
SandboxRuntimeAttr returns a sandbox runtime attribute.
func SandboxWorkspaceIsolationAttr ¶
SandboxWorkspaceIsolationAttr returns a sandbox workspace isolation attribute.
func SetSpanError ¶
SetSpanError records an error on the span and sets its status to Error. Safe to call with nil error (no-op). Call this on error paths before returning an error from a function that started a span.
func SetSpanOK ¶
SetSpanOK sets the span status to OK. Call this on success paths before returning nil from a function that started a span. This explicitly marks the span as successful.
func SeverityAttr ¶
SeverityAttr returns a severity attribute for the given severity string.
func SpanFromContext ¶
SpanFromContext returns the current span from the context. Returns a no-op span if none is present, which is safe to use (all operations become no-ops).
func SpanIDFromContext ¶
SpanIDFromContext extracts the span ID from the context, if present. Returns an empty string if no valid trace context exists.
func StartSpan ¶
func StartSpan(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span)
StartSpan starts a new span with the given name and options. Returns the updated context and the span.
Span lifecycle management:
- The caller MUST call span.End() when the operation completes (typically via defer)
- On success, call SetSpanOK(span) before returning nil
- On error, call SetSpanError(span, err) before returning the error
Example:
ctx, span := otel.StartSpan(ctx, "deputy.myop")
defer span.End()
result, err := doWork(ctx)
if err != nil {
otel.SetSpanError(span, err)
return err
}
otel.SetSpanOK(span)
return nil
func TraceIDFromContext ¶
TraceIDFromContext extracts the trace ID from the context, if present. Returns an empty string if no valid trace context exists.
func Tracer ¶
Tracer returns a named tracer for creating spans. Returns a no-op tracer if OTel is disabled.
func WithCommandAttrs ¶
func WithCommandAttrs(command string) trace.SpanStartOption
WithCommandAttrs returns span start options for command spans.
func WithEcosystemAttr ¶
func WithEcosystemAttr(ecosystem string) trace.SpanStartOption
WithEcosystemAttr returns a span start option for ecosystem.
func WithOSVAttrs ¶
func WithOSVAttrs(batchSize int, queryType string) trace.SpanStartOption
WithOSVAttrs returns span start options for OSV query spans.
func WithPolicyAttrs ¶
func WithPolicyAttrs(name, entrypoint string) trace.SpanStartOption
WithPolicyAttrs returns span start options for policy evaluation spans.
func WithPropagators ¶
func WithPropagators(p propagation.TextMapPropagator) otelhttp.Option
WithPropagators returns an option that sets custom propagators.
func WithProxyAttrs ¶
func WithProxyAttrs(listener, ecosystem, pkg, version string) trace.SpanStartOption
WithProxyAttrs returns span start options for proxy request spans.
func WithPublicEndpoint ¶
WithPublicEndpoint returns an option that marks the endpoint as public. Public endpoints always start a new trace rather than continuing an existing one.
func WithPublicEndpointFn ¶
WithPublicEndpointFn returns an option with a function to determine if an endpoint is public.
func WithServiceName ¶
WithServiceName returns an option that sets the service name for spans.
func WithSpanNameFormatter ¶
WithSpanNameFormatter returns an option that customizes span names.
func WithTargetAttrs ¶
func WithTargetAttrs(path, ref string, isRemote bool) trace.SpanStartOption
WithTargetAttrs returns span start options for target resolution spans.
Types ¶
type AuditHandler ¶
type AuditHandler struct {
// contains filtered or unexported fields
}
AuditHandler filters log records to only those matching audit event patterns and writes them as JSON to a dedicated audit log destination.
Audit events are identified by message prefixes (e.g., "deputy.scan.", "deputy.policy.", "deputy.proxy."). This allows using standard slog calls for audit logging without a separate API.
Usage:
auditFile, _ := os.OpenFile("audit.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
auditHandler := otel.NewAuditHandler(auditFile, "deputy.")
logger := slog.New(otel.NewMultiHandler(mainHandler, auditHandler))
// This goes to both main log and audit log:
logger.Info("deputy.scan.completed", "target", "github.com/example/repo", "vulns", 5)
// This only goes to main log (no "deputy." prefix):
logger.Debug("processing file", "path", "/tmp/foo")
func NewAuditHandler ¶
func NewAuditHandler(w io.Writer, prefix string) *AuditHandler
NewAuditHandler creates a handler that filters for audit events and writes JSON. Only log records whose message starts with the given prefix are written. Common prefix values: "deputy." for all Deputy events.
func (*AuditHandler) Enabled ¶
Enabled reports whether the handler handles records at the given level. The handler is always enabled; filtering happens in Handle based on message prefix.
type CacheStats ¶
type CacheStats struct {
Hits uint64 // Total cache hits
Misses uint64 // Total cache misses
Evicted uint64 // Total evictions due to capacity
Expired uint64 // Total expirations due to TTL
Size int // Current number of entries
MaxSize int // Maximum capacity
HitRate float64 // Hit rate (0.0-1.0)
}
CacheStats represents a snapshot of cache statistics compatible with memory.Stats from the cache/memory package.
type Config ¶
type Config struct {
// Enabled controls whether OTel instrumentation is active.
// Default: false (zero overhead when disabled).
Enabled bool `yaml:"enabled"`
// ServiceName identifies the service in traces/metrics.
// Default: "deputy"
ServiceName string `yaml:"service_name"`
// ServiceVersion is the service version for resource attributes.
// If empty, uses the build version.
ServiceVersion string `yaml:"service_version"`
// Exporter configures the OTLP exporter.
Exporter ExporterConfig `yaml:"exporter"`
// Traces configures tracing behavior.
Traces TracesConfig `yaml:"traces"`
// Metrics configures metrics collection.
Metrics MetricsConfig `yaml:"metrics"`
// Logs configures log correlation.
Logs LogsConfig `yaml:"logs"`
}
Config configures OpenTelemetry instrumentation.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a configuration with sensible defaults. Note: Enabled defaults to false for zero overhead.
type ExporterConfig ¶
type ExporterConfig struct {
// Protocol selects OTLP transport: "grpc" (default) or "http".
Protocol string `yaml:"protocol"`
// Endpoint is the collector address.
// For gRPC: "localhost:4317" (default)
// For HTTP: "localhost:4318"
Endpoint string `yaml:"endpoint"`
// Insecure disables TLS. Use for local development only.
Insecure bool `yaml:"insecure"`
// Headers for authentication (e.g., {"Authorization": "Bearer token"}).
Headers map[string]string `yaml:"headers"`
// Timeout for export operations. Default: 10s.
Timeout time.Duration `yaml:"timeout"`
}
ExporterConfig configures the OTLP exporter.
type LogsConfig ¶
type LogsConfig struct {
// Enabled controls log export to OTel. Default: true when OTel enabled.
Enabled bool `yaml:"enabled"`
// IncludeTraceContext adds trace_id/span_id to log records.
// Default: true.
IncludeTraceContext bool `yaml:"include_trace_context"`
}
LogsConfig configures log correlation.
type Metrics ¶
type Metrics struct {
// Scan metrics
ScanDuration metric.Float64Histogram
ScanPackages metric.Int64Counter
ScanVulns metric.Int64Counter
ScanPolicyResults metric.Int64Counter
// Container image scan metrics
ImageScanDuration metric.Float64Histogram
ImageScanPackages metric.Int64Counter
ImageScanLayers metric.Int64Counter
// OSV metrics
OSVQueries metric.Int64Counter
OSVQueryDuration metric.Float64Histogram
OSVCacheHits metric.Int64Counter
OSVCacheMisses metric.Int64Counter
// Policy metrics
PolicyEvaluations metric.Int64Counter
PolicyDuration metric.Float64Histogram
// Proxy metrics
ProxyRequests metric.Int64Counter
ProxyRequestDuration metric.Float64Histogram
ProxyAuth metric.Int64Counter
ProxyPolicyDenials metric.Int64Counter
// Cache metrics
CacheHits metric.Int64Counter
CacheMisses metric.Int64Counter
CacheEvictions metric.Int64Counter
CacheExpired metric.Int64Counter
CacheSize metric.Int64Gauge
CacheMaxSize metric.Int64Gauge
CacheHitRate metric.Float64Gauge
// MCP metrics
MCPToolCalls metric.Int64Counter
MCPToolDuration metric.Float64Histogram
MCPToolErrors metric.Int64Counter
// Sandbox metrics
SandboxExecutions metric.Int64Counter
SandboxExecutionDuration metric.Float64Histogram
SandboxFilesChanged metric.Int64Counter
SandboxPolicyDenials metric.Int64Counter
}
Metrics holds all Deputy metric instruments. Use GetMetrics() to access the singleton instance.
func GetMetrics ¶
GetMetrics returns the singleton Metrics instance. Creates the instruments on first call. Safe for concurrent use.
type MetricsConfig ¶
type MetricsConfig struct {
// Enabled controls metrics collection. Default: true when OTel enabled.
Enabled bool `yaml:"enabled"`
// Interval is the metrics export interval.
// Default: 5s (optimized for interactive demos).
// For production, consider 60s to reduce overhead.
// Can be overridden with OTEL_METRIC_EXPORT_INTERVAL env var.
Interval time.Duration `yaml:"interval"`
}
MetricsConfig configures metrics collection.
type MultiHandler ¶
type MultiHandler struct {
// contains filtered or unexported fields
}
NewMultiHandler creates a handler that writes to multiple handlers. Useful for sending logs to both stdout and OTel collector.
func NewMultiHandler ¶
func NewMultiHandler(handlers ...slog.Handler) *MultiHandler
NewMultiHandler creates a handler that fans out to multiple handlers.
func (*MultiHandler) Enabled ¶
Enabled reports whether the handler handles records at the given level.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider manages the OpenTelemetry SDK lifecycle. Call Shutdown when done to flush pending telemetry data.
func Init ¶
Init initializes the OpenTelemetry SDK based on configuration. Returns a Provider that must be shut down via Shutdown(). If OTel is disabled or not configured, returns a no-op provider.
This function is safe to call multiple times; subsequent calls after the first return the existing provider.
func (*Provider) LoggerProvider ¶
func (p *Provider) LoggerProvider() *sdklog.LoggerProvider
LoggerProvider returns the logger provider, or nil if not initialized.
type SandboxExecutionInfo ¶
type SandboxExecutionInfo struct {
Runtime string // Runtime name (e.g., "plugin", "docker", "gvisor")
PluginName string // Plugin name if runtime is "plugin"
NetworkMode string // Network mode (e.g., "none", "host", "allowlist")
WorkspaceIsolation string // Workspace isolation mode (e.g., "direct", "overlay")
Duration float64 // Execution duration in seconds
ExitCode int32 // Exit code from the execution
FilesAdded int // Number of files added
FilesModified int // Number of files modified
FilesDeleted int // Number of files deleted
Success bool // Whether execution succeeded
}
SandboxExecutionInfo holds information about a sandbox execution for metrics recording.
type ScanCompletion ¶
type ScanCompletion struct {
Span trace.Span // The span to record attributes on
Duration float64 // Scan duration in seconds
Ecosystem string // Package ecosystem (e.g., "go", "npm", "sbom")
PackageCount int // Number of packages scanned
Severity SeverityCounts // Vulnerability counts by severity
}
ScanCompletion holds data for recording scan completion on both traces and metrics. Use with RecordScanCompletion for consistent observability across both signals.
type SeverityCounts ¶
SeverityCounts holds vulnerability counts by severity level. This provides a standard way to pass severity data to recording functions.
func (SeverityCounts) ToMap ¶
func (s SeverityCounts) ToMap() map[string]int
ToMap converts SeverityCounts to a map for metric recording.
func (SeverityCounts) Total ¶
func (s SeverityCounts) Total() int
Total returns the sum of all severity counts.
type TraceContextHandler ¶
type TraceContextHandler struct {
// contains filtered or unexported fields
}
TraceContextHandler wraps an slog.Handler to add trace context attributes (trace_id, span_id) to log records when available.
func NewTraceContextHandler ¶
func NewTraceContextHandler(base slog.Handler) *TraceContextHandler
NewTraceContextHandler creates a new handler that adds trace context to logs.
func (*TraceContextHandler) Enabled ¶
Enabled reports whether the handler handles records at the given level.
func (*TraceContextHandler) Handle ¶
Handle adds trace context attributes and delegates to the base handler.
type TracesConfig ¶
type TracesConfig struct {
// Enabled controls trace collection. Default: true when OTel enabled.
Enabled bool `yaml:"enabled"`
// SampleRate is the probability of sampling (0.0-1.0).
// Default: 1.0 (sample everything).
SampleRate float64 `yaml:"sample_rate"`
// Propagators selects context propagation formats.
// Default: ["tracecontext", "baggage"]
Propagators []string `yaml:"propagators"`
}
TracesConfig configures tracing behavior.