Documentation
¶
Overview ¶
Package ion context helpers provide functions for propagating trace, request, and user IDs through context.Context. These values are automatically extracted and included in log entries.
For OTEL tracing, trace_id and span_id are automatically extracted from the span context. For non-OTEL scenarios, use WithTraceID to set manually.
Package ion provides production-grade logging and tracing for Go services.
Ion unifies structured logging (Zap) and distributed tracing (OpenTelemetry) behind a minimal, context-first API.
Guarantees ¶
- Process Safety: Ion never terminates the process (no os.Exit, no panic).
- Concurrency: All Logger and Tracer APIs are safe for concurrent use.
- Failure Isolation: Telemetry backend failures never crash application logic.
- Lifecycle: Shutdown(ctx) flushes all buffers on a best-effort basis.
Architecture ¶
- Logs: Synchronous, structured, strongly typed.
- Traces: Asynchronous, sampled, batched.
- Correlation: Automatic injection of trace_id/span_id from context.Context.
Ion is designed for long-running services and distributed systems. It is not a metrics SDK or a web framework.
Package ion provides enterprise-grade structured logging for JupiterMeta blockchain applications.
Ion is designed for distributed systems where trace correlation is critical. All log methods require a context.Context as the first parameter to ensure trace information is never forgotten.
Features:
- High-performance Zap core
- Multi-destination output (Console, File, OTEL)
- Blockchain-specific field helpers (TxHash, ShardID, Slot, etc.)
- Automatic trace context propagation from context.Context
- Pretty console output for development
- File rotation via lumberjack
- OpenTelemetry integration for observability
Basic usage:
ctx := context.Background()
logger, warnings, _ := ion.New(ion.Default())
defer logger.Sync()
logger.Info(ctx, "server started", ion.Int("port", 8080))
With blockchain fields:
import "github.com/JupiterMetaLabs/ion/fields"
logger.Info(ctx, "transaction routed",
fields.TxHash("abc123"),
fields.ShardID(5),
fields.LatencyMs(12.5),
)
Context-first design ensures trace_id and span_id are automatically extracted:
func HandleRequest(ctx context.Context) {
// trace_id and span_id from ctx are added to logs automatically
logger.Info(ctx, "processing request")
}
Index ¶
- func Critical(ctx context.Context, msg string, err error, fields ...Field)
- func Debug(ctx context.Context, msg string, fields ...Field)
- func Error(ctx context.Context, msg string, err error, fields ...Field)
- func Info(ctx context.Context, msg string, fields ...Field)
- func New(cfg Config) (*Ion, []Warning, error)
- func RequestIDFromContext(ctx context.Context) string
- func SetGlobal(logger Logger)deprecated
- func Sync() error
- func UserIDFromContext(ctx context.Context) string
- func Warn(ctx context.Context, msg string, fields ...Field)
- func WithRequestID(ctx context.Context, requestID string) context.Context
- func WithTraceID(ctx context.Context, traceID string) context.Context
- func WithUserID(ctx context.Context, userID string) context.Context
- type Config
- type ConsoleConfig
- type Field
- func Bool(key string, value bool) Field
- func Err(err error) Field
- func F(key string, value any) Field
- func Float64(key string, value float64) Field
- func Int(key string, value int) Field
- func Int64(key string, value int64) Field
- func String(key, value string) Field
- func Uint64(key string, value uint64) Field
- type FieldType
- type FileConfig
- type Ion
- func (i *Ion) Critical(ctx context.Context, msg string, err error, fields ...Field)
- func (i *Ion) Debug(ctx context.Context, msg string, fields ...Field)
- func (i *Ion) Error(ctx context.Context, msg string, err error, fields ...Field)
- func (i *Ion) GetLevel() string
- func (i *Ion) Info(ctx context.Context, msg string, fields ...Field)
- func (i *Ion) Named(name string) Logger
- func (i *Ion) SetLevel(level string)
- func (i *Ion) Shutdown(ctx context.Context) error
- func (i *Ion) Sync() error
- func (i *Ion) Tracer(name string) Tracer
- func (i *Ion) Warn(ctx context.Context, msg string, fields ...Field)
- func (i *Ion) With(fields ...Field) Logger
- type Logger
- type OTELConfig
- type Span
- type SpanOption
- type Tracer
- type TracingConfig
- type Warning
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Critical ¶ added in v0.2.0
Critical logs at critical level using global logger. Does NOT exit the process - caller decides what to do.
func New ¶
New creates a new Ion instance with the given configuration. This is the single entry point for creating ion observability.
Returns:
- *Ion: Always returns a working Ion instance (may use fallbacks)
- []Warning: Non-fatal issues (e.g., OTEL connection failed, tracing disabled)
- error: Fatal configuration errors
func RequestIDFromContext ¶
RequestIDFromContext extracts the request ID from context.
func UserIDFromContext ¶
UserIDFromContext extracts the user ID from context.
func WithRequestID ¶
WithRequestID adds a request ID to the context. This ID will be automatically included in logs.
func WithTraceID ¶
WithTraceID adds a trace ID to the context (for non-OTEL scenarios).
Types ¶
type Config ¶
Config holds the complete logger configuration. It is an alias to internal/config.Config to allow sharing with internal packages.
func Development ¶
func Development() Config
Development returns a Config optimized for development.
type ConsoleConfig ¶
type ConsoleConfig = config.ConsoleConfig
ConsoleConfig configures console output.
type Field ¶
type Field struct {
Key string
Type FieldType
Integer int64
StringVal string
Float float64
Interface any
}
Field represents a structured logging field (key-value pair). Field construction is zero-allocation for primitive types (String, Int, etc).
type Ion ¶ added in v0.2.0
type Ion struct {
// contains filtered or unexported fields
}
Ion is the unified observability instance providing logging and tracing. It implements the Logger interface directly, so you can use it for logging. It also provides access to Tracer for distributed tracing.
Example:
app, err := ion.New(cfg)
if err != nil {
log.Fatal(err)
}
defer app.Shutdown(context.Background())
// Logging (Ion implements Logger)
app.Info(ctx, "message", ion.F("key", "value"))
// Tracing
tracer := app.Tracer("myapp.component")
ctx, span := tracer.Start(ctx, "Operation")
defer span.End()
// Global usage (DEPRECATED: Prefer Dependency Injection)
ion.SetGlobal(app)
ion.Info(ctx, "works from anywhere (but try to avoid this)")
func (*Ion) Tracer ¶ added in v0.2.0
Tracer returns a named tracer for creating spans. If tracing is not enabled, returns a no-op tracer (logs warning once).
type Logger ¶
type Logger interface {
// Debug logs a message at debug level.
Debug(ctx context.Context, msg string, fields ...Field)
// Info logs a message at info level.
Info(ctx context.Context, msg string, fields ...Field)
// Warn logs a message at warn level.
Warn(ctx context.Context, msg string, fields ...Field)
// Error logs a message at error level with an error.
Error(ctx context.Context, msg string, err error, fields ...Field)
// Critical logs a message at the highest severity level but does NOT exit.
//
// Critical logs are emitted at FATAL level to ensure visibility in backends,
// but the process is GUARANTEED not to exit.
//
// Usage pattern:
// logger.Critical(ctx, "unrecoverable error", err)
// return err // Let caller decide how to handle
Critical(ctx context.Context, msg string, err error, fields ...Field)
// With returns a child logger with additional fields attached.
// Fields are included in all subsequent log entries.
With(fields ...Field) Logger
// Named returns a named sub-logger.
// The name appears in logs as the "component" field.
Named(name string) Logger
// Sync flushes any buffered log entries.
// Applications should call Sync before exiting.
Sync() error
// Shutdown gracefully shuts down the logger, flushing any buffered logs
// and closing background resources (like OTEL exporters).
Shutdown(ctx context.Context) error
// SetLevel changes the log level at runtime.
// Valid levels: debug, info, warn, error, fatal.
SetLevel(level string)
// GetLevel returns the current log level as a string.
GetLevel() string
}
Logger is the primary logging interface. All methods are safe for concurrent use. All log methods require a context.Context as the first parameter for trace correlation.
Example ¶
ctx := context.Background()
// 1. Initialize the logger
logger := newZapLogger(Development())
defer func() { _ = logger.Sync() }()
// 2. Log a simple message (context-first)
logger.Info(ctx, "Hello, World!")
// 3. Log with structured fields
logger.Info(ctx, "User logged in",
F("user_id", 42),
F("ip", "192.168.1.1"),
)
Example (ContextIntegration) ¶
// Initialize logger
logger := newZapLogger(Default())
defer func() { _ = logger.Sync() }()
// Create a context (in a real app, this comes from the request)
ctx := context.Background()
ctx = WithRequestID(ctx, "req-123")
// Context is ALWAYS the first parameter
// Trace IDs are extracted automatically
logger.Info(ctx, "Processing request")
type Span ¶ added in v0.2.0
type Span interface {
// End marks the span as complete.
End()
// SetStatus sets the span status.
SetStatus(code codes.Code, description string)
// RecordError records an error as an event.
RecordError(err error)
// SetAttributes sets attributes on the span.
SetAttributes(attrs ...attribute.KeyValue)
// AddEvent adds an event to the span.
AddEvent(name string, attrs ...attribute.KeyValue)
}
Span represents a unit of work in a trace.
type SpanOption ¶ added in v0.2.0
type SpanOption interface {
// contains filtered or unexported methods
}
SpanOption configures span creation.
func WithAttributes ¶ added in v0.2.0
func WithAttributes(attrs ...attribute.KeyValue) SpanOption
WithAttributes adds attributes to the span.
func WithSpanKind ¶ added in v0.2.0
func WithSpanKind(kind trace.SpanKind) SpanOption
WithSpanKind sets the span kind (client, server, etc).
type Tracer ¶ added in v0.2.0
type Tracer interface {
// Start creates a new span.
Start(ctx context.Context, spanName string, opts ...SpanOption) (context.Context, Span)
}
Tracer creates spans for distributed tracing.
func GetTracer ¶ added in v0.2.0
GetTracer returns a named tracer from global Ion. Note: This relies on SetGlobal being called with an *Ion instance (or implementation that supports Tracer()) If the global logger does not support Tracer, this might fail or return no-op. Since Logger interface doesn't have Tracer(), we can only check if global is *Ion. BUT, legacy GetTracer probably used `otel.Tracer`. We should probably just call `otel.Tracer` directly here or use `GetGlobal`? The previous implementation called `getGlobal().Tracer()`. Since `Logger` interface does NOT have `Tracer`, `ion.Tracer` works on `*Ion`. So `GetGlobal()` returning `Logger` logic is tricky for `Tracer`. Fix: Check type assertion.
type TracingConfig ¶ added in v0.2.0
type TracingConfig = config.TracingConfig
TracingConfig configures distributed tracing.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basic
command
|
|
|
benchmark
command
Package main provides a comprehensive benchmark suite for ion logging library.
|
Package main provides a comprehensive benchmark suite for ion logging library. |
|
otel-test
command
Package main tests ion trace correlation with OTEL and Jaeger.
|
Package main tests ion trace correlation with OTEL and Jaeger. |
|
Package fields provides blockchain-specific logging field helpers.
|
Package fields provides blockchain-specific logging field helpers. |
|
internal
|
|
|
core
Package core provides the internal implementation of Ion's logging and tracing.
|
Package core provides the internal implementation of Ion's logging and tracing. |
|
middleware
|
|
|
iongrpc
Package grpc provides gRPC server and client instrumentation using OpenTelemetry.
|
Package grpc provides gRPC server and client instrumentation using OpenTelemetry. |
|
ionhttp
Package http provides HTTP server and client instrumentation using OpenTelemetry.
|
Package http provides HTTP server and client instrumentation using OpenTelemetry. |