slogelastic

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2025 License: Apache-2.0 Imports: 10 Imported by: 0

README

Go Report Card GoDoc Coverage License

Slog-Elastic - implementation of slog.Handler for elasticsearch

Golang have structural logging for some time, named slog. It even has rich and Awesome Slog ecosystem. This package is very young, your feedback is welcome.

Why?

Why use ElasticSearch directly? There is Logstash after all. But sometimes You...

  • Develop locally, and still want persistency.
  • Have IoT solution, and don't want big guns.
  • Didn't get access to logstash from Your operations department.

This package was made to solve the above. Having somewhat decent implementation would be better than cobbling ad-hoc solutions in every project.

Features

  • Implements slog.Handler
  • Extracts values from Context using ContextAttrFunc
  • Utility function to connect database
  • Utility function to load ES_LOG_xx from .env or environment.
  • Works with zinc
  • Works with elasticsearch
  • Ability to overwrite error handler

Usage

// initialize by config
slogEsCfg := slogelastic.Config{
	Address:  "https://example.com",
	Index:    "some-log-index",
	User:     "john",
	Pass:     "secret",
	MinLevel: slog.LevelDebug,
}

// load from .env or enviroment ES_LOG_xxx
err := slogEsCfg.LoadFromEnv()
if err != nil {
	log.Fatal(err)
}

// connecting to ElasticSearch and selecting index
err = slogEsCfg.ConnectEsLog()
if err != nil {
	log.Fatal(err)
}

// or use arleady established connection
slogEsCfg.ESIndex = slogelastic.AlreadyConnected()

// finalize configuration and build slog.Handler
esHandler := slogEsCfg.NewElasticHandler()

// To see output in terminal, we recomend slogmulti.Fanout from Samber
slog.SetDefault(slog.New(esHandler))

// now we can use persistent logging in rest of application
slog.Info("Registered banana", "bannanaId", 42)
slog.Warn("Invalid monkeyId", "monkeyId", "mojo")
slog.Error("BannanaDB connection failed", "error", "unknown protocol banana://")

Planned features and to-do

  • Ability for client code to filter/rename attributes.
  • Safeguard to propagate all logs before application shutdown.
  • Bulk inserts asynchronously.

Documentation

Overview

Example
package main

import (
	"log"
	"log/slog"

	slogelastic "github.com/nicus101/slog-elastic"
)

func main() {
	// initialize by config
	slogEsCfg := slogelastic.Config{
		Address:  "https://example.com",
		Index:    "some-log-index",
		User:     "john",
		Pass:     "secret",
		MinLevel: slog.LevelDebug,
	}

	// load from .env or enviroment ES_LOG_xxx
	err := slogEsCfg.LoadFromEnv()
	if err != nil {
		log.Fatal(err)
	}

	// connecting to ElasticSearch and selecting index
	err = slogEsCfg.ConnectEsLog()
	if err != nil {
		log.Fatal(err)
	}

	// or use arleady established connection
	slogEsCfg.ESIndex = slogelastic.AlreadyConnected()

	// finalize configuration and build slog.Handler
	esHandler := slogEsCfg.NewElasticHandler()

	// To see output in terminal, we recomend slogmulti.Fanout from Samber
	slog.SetDefault(slog.New(esHandler))

	// now we can use persistent logging in rest of application
	slog.Info("Registered banana", "bannanaId", 42)
	slog.Warn("Invalid monkeyId", "monkeyId", "mojo")
	slog.Error("BannanaDB connection failed", "error", "unknown protocol banana://")

}
Output:
{"bannanaId":42,"level":"INFO","message":"Registered banana","time":"0001-01-01T00:00:00Z"}
{"level":"WARN","message":"Invalid monkeyId","monkeyId":"mojo","time":"0001-01-01T00:00:00Z"}
{"error":"unknown protocol banana://","level":"ERROR","message":"BannanaDB connection failed","time":"0001-01-01T00:00:00Z"}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Address string `env:"ES_LOG_ADDRESS"`
	Index   string `env:"ES_LOG_INDEX"`
	User    string `env:"ES_LOG_USER"`
	Pass    string `env:"ES_LOG_PASS"`

	ESIndex      *index.Index
	MinLevel     slog.Level
	ContextFuncs []ContextAttrFunc
	ErrorHandler ErrorHandlerFunc
}

func (*Config) ConnectEsLog

func (cfg *Config) ConnectEsLog() error

ConnectEsLog establishes a connection to Elasticsearch using the configured credentials and initializes the ESIndex client for the specified index. It returns an error if the connection cannot be established.

func (*Config) LoadFromEnv

func (cfg *Config) LoadFromEnv() error

LoadFromEnv loads configuration from environment variables, optionally reading from a .env file if present. It validates required fields and returns an error if any required field is missing or if there are issues loading the environment variables. The function will not return an error if the .env file is missing, but will return errors for other file-related issues.

func (Config) NewElasticHandler

func (cfg Config) NewElasticHandler() slog.Handler

NewElasticHandler creates a new Handler with the given configuration and options

type ContextAttrFunc

type ContextAttrFunc func(context.Context) []slog.Attr

type ErrorHandlerFunc

type ErrorHandlerFunc func(error)

type Handler

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

func (*Handler) Enabled

func (h *Handler) Enabled(ctx context.Context, level slog.Level) bool

Enabled checks if the given log level meets the minimum level requirement

func (*Handler) Handle

func (h *Handler) Handle(ctx context.Context, rec slog.Record) error

Handle processes a log record, converting it to a document and sending it to Elasticsearch

func (*Handler) WithAttrs

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

WithAttrs returns the handler itself, maintaining compatibility with slog.Handler interface

func (*Handler) WithGroup

func (h *Handler) WithGroup(name string) slog.Handler

WithGroup creates a new handler with the given group name appended to the groups slice

Directories

Path Synopsis
cmd
slog-sim command

Jump to

Keyboard shortcuts

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