Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<p align="center">
<a href="https://github.com/loglayer/loglayer-go/releases"><img src="https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=v*&sort=date&label=version&style=flat-square&color=blue" alt="Latest version"></a>
<a href="https://pkg.go.dev/go.loglayer.dev"><img src="https://pkg.go.dev/badge/go.loglayer.dev.svg" alt="Go Reference"></a>
<a href="https://pkg.go.dev/go.loglayer.dev/v2"><img src="https://pkg.go.dev/badge/go.loglayer.dev.svg" alt="Go Reference"></a>
<a href="https://github.com/loglayer/loglayer-go/actions/workflows/ci.yml"><img src="https://github.com/loglayer/loglayer-go/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
</p>
Expand All @@ -26,8 +26,8 @@ For full documentation, read the [docs](https://go.loglayer.dev).
import (
"errors"

"go.loglayer.dev"
"go.loglayer.dev/transports/structured"
"go.loglayer.dev/v2"
"go.loglayer.dev/transports/structured/v2"
)

log := loglayer.New(loglayer.Config{
Expand Down Expand Up @@ -85,7 +85,7 @@ log.WithPrefix("[my-app]").
## Install

```sh
go get go.loglayer.dev
go get go.loglayer.dev/v2
```

## Documentation
Expand All @@ -98,7 +98,7 @@ Coming from [loglayer for TypeScript](https://loglayer.dev)? See [For TypeScript

## Contributing

This is a multi-module repo: the framework core lives at the root (`go.loglayer.dev`); every transport, plugin, and integration ships as its own independently-versioned Go module under `transports/`, `plugins/`, and `integrations/`.
This is a multi-module repo: the framework core lives at the root (`go.loglayer.dev/v2`); every transport, plugin, and integration ships as its own independently-versioned Go module under `transports/`, `plugins/`, and `integrations/`.

- **Dev-loop on-ramp** (prerequisites, hooks, make targets, commits, tests, docs, releases via [monorel](https://monorel.disaresta.com)): [CONTRIBUTING.md](CONTRIBUTING.md).
- **Architectural context** (multi-module split, thread-safety contract, performance log, release flow internals): [AGENTS.md](AGENTS.md).
Expand Down
10 changes: 5 additions & 5 deletions docs/src/benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ With LogLayer, swapping the underlying transport is a one-line change in `New()`

```go
import (
"go.loglayer.dev"
"go.loglayer.dev/integrations/sloghandler"
"go.loglayer.dev/transports/structured"
llzero "go.loglayer.dev/transports/zerolog"
llzap "go.loglayer.dev/transports/zap"
"go.loglayer.dev/v2"
"go.loglayer.dev/integrations/sloghandler/v2"
"go.loglayer.dev/transports/structured/v2"
llzero "go.loglayer.dev/transports/zerolog/v2"
llzap "go.loglayer.dev/transports/zap/v2"
)

// Wrap zerolog (142 ns)
Expand Down
12 changes: 6 additions & 6 deletions docs/src/cheatsheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ description: One-page quick reference of the LogLayer for Go API.

```go
import (
"go.loglayer.dev"
"go.loglayer.dev/transports/structured"
"go.loglayer.dev/v2"
"go.loglayer.dev/transports/structured/v2"
)

log := loglayer.New(loglayer.Config{Transport: structured.New(structured.Config{})})
Expand Down Expand Up @@ -61,10 +61,10 @@ log.Panic("...") // calls panic(joined-message) after dispatch; recoverable

Each method takes `...any`, joined with a space.

For `fmt.Sprintf`-style format strings, register the optional [`fmtlog`](https://pkg.go.dev/go.loglayer.dev/plugins/fmtlog) plugin:
For `fmt.Sprintf`-style format strings, register the optional [`fmtlog`](https://pkg.go.dev/go.loglayer.dev/plugins/fmtlog/v2) plugin:

```go
import "go.loglayer.dev/plugins/fmtlog"
import "go.loglayer.dev/plugins/fmtlog/v2"

log.AddPlugin(fmtlog.New())

Expand Down Expand Up @@ -255,7 +255,7 @@ The merged group set is also surfaced to transports via `TransportParams.Groups`
## Plugins

```go
import "go.loglayer.dev/plugins/redact"
import "go.loglayer.dev/plugins/redact/v2"

// Inline single-hook plugin via an adapter constructor
log.AddPlugin(loglayer.NewDataHook("tag", func(p loglayer.BeforeDataOutParams) loglayer.Data {
Expand Down Expand Up @@ -323,7 +323,7 @@ Off by default. Costs ~100 ns / one runtime.Caller per emission when on. The slo
## slog Interop

```go
import "go.loglayer.dev/integrations/sloghandler"
import "go.loglayer.dev/integrations/sloghandler/v2"

// Make every slog.Info(...) flow through your loglayer pipeline (plugins,
// fan-out, groups, level state). slog.With / WithAttrs become persistent
Expand Down
2 changes: 1 addition & 1 deletion docs/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ loglayer.New(loglayer.Config{
Plugins to register at construction time. Equivalent to calling `log.AddPlugin` for each entry after `New`; either form is fine.

```go
import "go.loglayer.dev/plugins/redact"
import "go.loglayer.dev/plugins/redact/v2"

log := loglayer.New(loglayer.Config{
Transport: structured.New(structured.Config{}),
Expand Down
16 changes: 8 additions & 8 deletions docs/src/for-typescript-developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,10 @@ TypeScript's `@loglayer/transport-pino`, `@loglayer/plugin-redaction`, etc. are

| TypeScript | Go |
|----------------------------------|-----------------------------------------------|
| `loglayer` | `go.loglayer.dev` (core + stdlib renderers) |
| `@loglayer/transport-zerolog` | `go.loglayer.dev/transports/zerolog` |
| `@loglayer/transport-datadog` | `go.loglayer.dev/transports/datadog` |
| `@loglayer/integration-elysia` | `go.loglayer.dev/integrations/loghttp` (etc.) |
| `loglayer` | `go.loglayer.dev/v2` (core + stdlib renderers) |
| `@loglayer/transport-zerolog` | `go.loglayer.dev/transports/zerolog/v2` |
| `@loglayer/transport-datadog` | `go.loglayer.dev/transports/datadog/v2` |
| `@loglayer/integration-elysia` | `go.loglayer.dev/integrations/loghttp/v2` (etc.) |

`go get` each module you actually need; the dependency graph stays focused on whatever you imported.

Expand Down Expand Up @@ -149,15 +149,15 @@ The full set: `NewFieldsHook`, `NewMetadataHook`, `NewDataHook`, `NewMessageHook
`plugins/redact` mirrors `@loglayer/plugin-redaction`. It supports key matching, regex value patterns, and json-tag-aware struct walking, all type-preserving:

```go
import "go.loglayer.dev/plugins/redact"
import "go.loglayer.dev/plugins/redact/v2"

log.AddPlugin(redact.New(redact.Config{
Keys: []string{"password", "apiKey"},
Patterns: []*regexp.Regexp{regexp.MustCompile(`^\d{16}$`)},
}))
```

See [Plugins](/plugins/) for the full lifecycle, hook ordering, and nil-return semantics. Third-party plugins can use [`utils/maputil`](https://pkg.go.dev/go.loglayer.dev/utils/maputil) for the same reflection-based deep-clone primitive that the redact plugin uses.
See [Plugins](/plugins/) for the full lifecycle, hook ordering, and nil-return semantics. Third-party plugins can use [`utils/maputil`](https://pkg.go.dev/go.loglayer.dev/v2/utils/maputil) for the same reflection-based deep-clone primitive that the redact plugin uses.

## Groups

Expand Down Expand Up @@ -197,8 +197,8 @@ If any of these are blockers for your use case, open an issue at [github.com/log
// log.withMetadata({ duration: 42 }).withError(err).info('did the thing');

import (
"go.loglayer.dev"
"go.loglayer.dev/transports/structured"
"go.loglayer.dev/v2"
"go.loglayer.dev/transports/structured/v2"
)

log := loglayer.New(loglayer.Config{
Expand Down
18 changes: 9 additions & 9 deletions docs/src/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ description: Install LogLayer, pick a transport, and write your first structured

# Getting Started

LogLayer for Go targets **Go 1.25+** for the main module: `go.loglayer.dev`. Most transports are sub-packages of that module, so you only pull in dependencies for the transports you actually use. Individual transports and plugins call out any stricter requirement on their per-page docs.
LogLayer for Go targets **Go 1.25+** for the main module: `go.loglayer.dev/v2`. Most transports are sub-packages of that module, so you only pull in dependencies for the transports you actually use. Individual transports and plugins call out any stricter requirement on their per-page docs.

## Installation

LogLayer ships as a multi-module repo: the core lives at `go.loglayer.dev`, and every transport and plugin is its own independently-versioned sub-module. You install the core plus only the transports you actually use.
LogLayer ships as a multi-module repo: the core lives at `go.loglayer.dev/v2`, and every transport and plugin is its own independently-versioned sub-module. You install the core plus only the transports you actually use.

```sh
go get go.loglayer.dev
go get go.loglayer.dev/transports/structured
go get go.loglayer.dev/v2
go get go.loglayer.dev/transports/structured/v2
```

## Basic Usage with the Structured Transport
Expand All @@ -26,8 +26,8 @@ package main
import (
"errors"

"go.loglayer.dev"
"go.loglayer.dev/transports/structured"
"go.loglayer.dev/v2"
"go.loglayer.dev/transports/structured/v2"
)

func main() {
Expand Down Expand Up @@ -83,7 +83,7 @@ For stack traces, custom shapes, or other options, see [Error Handling](/logging
If you already have an existing logging stack, LogLayer can wrap it so your call sites use the LogLayer API while emission goes through the underlying logger you've already configured. Here it is for `zerolog`:

```sh
go get go.loglayer.dev/transports/zerolog github.com/rs/zerolog
go get go.loglayer.dev/transports/zerolog/v2 github.com/rs/zerolog
```

```go
Expand All @@ -92,8 +92,8 @@ import (

zlog "github.com/rs/zerolog"

"go.loglayer.dev"
llzero "go.loglayer.dev/transports/zerolog"
"go.loglayer.dev/v2"
llzero "go.loglayer.dev/transports/zerolog/v2"
)

z := zlog.New(os.Stderr).With().Timestamp().Logger()
Expand Down
4 changes: 2 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ package main
import (
"errors"

"go.loglayer.dev"
"go.loglayer.dev/transports/structured"
"go.loglayer.dev/v2"
"go.loglayer.dev/transports/structured/v2"
)

func main() {
Expand Down
8 changes: 4 additions & 4 deletions docs/src/integrations/loghttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description: One-line HTTP middleware that derives a per-request logger and stuf
Mirrors the role that `hlog.NewHandler` plays for zerolog. Works with any `net/http`-compatible router: stdlib, chi, gorilla/mux, gin, echo, etc.

```sh
go get go.loglayer.dev/integrations/loghttp
go get go.loglayer.dev/integrations/loghttp/v2
```

## Basic Usage
Expand All @@ -21,9 +21,9 @@ go get go.loglayer.dev/integrations/loghttp
import (
"net/http"

"go.loglayer.dev"
"go.loglayer.dev/integrations/loghttp"
"go.loglayer.dev/transports/structured"
"go.loglayer.dev/v2"
"go.loglayer.dev/integrations/loghttp/v2"
"go.loglayer.dev/transports/structured/v2"
)

var log = loglayer.New(loglayer.Config{
Expand Down
10 changes: 5 additions & 5 deletions docs/src/integrations/sloghandler.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: "slog.Handler that routes every slog.Info(...) call through your lo
`integrations/sloghandler` is a `log/slog.Handler` backed by a loglayer logger. Once installed, every `slog.Info(...)` call (yours or your dependencies') flows through loglayer's plugin pipeline, multi-transport fan-out, group routing, and level filtering.

```sh
go get go.loglayer.dev/integrations/sloghandler
go get go.loglayer.dev/integrations/sloghandler/v2
```

This is the **slog → loglayer** direction. If you want the opposite (use loglayer's API and emit through a `*slog.Logger` you've already configured), see the [slog Transport](/transports/slog).
Expand All @@ -27,10 +27,10 @@ This is the **slog → loglayer** direction. If you want the opposite (use logla
import (
"log/slog"

"go.loglayer.dev"
"go.loglayer.dev/integrations/sloghandler"
"go.loglayer.dev/plugins/redact"
"go.loglayer.dev/transports/structured"
"go.loglayer.dev/v2"
"go.loglayer.dev/integrations/sloghandler/v2"
"go.loglayer.dev/plugins/redact/v2"
"go.loglayer.dev/transports/structured/v2"
)

log := loglayer.New(loglayer.Config{
Expand Down
2 changes: 1 addition & 1 deletion docs/src/llms.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ If you're not sure, start with `llms-full.txt`. It's the lower-friction option.
## Other ways to feed loglayer to an LLM

- **Source code** at [github.com/loglayer/loglayer-go](https://github.com/loglayer/loglayer-go) is small enough to fit in most coding assistants' context.
- **pkg.go.dev** (`pkg.go.dev/go.loglayer.dev`) renders all GoDoc, including type signatures and doc comments. Useful for fact-checking the model's output.
- **pkg.go.dev** (`pkg.go.dev/go.loglayer.dev/v2`) renders all GoDoc, including type signatures and doc comments. Useful for fact-checking the model's output.
- **This docs site** is itself indexed by most search-augmented assistants. Asking "from the loglayer.dev Go docs, ..." often works without any setup.
2 changes: 1 addition & 1 deletion docs/src/logging-api/basic-logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Drop the result into anything that takes the corresponding type:
import (
"net/http"

"go.loglayer.dev"
"go.loglayer.dev/v2"
)

srv := &http.Server{
Expand Down
8 changes: 4 additions & 4 deletions docs/src/logging-api/groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ Define groups when creating the logger:

```go
import (
"go.loglayer.dev"
"go.loglayer.dev/transports/structured"
"go.loglayer.dev/transports/datadog"
"go.loglayer.dev/transport"
"go.loglayer.dev/v2"
"go.loglayer.dev/transports/structured/v2"
"go.loglayer.dev/transports/datadog/v2"
"go.loglayer.dev/v2/transport"
)

log := loglayer.New(loglayer.Config{
Expand Down
6 changes: 3 additions & 3 deletions docs/src/logging-api/mocking.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ LogLayer ships a primitive for each.
Use this when logs aren't part of what you're testing. It's a drop-in `*loglayer.LogLayer` backed by a discard transport. Every call is accepted but produces no output.

```go
import "go.loglayer.dev"
import "go.loglayer.dev/v2"

func TestSomething(t *testing.T) {
log := loglayer.NewMock()
Expand Down Expand Up @@ -57,8 +57,8 @@ Use this when the test's purpose is to verify *what* was logged. The `transports

```go
import (
"go.loglayer.dev"
lltest "go.loglayer.dev/transports/testing"
"go.loglayer.dev/v2"
lltest "go.loglayer.dev/transports/testing/v2"
)

func TestRequestLogging(t *testing.T) {
Expand Down
10 changes: 5 additions & 5 deletions docs/src/plugins/_partials/plugin-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

| Name | Version | Go Reference | Description |
|------|---------|--------------|-------------|
| [Redact](/plugins/redact) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/redact/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/redact/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/redact.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/redact) | Replace values for a configured set of keys (and optional regex patterns) before metadata or fields reach a transport. Walks structs, maps, and slices via reflection; preserves the runtime type. |
| [Sampling](/plugins/sampling) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/sampling/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/sampling/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/sampling.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/sampling) | Drop a fraction of emissions to keep volume and cost under control. `FixedRate` (per-emission Bernoulli draw), `FixedRatePerLevel` (per-level rate), and `Burst` (rate cap per rolling window). Composes with itself for "1% kept, capped at 100/sec" patterns. |
| [Format Strings](/plugins/fmtlog) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/fmtlog/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/fmtlog/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/fmtlog.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/fmtlog) | Opt the logger into `fmt.Sprintf`-style format strings: `log.Info("user %d", id)` resolves to `"user 1234"` before downstream hooks see it. |
| [Datadog APM Trace Injector](/plugins/datadogtrace) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/datadogtrace/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/datadogtrace/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/datadogtrace.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/datadogtrace) | Inject the active Datadog APM trace and span IDs (`dd.trace_id`, `dd.span_id`) into every log entry that carries a context, enabling Datadog's log/trace correlation. Tracer-agnostic; bring your own `dd-trace-go` (v1 or v2). |
| [OpenTelemetry Trace Injector](/plugins/oteltrace) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/oteltrace/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/oteltrace/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/oteltrace.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/oteltrace) | Inject the active OTel `trace_id` and `span_id` (and optional `trace_flags`) into every log entry that carries a context. Use with non-OTel transports for log/trace correlation; the OTel pipeline does this itself when shipping via `transports/otellog`. |
| [Redact](/plugins/redact) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/redact/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/redact/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/redact/v2.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/redact/v2) | Replace values for a configured set of keys (and optional regex patterns) before metadata or fields reach a transport. Walks structs, maps, and slices via reflection; preserves the runtime type. |
| [Sampling](/plugins/sampling) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/sampling/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/sampling/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/sampling/v2.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/sampling/v2) | Drop a fraction of emissions to keep volume and cost under control. `FixedRate` (per-emission Bernoulli draw), `FixedRatePerLevel` (per-level rate), and `Burst` (rate cap per rolling window). Composes with itself for "1% kept, capped at 100/sec" patterns. |
| [Format Strings](/plugins/fmtlog) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/fmtlog/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/fmtlog/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/fmtlog/v2.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/fmtlog/v2) | Opt the logger into `fmt.Sprintf`-style format strings: `log.Info("user %d", id)` resolves to `"user 1234"` before downstream hooks see it. |
| [Datadog APM Trace Injector](/plugins/datadogtrace) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/datadogtrace/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/datadogtrace/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/datadogtrace/v2.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/datadogtrace/v2) | Inject the active Datadog APM trace and span IDs (`dd.trace_id`, `dd.span_id`) into every log entry that carries a context, enabling Datadog's log/trace correlation. Tracer-agnostic; bring your own `dd-trace-go` (v1 or v2). |
| [OpenTelemetry Trace Injector](/plugins/oteltrace) | [![Version](https://img.shields.io/github/v/tag/loglayer/loglayer-go?filter=plugins/oteltrace/v*&sort=date&label=version&style=flat-square&color=blue)](https://github.com/loglayer/loglayer-go/releases?q=plugins/oteltrace/&expanded=true) | [![Go Reference](https://pkg.go.dev/badge/go.loglayer.dev/plugins/oteltrace/v2.svg)](https://pkg.go.dev/go.loglayer.dev/plugins/oteltrace/v2) | Inject the active OTel `trace_id` and `span_id` (and optional `trace_flags`) into every log entry that carries a context. Use with non-OTel transports for log/trace correlation; the OTel pipeline does this itself when shipping via `transports/otellog`. |

</div>
Loading
Loading