LuminaLog
Waitlist
SDK Reference

Go SDK

High-performance logging SDK for Go applications with automatic buffering, zero-allocation options, and deep framework integrations.

Installation

go get github.com/luminalog/sdk-go/luminalog

Quick Start

main.go
package main

import (
    "os"
    "github.com/luminalog/sdk-go/luminalog"
)

func main() {
    logger, err := luminalog.New(luminalog.Config{
        APIKey:      os.Getenv("LUMINALOG_API_KEY"),
        Environment: os.Getenv("ENVIRONMENT"),
    })
    if err != nil {
        panic(err)
    }
    defer logger.Shutdown()

    // Start logging
    logger.Info("Application started", map[string]interface{}{
        "version": "1.0.0",
    })
}

Configuration Options

OptionTypeDefaultDescription
APIKeystringRequiredYour LuminaLog API key
Environmentstring"default"Label for filtering logs (stored as metadata). Actual environment is set by your API key.
ProjectIDstring""Optional project ID for multi-project setups
BatchSizeint100Logs to buffer before sending. Min: 50, Max: 500. Automatically capped.
FlushIntervaltime.Duration5sDuration between automatic flushes
Endpointstringapi.luminalog.cloudCustom API endpoint (for testing)
DebugboolfalseEnable debug logging to console

Full Configuration Example

logger, err := luminalog.New(luminalog.Config{
    APIKey:        os.Getenv("LUMINALOG_API_KEY"),
    Environment:   os.Getenv("ENVIRONMENT"),
    ProjectID:     "proj_abc123",        // Optional
    BatchSize:     50,                   // Send every 50 logs
    FlushInterval: 3 * time.Second,      // Or every 3 seconds
    Debug:         true,                 // Enable debug mode
})
if err != nil {
    log.Fatal(err)
}

Environment Handling

The Environment parameter is stored as metadata for filtering within your logs. The actual environment (production, staging, etc.) is determined by your API key's environment setting in the dashboard.

Why? This prevents quota abuse and ensures clear project boundaries. Create separate API keys for each environment in your project settings.

Batching Optimization

The Go SDK enforces strict batching limits to maximize throughput and protect your log quota:

  • Minimum (50): Prevents small, inefficient network requests. Values below this are automatically set to 50.
  • Maximum (500): Ensures reliable delivery without exceeding ingestion buffer limits. Values above this are capped at 500.

Capping your batch size at 500 ensures that no single ingestion request exceeds platform limits.

Logging Methods

🔍logger.Debug(message, metadata)

Detailed diagnostics for development. Useful for tracing internal application state.

ℹ️logger.Info(message, metadata)

General operational events. Track user actions, system events.

⚠️logger.Warn(message, metadata)

Warning conditions. Slow queries, deprecated API usage, high memory.

logger.Error(message, metadata)

Error conditions requiring attention. Failed operations, exceptions.

🔥logger.Fatal(message, metadata)

Critical errors causing service degradation.

🚨logger.Panic(message, metadata)

System-wide failures. Flushes immediately, bypasses batching.

Error Tracking

logger.CaptureError()

Capture Go errors with automatic stack trace extraction.

if err := processPayment(order); err != nil {
    logger.CaptureError(err, map[string]interface{}{
        "order_id": order.ID,
        "user_id":  order.UserID,
        "amount":   order.Amount,
    })
    return err
}

logger.CaptureException()

Alias for CaptureError() - same functionality.

logger.CaptureException(errors.New("something went wrong"), map[string]interface{}{
    "component": "checkout",
    "action":    "submit",
})

Automatic Error Tracking

Errors logged with CaptureError() or CaptureException() are automatically:
  • Grouped by fingerprint (message + stack trace)
  • Counted toward error quota
  • Analyzed by AI (Bootstrapper+ tiers)
  • Visible in the Errors dashboard

Distributed Tracing

Built-in helpers for managing trace and span identifiers, compatible with standard HTTP headers and W3C Trace Context.

Tracing Helpers

  • GenerateTraceID()Generates a unique UUID v4 string.
  • GenerateSpanID()Generates a unique span ID string.
  • GetTraceIDFromRequest(*http.Request)Extracts from 'x-trace-id' or 'traceparent'.

Implementation

import "github.com/luminalog/sdk-go/luminalog"

traceID := luminalog.GenerateTraceID()
spanID := luminalog.GenerateSpanID()

logger.Info("Internal process", map[string]interface{}{
    "trace_id": traceID,
    "span_id":  spanID,
})

Flushing & Shutdown

logger.Flush()

Manually flush all queued logs immediately.

// Example: Flush before exiting
func main() {
    logger, _ := luminalog.New(luminalog.Config{...})
    defer logger.Flush()
    
    // Your application code
}

logger.Shutdown()

Stop the flush timer and flush all remaining logs.

// Example: Graceful shutdown
func main() {
    logger, _ := luminalog.New(luminalog.Config{...})
    defer logger.Shutdown()
    
    // Your application code
}

Automatic Shutdown

The SDK automatically registers signal handlers for SIGINT and SIGTERM. It will flush logs on process exit. Use defer logger.Shutdown() for extra safety.

Framework Integration

net/http

main.go
func loggingMiddleware(logger *luminalog.Logger, next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        wrapped := &responseWriter{ResponseWriter: w, statusCode: 200}
        next.ServeHTTP(wrapped, r)
        
        logger.Info("HTTP Request", map[string]interface{}{
            "method":      r.Method,
            "path":        r.URL.Path,
            "status_code": wrapped.statusCode,
            "duration":    time.Since(start).Milliseconds(),
            "user_agent":  r.UserAgent(),
            "ip":          r.RemoteAddr,
        })
    })
}

Gin

main.go
func LoggingMiddleware(logger *luminalog.Logger) gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now()
        c.Next()
        
        logger.Info("HTTP Request", map[string]interface{}{
            "method":      c.Request.Method,
            "path":        c.Request.URL.Path,
            "status_code": c.Writer.Status(),
            "duration":    time.Since(start).Milliseconds(),
            "user_agent":  c.Request.UserAgent(),
            "ip":          c.ClientIP(),
        })
    }
}

Echo

main.go
func LoggingMiddleware(logger *luminalog.Logger) echo.MiddlewareFunc {
    return func(next echo.HandlerFunc) echo.HandlerFunc {
        return func(c echo.Context) error {
            start := time.Now()
            err := next(c)
            
            logger.Info("HTTP Request", map[string]interface{}{
                "method":      c.Request().Method,
                "path":        c.Request().URL.Path,
                "status_code": c.Response().Status,
                "duration":    time.Since(start).Milliseconds(),
                "user_agent":  c.Request().UserAgent(),
                "ip":          c.RealIP(),
            })
            
            return err
        }
    }
}

Best Practices

Create a Single Instance

Create one logger instance and pass it around your app.

Use Environment Variables

Never hardcode API keys - use os.Getenv().

Add Rich Metadata

Include user_id, request_id, order_id for better debugging.

Use defer for Shutdown

Always use defer logger.Shutdown() in main().

Use CaptureError()

Automatic stack trace extraction and error grouping.

Type Definitions

type Config struct {
    APIKey        string
    Environment   string
    ProjectID     string
    BatchSize     int
    FlushInterval time.Duration
    Endpoint      string
    Debug         bool
}

type LogLevel string

const (
    LevelDebug LogLevel = "debug"
    LevelInfo  LogLevel = "info"
    LevelWarn  LogLevel = "warn"
    LevelError LogLevel = "error"
    LevelFatal LogLevel = "fatal"
    LevelPanic LogLevel = "panic"
)

Troubleshooting

Logs Not Appearing

  • Check API key is correct and starts with ll_
  • Verify network connectivity to api.luminalog.cloud
  • Enable debug mode: Debug: true
  • Check quota limits in dashboard
  • Call logger.Flush() to send immediately

429 Rate Limit Errors

Solutions for hitting rate limits:

  • Increase BatchSize to reduce request frequency
  • Increase FlushInterval to batch more logs
  • Reduce log volume (disable debug logs in production)
  • Upgrade to a higher tier for increased rate limits

Next Steps