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/luminalogQuick Start
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
| Option | Type | Default | Description |
|---|---|---|---|
| APIKey | string | Required | Your LuminaLog API key |
| Environment | string | "default" | Label for filtering logs (stored as metadata). Actual environment is set by your API key. |
| ProjectID | string | "" | Optional project ID for multi-project setups |
| BatchSize | int | 100 | Logs to buffer before sending. Min: 50, Max: 500. Automatically capped. |
| FlushInterval | time.Duration | 5s | Duration between automatic flushes |
| Endpoint | string | api.luminalog.cloud | Custom API endpoint (for testing) |
| Debug | bool | false | Enable 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
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
SIGINT and SIGTERM. It will flush logs on process exit. Use defer logger.Shutdown() for extra safety.Framework Integration
net/http
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
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
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 one logger instance and pass it around your app.
Never hardcode API keys - use os.Getenv().
Include user_id, request_id, order_id for better debugging.
Always use defer logger.Shutdown() in main().
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
BatchSizeto reduce request frequency - Increase
FlushIntervalto batch more logs - Reduce log volume (disable debug logs in production)
- Upgrade to a higher tier for increased rate limits