Skip to content

samber/slog-parquet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

76e3022 Β· Mar 4, 2025

History

56 Commits
Nov 19, 2024
Mar 4, 2025
Aug 19, 2023
Aug 19, 2023
Nov 1, 2023
Mar 4, 2025
Jul 1, 2024
Aug 19, 2023
Mar 4, 2025
Mar 4, 2025
Jul 10, 2024
Aug 19, 2023
Aug 19, 2023
Aug 19, 2023
Jun 27, 2024
Aug 19, 2023

Repository files navigation

slog: Parquet handler

tag Go Version GoDoc Build Status Go report Coverage Contributors License

A parquet Handler for slog Go library.

See also:

HTTP middlewares:

Loggers:

Log sinks:

πŸš€ Install

go get github.com/samber/slog-parquet/v2

Compatibility: go >= 1.21

No breaking changes will be made to exported APIs before v3.0.0.

πŸ’‘ Usage

GoDoc: https://pkg.go.dev/github.com/samber/slog-parquet/v2

Handler options

type Option struct {
    // log level (default: debug)
    Level slog.Leveler

    // parquet rows buffer
    Buffer slogparquet.ParquetBuffer

    // optional: customize json payload builder
    Converter Converter
    // optional: fetch attributes from context
    AttrFromContext []func(ctx context.Context) []slog.Attr

    // optional: see slog.HandlerOptions
    AddSource   bool
    ReplaceAttr func(groups []string, a slog.Attr) slog.Attr
}

Other global parameters:

slogparquet.SourceKey = "source"
slogparquet.ErrorKeys = []string{"error", "err"}

Parquet buffer

func NewParquetBuffer(bucket objstore.Bucket, prefix string, maxRecords int, maxInterval time.Duration) slogparquet.ParquetBuffer

Attributes will be injected in log payload.

Object storage

See github.com/thanos-io/objstore.

Example

import (
    "log/slog"

    slogparquet "github.com/samber/slog-parquet/v2"
    "github.com/thanos-io/objstore/providers/s3"
)

func main() {
    bucket, _ := s3.NewBucketWithConfig(
        slogparquet.NewLogger(),
        s3.Config{
            Endpoint:  os.Getenv("AWS_S3_ENDPOINT"),
            Region:    os.Getenv("AWS_S3_REGION"),
            Bucket:    os.Getenv("AWS_S3_BUCKET"),
            AccessKey: os.Getenv("AWS_ACCESS_KEY"),
            SecretKey: os.Getenv("AWS_SECRET_KEY"),
            PartSize:  16 * 1024 * 1024, // 16MB
        },
        "logger",
    )

    buffer := slogparquet.NewParquetBuffer(bucket, "api/logs", 10*1024*1024)

    logger := slog.New(slogparquet.Option{Level: slog.LevelDebug, Buffer: buffer}.NewParquetHandler())
    logger = logger.
        With("environment", "dev").
        With("release", "v1.0.0")

    // log error
    logger.
        With("category", "sql").
        With("query.statement", "SELECT COUNT(*) FROM users;").
        With("query.duration", 1*time.Second).
        With("error", fmt.Errorf("could not count users")).
        Error("caramba!")

    // log user signup
    logger.
        With(
            slog.Group("user",
                slog.String("id", "user-123"),
                slog.Time("created_at", time.Now()),
            ),
        ).
        Info("user registration")

    buffer.Flush(true)
    bucket.Close()
}

Output:

$ parquet meta ~/Downloads/00_17_08.d4d9f.parquet

File path:  /Users/samber/Downloads/00_17_08.d4d9f.parquet
Created by: github.com/samber/slog-parquet version (devel)(build )
Properties: (none)
Schema:
message log {
  required int64 time (TIMESTAMP(NANOS,true));
  required binary log_level (STRING);
  required binary message (STRING);
  required binary attributes;
  required binary source (STRING);
}


Row group 0:  count: 2  279.00 B records  start: 51  total(compressed): 558 B total(uncompressed):644 B 
--------------------------------------------------------------------------------
            type      encodings count     avg size   nulls   min / max
time        INT64     F   _     2         22.50 B            "2023-08-19T00:17:08.14408..." / "2023-08-19T00:17:08.14420..."
log_level   BINARY    F         2         26.50 B            "ERROR" / "INFO"
message     BINARY    F         2         35.00 B            "caramba!" / "user registration"
attributes  BINARY    F         2         155.50 B           "0x7B2263617465676F7279223..." / "0x7B22656E7669726F6E6D656..."
source      BINARY    F         2         39.50 B            "samber/slog-parquet" / "samber/slog-parquet"

Tracing

Import the samber/slog-otel library.

import (
	slogparquet "github.com/samber/slog-parquet"
	slogotel "github.com/samber/slog-otel"
	"go.opentelemetry.io/otel/sdk/trace"
)

func main() {
	tp := trace.NewTracerProvider(
		trace.WithSampler(trace.AlwaysSample()),
	)
	tracer := tp.Tracer("hello/world")

	ctx, span := tracer.Start(context.Background(), "foo")
	defer span.End()

	span.AddEvent("bar")

	logger := slog.New(
		slogparquet.Option{
			// ...
			AttrFromContext: []func(ctx context.Context) []slog.Attr{
				slogotel.ExtractOtelAttrFromContext([]string{"tracing"}, "trace_id", "span_id"),
			},
		}.NewParquetHandler(),
	)

	logger.ErrorContext(ctx, "a message")
}

🀝 Contributing

Don't hesitate ;)

# Install some dev dependencies
make tools

# Run tests
make test
# or
make watch-test

πŸ‘€ Contributors

Contributors

πŸ’« Show your support

Give a ⭐️ if this project helped you!

GitHub Sponsors

πŸ“ License

Copyright Β© 2023 Samuel Berthe.

This project is MIT licensed.