Skip to content

Instantly share code, notes, and snippets.

@arsharaj
Created August 31, 2025 15:44
Show Gist options
  • Select an option

  • Save arsharaj/b4f7748171bf24650f565198e208148c to your computer and use it in GitHub Desktop.

Select an option

Save arsharaj/b4f7748171bf24650f565198e208148c to your computer and use it in GitHub Desktop.
go : slog and log to elasticsearch handler
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"log"
"log/slog"
"time"
"github.com/elastic/go-elasticsearch/v8"
)
// ElasticHandler is a slog handler that sends logs to elasticsearch
type ElasticHandler struct {
es *elasticsearch.Client
index string
level slog.Level
attr []slog.Attr
withGroup string
}
func NewElasticHandler(es *elasticsearch.Client, index string, level slog.Level) *ElasticHandler {
return &ElasticHandler{
es: es,
index: index,
level: level,
}
}
func (esh *ElasticHandler) Enabled(ctx context.Context, level slog.Level) bool {
return level >= esh.level
}
func (esh *ElasticHandler) Handle(ctx context.Context, r slog.Record) error {
data := make(map[string]any)
data["time"] = r.Time.Format(time.RFC3339)
data["level"] = r.Level.String()
data["msg"] = r.Message
r.Attrs(func(a slog.Attr) bool {
data[a.Key] = a.Value.Any()
return true
})
body, err := json.Marshal(data)
if err != nil {
return err
}
// Send to elasticsearch
res, err := esh.es.Index(
esh.index,
bytes.NewReader(body),
esh.es.Index.WithContext(ctx),
esh.es.Index.WithRefresh("true"),
)
if err != nil {
return err
}
defer res.Body.Close()
if res.IsError() {
return fmt.Errorf("error indexing log: %s", res.String())
}
return nil
}
func (esh *ElasticHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
newEsh := *esh
newEsh.attr = append(newEsh.attr, attrs...)
return &newEsh
}
func (esh *ElasticHandler) WithGroup(name string) slog.Handler {
newEsh := *esh
newEsh.withGroup = name
return &newEsh
}
func main() {
// Connect to elasticsearch
es, err := elasticsearch.NewDefaultClient()
if err != nil {
log.Fatalf("error creating es client : %v", err)
}
// Create handler
esHandler := NewElasticHandler(es, "system-logs", slog.LevelInfo)
// Create logger
logger := slog.New(esHandler)
// Example logs
logger.Info("System stated", slog.String("host", "server-01"), slog.Int("pid", 1234))
logger.Error("Disk space low", slog.String("path", "/var/log"), slog.Float64("usage", 92.4))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment