slogprovider

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2025 License: MPL-2.0 Imports: 5 Imported by: 0

README

Iris Provider: slog

an AGILira library

CI/CD Go Report Card Go Version

External provider for integrating Go's standard log/slog package with Iris logging framework.

Features

  • Zero Code Changes: Use existing slog code unchanged
  • 10x Performance: Benefit from Iris's 31ns/op logging performance
  • Feature Inheritance: Automatic OpenTelemetry, writers, security features
  • Drop-in Replacement: Simply replace slog.Handler with Iris provider

Installation

go get github.com/agilira/iris-provider-slog

Usage

Basic Integration
package main

import (
    "log/slog"
    "os"
    
    "github.com/agilira/iris"
    slogprovider "github.com/agilira/iris-provider-slog"
)

func main() {
    // Create slog provider
    provider := slogprovider.New(1000)
    defer provider.Close()
    
    // Create Iris logger with provider
    readers := []iris.SyncReader{provider}
    logger, _ := iris.NewReaderLogger(iris.Config{
        Output:  iris.WrapWriter(os.Stdout),
        Encoder: iris.NewJSONEncoder(),
        Level:   iris.Info,
    }, readers)
    defer logger.Close()
    
    logger.Start()
    
    // Use slog normally - but get Iris performance!
    slogger := slog.New(provider)
    slogger.Info("User login", "user_id", "12345")
}
Advanced Features
// For advanced features like Loki integration, install the writer module:
// go get github.com/agilira/iris-writer-loki

import loki "github.com/agilira/iris-writer-loki"

// Create Loki writer
lokiWriter, err := loki.NewWriter(loki.Config{
    Endpoint: "http://loki:3100/loki/api/v1/push",
    Labels: map[string]string{
        "service": "my-app",
        "source":  "slog",
    },
})
if err != nil {
    panic(err)
}
defer lokiWriter.Close()

// Create Iris logger with all advanced features
logger, _ := iris.NewReaderLogger(iris.Config{
    Output: iris.MultiWriter(
        iris.WrapWriter(os.Stdout),
        lokiWriter, // Loki integration via external module
    ),
    Encoder: iris.NewJSONEncoder(),
    Level:   iris.Debug,
}, readers,
    iris.WithOTel(),    // OpenTelemetry integration
    iris.WithCaller(),  // Caller information
)

// Now slog gets ALL Iris features automatically:
// ✅ OpenTelemetry trace correlation
// ✅ Grafana Loki batching  
// ✅ Automatic secret redaction
// ✅ High-performance ring buffer
slogger.Info("Payment", "amount", 100, "api_key", "secret") // api_key redacted

Examples

See the examples/basic directory for a complete working example demonstrating all features.

Run the basic example:

go run examples/basic/main.go

Performance

  • slog Handle: ~56 ns/op
  • Record Conversion: ~745 ns/op
  • Overall: 20x+ faster than standard slog

Architecture

This provider implements the iris.SyncReader interface, allowing slog records to be processed by Iris's high-performance pipeline:

slog.Logger → SlogProvider → iris.SyncReader → Iris Ring Buffer → Features

License

iris-provider-slog is licensed under the Mozilla Public License 2.0.


iris-provider-slog • an AGILira library

Documentation

Overview

Package slogprovider provides an iris.SyncReader implementation for Go's standard log/slog package.

This provider enables existing slog-based applications to benefit from Iris's high-performance logging pipeline without requiring code changes. It implements both the iris.SyncReader interface for integration with Iris and the slog.Handler interface for compatibility with slog.

Key Features

  • Zero Code Changes: Use existing slog code unchanged with enhanced performance
  • High Performance: 10-20x faster than standard slog through Iris acceleration
  • Feature Inheritance: Automatic OpenTelemetry, security, and advanced Iris features
  • Drop-in Replacement: Simply replace slog.Handler with this provider
  • Thread Safety: Safe for concurrent access from multiple goroutines

Performance Characteristics

  • slog Handle: ~60-150 ns/op (compared to ~1000+ ns/op for standard handlers)
  • Record Conversion: ~500-1000 ns/op with zero additional allocations
  • Overall: 10-20x faster than standard slog implementations

Basic Usage

import (
    "log/slog"
    "os"
    "github.com/agilira/iris"
    slogprovider "github.com/agilira/iris-provider-slog"
)

func main() {
    // Create provider
    provider := slogprovider.New(1000)
    defer provider.Close()

    // Create Iris logger with provider
    readers := []iris.SyncReader{provider}
    logger, err := iris.NewReaderLogger(iris.Config{
        Output:  iris.WrapWriter(os.Stdout),
        Encoder: iris.NewJSONEncoder(),
        Level:   iris.Info,
    }, readers)
    if err != nil {
        panic(err)
    }
    defer logger.Close()

    logger.Start()

    // Use slog normally - but get Iris performance!
    slogger := slog.New(provider)
    slogger.Info("User login", "user_id", "12345")
}

Advanced Integration

For advanced features like Loki integration, install the writer module:

go get github.com/agilira/iris-writer-loki

Then configure multiple outputs:

import loki "github.com/agilira/iris-writer-loki"

lokiWriter, err := loki.NewWriter(loki.Config{
    Endpoint: "http://loki:3100/loki/api/v1/push",
    Labels: map[string]string{"service": "my-app"},
})
if err != nil {
    panic(err)
}

logger, err := iris.NewReaderLogger(iris.Config{
    Output: iris.MultiWriter(
        iris.WrapWriter(os.Stdout),
        lokiWriter,
    ),
    Encoder: iris.NewJSONEncoder(),
}, readers,
    iris.WithOTel(),    // OpenTelemetry integration
    iris.WithCaller(),  // Caller information
)

Now slog gets ALL Iris features automatically:

  • OpenTelemetry trace correlation
  • Grafana Loki batching
  • Automatic secret redaction
  • High-performance ring buffer

Architecture

This provider implements the iris.SyncReader interface, allowing slog records to be processed by Iris's high-performance pipeline:

slog.Logger → SlogProvider → iris.SyncReader → Iris Ring Buffer → Features

The provider maintains an internal buffer of slog records and converts them to Iris records on demand. This design ensures:

  • Non-blocking slog operations
  • Efficient batching and processing
  • Automatic cleanup and resource management
  • Graceful handling of buffer overflow conditions

Thread Safety

All provider operations are thread-safe:

  • Multiple goroutines can call Handle() simultaneously
  • Read() operations are safe for concurrent access
  • Close() can be called while other operations are in progress
  • Internal state is protected with appropriate synchronization

Buffer Management

The provider uses a buffered channel for record storage:

  • Buffer size is configurable during construction
  • Full buffers result in record dropping (non-blocking behavior)
  • Buffer size should be tuned based on logging volume and processing speed
  • Recommended buffer sizes: 100-1000 for typical applications, 1000+ for high-volume

Error Handling

The provider follows Iris patterns for error handling:

  • Handle() drops records on buffer full rather than blocking
  • Read() respects context cancellation for graceful shutdown
  • Close() is idempotent and safe to call multiple times
  • Conversion errors are handled gracefully with fallback behavior

Level Mapping

Slog levels are mapped to Iris levels as follows:

  • slog.LevelDebug → iris.Debug
  • slog.LevelInfo → iris.Info
  • slog.LevelWarn → iris.Warn
  • slog.LevelError → iris.Error
  • Custom levels are mapped to the nearest Iris level

Field Conversion

Slog attributes are converted to Iris fields with type preservation:

  • String values → iris.String
  • Integer values → iris.Int64
  • Float values → iris.Float64
  • Boolean values → iris.Bool
  • Duration values → iris.Dur
  • Time values → iris.Time
  • Other types → iris.String (with String() conversion)

Dependencies

This package requires:

  • github.com/agilira/iris (core logging library)
  • Go's standard log/slog package (Go 1.21+)

No additional dependencies are required for basic functionality.

License

iris-provider-slog is licensed under the Mozilla Public License 2.0.

Copyright (c) 2025 AGILira Series: an AGILira library SPDX-License-Identifier: MPL-2.0

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Provider

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

Provider implements iris.SyncReader for Go's standard log/slog package.

Provider acts as a bridge between slog and Iris, implementing both the iris.SyncReader interface for Iris integration and the slog.Handler interface for slog compatibility. It captures slog records in an internal buffer and converts them to Iris records on demand.

The provider is designed for high performance and thread safety:

  • Non-blocking Handle() operations (drops records on buffer full)
  • Efficient record conversion with type preservation
  • Safe concurrent access from multiple goroutines
  • Graceful shutdown with proper resource cleanup

Example usage:

provider := slogprovider.New(1000)
defer provider.Close()

slogger := slog.New(provider)
slogger.Info("Message", "key", "value")

func New

func New(bufferSize int) *Provider

New creates a new Provider that captures slog records for processing by Iris.

The bufferSize parameter controls the internal channel buffer size. A larger buffer provides better performance under burst loads but uses more memory. Recommended values:

  • 100-500: Low to moderate logging volume applications
  • 1000-5000: High volume applications
  • 5000+: Very high volume or burst-heavy applications

When the buffer is full, new records are dropped to maintain non-blocking behavior. Monitor your application's logging patterns to choose an appropriate buffer size.

The returned Provider must be closed when no longer needed to free resources:

provider := New(1000)
defer provider.Close()

func (*Provider) Close

func (p *Provider) Close() error

Close implements io.Closer to gracefully shut down the provider.

This method signals the provider to stop accepting new records and allows pending Read() operations to complete gracefully. It's safe to call multiple times and from multiple goroutines.

After Close() is called:

  • Handle() will return an error for new records
  • Read() will return nil, nil after processing remaining buffered records
  • The provider should not be used for new operations

Close() does not wait for pending operations to complete. Use context cancellation and proper coordination if you need to ensure all records are processed before shutdown.

func (*Provider) Enabled

func (p *Provider) Enabled(ctx context.Context, level slog.Level) bool

Enabled implements slog.Handler to indicate whether records at the given level should be processed.

This implementation always returns true, allowing Iris to handle level filtering according to its own configuration. This approach provides more flexibility and ensures that level changes in Iris are respected without requiring provider reconfiguration.

If you need level filtering at the slog level, consider creating a wrapper handler that checks levels before delegating to this provider.

func (*Provider) Handle

func (p *Provider) Handle(ctx context.Context, record slog.Record) error

Handle implements slog.Handler to capture slog records for processing by Iris.

This method is called by the slog library for each log record. It attempts to store the record in the internal buffer for later processing by Iris. The operation is non-blocking:

  • If buffer space is available, the record is stored successfully
  • If the provider is closed, an error is returned
  • If the buffer is full, the record is dropped silently (returns nil)

The non-blocking behavior ensures that logging never blocks the application, even under high load conditions. Applications should monitor buffer sizes and provider performance if record dropping is a concern.

Thread Safety: Safe for concurrent access from multiple goroutines.

func (*Provider) Read

func (p *Provider) Read(ctx context.Context) (*iris.Record, error)

Read implements iris.SyncReader to provide slog records to the Iris pipeline.

This method is called by Iris to retrieve the next available log record for processing. It blocks until:

  • A record becomes available (returns the converted record)
  • The context is cancelled (returns context error)
  • The provider is closed (returns nil, nil)

The method converts slog records to Iris records, preserving message content, level information, and all attributes with appropriate type conversion.

Thread Safety: Safe for concurrent access, though typically called by a single Iris reader goroutine.

func (*Provider) WithAttrs

func (p *Provider) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs implements slog.Handler to create a handler with additional attributes.

This implementation returns the same provider instance, as attribute handling is delegated to the slog library. The slog library will include the attributes in each record before calling Handle(), so no special handling is needed here.

For more sophisticated attribute handling, consider implementing a wrapper handler that manages attributes before delegating to this provider.

func (*Provider) WithGroup

func (p *Provider) WithGroup(name string) slog.Handler

WithGroup implements slog.Handler to create a handler with a named group.

This implementation returns the same provider instance, as group handling is delegated to the slog library. The slog library will structure the attributes appropriately before calling Handle(), so no special handling is needed here.

For more sophisticated group handling, consider implementing a wrapper handler that manages groups before delegating to this provider.

Directories

Path Synopsis
examples
basic command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL