Documentation
¶
Overview ¶
Package zharp sends your Go app's logs and panics to Zharp.
Start it once in main, and close it on the way out so the last logs are sent:
func main() {
zharp.Init(zharp.Config{APIKey: "your-ingest-only-key", Service: "checkout-api"})
defer zharp.Close()
zharp.Info("User signed in", zharp.Fields{"user_id": 42})
}
Logs are queued and sent in batches from a background goroutine; Error and Fatal go at once. Logging never blocks on the network and never panics. To send log/slog records, use NewSlogHandler; to capture panics, Recover and Middleware.
Index ¶
- Constants
- func CaptureError(err error, fields ...Fields)
- func Close()
- func Debug(message any, fields ...Fields)
- func Error(message any, fields ...Fields)
- func Fatal(message any, fields ...Fields)
- func Flush(timeout time.Duration) bool
- func Info(message any, fields ...Fields)
- func Init(cfg Config)
- func IsActive() bool
- func Log(level Level, message any, fields Fields)
- func LogService(service string, level Level, message any, fields Fields)
- func Middleware(next http.Handler) http.Handler
- func NewSlogHandler(opts *SlogOptions) slog.Handler
- func Recover()
- func ResetSessionID()
- func SessionID() string
- func SetContext(fields Fields)
- func Warn(message any, fields ...Fields)
- type Config
- type Fields
- type Level
- type SlogOptions
Constants ¶
const Version = "0.1.1"
Version is this package's version.
Variables ¶
This section is empty.
Functions ¶
func CaptureError ¶
CaptureError logs err at error with its type and stack. A nil err does nothing.
if err := charge(order); err != nil {
zharp.CaptureError(err, zharp.Fields{"order_id": order.ID})
}
func Close ¶
func Close()
Close sends everything queued (waiting at most 5 seconds) and stops. Defer it in main: Go runs nothing at exit by itself, so logs still queued when main returns would be lost.
func Error ¶
Error logs at error and sends at once. An error as the message, or among the fields, brings its stack.
func Flush ¶
Flush sends everything queued and waits up to timeout for it. It reports whether all of it went. Normally not needed: logs go out every few seconds and errors at once — but call it before a serverless function returns.
func Init ¶
func Init(cfg Config)
Init starts sending logs. Call it once, as early as possible in main, and defer Close.
It prints one line to stderr:
[Zharp] Logging active — service "checkout-api", environment "production"
With no API key anywhere it prints how to give it one and starts nothing; ZHARP_DISABLED=true turns it off whatever the code says. It never returns an error or panics. Calling it again replaces the running setup; what the old one had queued is still sent.
func IsActive ¶
func IsActive() bool
IsActive reports whether Init succeeded and logs are being sent.
func LogService ¶
LogService logs at any level under another service than the one set in Init.
func Middleware ¶
Middleware sends a panic in an HTTP handler as an error log with its stack and the request's method and path, then panics again so net/http handles it as it would have (it ends that request and keeps serving).
http.ListenAndServe(":8080", zharp.Middleware(mux))
func NewSlogHandler ¶
func NewSlogHandler(opts *SlogOptions) slog.Handler
NewSlogHandler returns a log/slog handler that sends records to Zharp, at the matching level (slog.LevelWarn → warn; above slog.LevelError → fatal). Attributes become the log's fields, groups nested; an error attribute brings its stack. Start Zharp with Init first.
slog.SetDefault(slog.New(zharp.NewSlogHandler(nil)))
slog.Warn("Stock low", "sku", "SKU-1")
To keep printing to the console too, send records to both handlers — see the README.
func Recover ¶
func Recover()
Recover sends a panic as a fatal log with its stack, waits briefly for it to go out, then panics again — so the program ends as it would have. Defer it first thing in main, and in any goroutine whose panics you want to see:
func main() {
zharp.Init(zharp.Config{})
defer zharp.Close()
defer zharp.Recover()
…
}
Go has no global hook for panics, so a goroutine without it ends the program unseen.
func ResetSessionID ¶
func ResetSessionID()
ResetSessionID starts a new session ID, e.g. per job in a long-running worker.
func SessionID ¶
func SessionID() string
SessionID is the ID every log of this run carries, so one run's logs can be found together.
func SetContext ¶
func SetContext(fields Fields)
SetContext sets extra fields added to every log's context, e.g. a deployment's region. Replaces what was set before; pass nil to clear it.
Types ¶
type Config ¶
type Config struct {
// APIKey is an Ingest only key from Integrations & API → Main API keys. Without one, nothing
// starts.
APIKey string
// Service is the name logs are filed under. Defaults to the last part of the main module's
// path (github.com/acme/checkout-api → checkout-api), else "unknown-service".
Service string
// Environment tags every log, e.g. "production". Not guessed when unset.
Environment string
// AppVersion tags every log, so you can filter to one release.
AppVersion string
// Source tags every log with what wrote it.
Source string
// Endpoint is where logs are sent. Defaults to https://api.zharp.io/api/v1.
Endpoint string
// FlushInterval is how long logs wait to be sent together. 5 seconds when zero.
FlushInterval time.Duration
// MaxBatchSize is the most logs sent in one request. 50 when zero.
MaxBatchSize int
// HTTPClient sends the requests. One with a 15-second timeout when nil.
HTTPClient *http.Client
}
Config holds the settings for Init. Every field is optional: anything left empty is read from the environment (ZHARP_API_KEY, ZHARP_SERVICE then OTEL_SERVICE_NAME, ZHARP_ENV, ZHARP_VERSION, ZHARP_SOURCE, ZHARP_ENDPOINT), then defaulted.
type Fields ¶
Fields are extra data kept with a log. Values are copied when the log is made, so changing the map afterwards doesn't change a log waiting to be sent. An error among them brings its stack.
type SlogOptions ¶
type SlogOptions struct {
// Level is the lowest level sent. slog.LevelInfo when nil.
Level slog.Leveler
}
SlogOptions configures NewSlogHandler.
