> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracelit.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Go [Logs]

> OpenTelemetry for Go services on Tracelit — frameworks, LoggerProvider, and logger bridges.

<Note>
  **Requirements:** Go ≥ 1.21
</Note>

## 1. Environment

```bash theme={null}
OTEL_SERVICE_NAME=my-service
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.tracelit.app
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <WORKSPACE_INGEST_KEY>
```

## 2. Install packages

```bash theme={null}
go get go.opentelemetry.io/otel@latest
go get go.opentelemetry.io/otel/sdk@latest
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp@latest
go get go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp@latest
go get go.opentelemetry.io/otel/log@latest
go get go.opentelemetry.io/otel/sdk/log@latest
go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@latest
```

Create an `otelsetup` package that builds a `TracerProvider` **and** a `LoggerProvider` (OTLP HTTP). Call it once from `main` before serving traffic.

## 3. Framework instrumentation

| Framework | Package                                                                         |
| --------- | ------------------------------------------------------------------------------- |
| Gin       | `go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin`  |
| Echo      | `go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho` |
| Chi       | `go.opentelemetry.io/contrib/instrumentation/github.com/go-chi/chi/otelchi`     |
| net/http  | `otelhttp.NewHandler(mux, "server")`                                            |

## 4. Log library bridges

Traces alone are not enough for the onboarding connection check — bridge your logger.

<Tabs>
  <Tab title="slog">
    ### Install

    ```bash theme={null}
    go get go.opentelemetry.io/contrib/bridges/otelslog
    ```

    ### Wire

    After you create a `LoggerProvider` pointed at Tracelit:

    ```go theme={null}
    import (
      "log/slog"
      "go.opentelemetry.io/contrib/bridges/otelslog"
    )

    slog.SetDefault(slog.New(otelslog.NewHandler("app", otelslog.WithLoggerProvider(lp))))
    ```

    ### Produce signals

    ```go theme={null}
    slog.Info("order listed", "count", 3)
    slog.Error("payment failed", "err", err)
    ```
  </Tab>

  <Tab title="zerolog">
    ### Approach

    zerolog does not ship a first-party OTel bridge in every version. Recommended pattern:

    1. Keep zerolog for local pretty/JSON output
    2. Add a **Hook** that forwards each event to `go.opentelemetry.io/otel/log` using your `LoggerProvider`

    ### Minimal OTel emit (smoke test)

    ```go theme={null}
    logger := lp.Logger("app")
    var rec otelLog.Record
    rec.SetSeverity(otelLog.SeverityInfo)
    rec.SetBody(attribute.StringValue("order listed"))
    logger.Emit(ctx, rec)
    ```

    For production, implement a zerolog Hook that maps levels (`Debug`→DEBUG, `Info`→INFO, `Error`/`Fatal`→ERROR/FATAL) and copies fields as attributes.

    ### Produce signals

    ```go theme={null}
    log.Info().Int("count", 3).Msg("order listed")
    log.Error().Err(err).Msg("payment failed")
    ```
  </Tab>

  <Tab title="zap">
    ### Install

    ```bash theme={null}
    go get go.opentelemetry.io/contrib/bridges/otelzap
    go get go.uber.org/zap
    ```

    ### Wire

    ```go theme={null}
    import (
      "os"
      "go.uber.org/zap"
      "go.uber.org/zap/zapcore"
      "go.opentelemetry.io/contrib/bridges/otelzap"
    )

    core := zapcore.NewTee(
      zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), zapcore.AddSync(os.Stdout), zap.InfoLevel),
      otelzap.NewCore("app", otelzap.WithLoggerProvider(lp)),
    )
    log := zap.New(core)
    ```

    ### Produce signals

    ```go theme={null}
    log.Info("order listed", zap.Int("count", 3))
    log.Error("payment failed", zap.Error(err))
    ```
  </Tab>

  <Tab title="logrus">
    ### Install

    ```bash theme={null}
    go get go.opentelemetry.io/contrib/bridges/otellogrus
    go get github.com/sirupsen/logrus
    ```

    ### Wire

    ```go theme={null}
    import (
      "github.com/sirupsen/logrus"
      "go.opentelemetry.io/contrib/bridges/otellogrus"
    )

    logrus.AddHook(otellogrus.NewHook("app", otellogrus.WithLoggerProvider(lp)))
    ```

    ### Produce signals

    ```go theme={null}
    logrus.WithField("count", 3).Info("order listed")
    logrus.WithError(err).Error("payment failed")
    ```
  </Tab>
</Tabs>

## 5. Verify

Produce **one INFO log** and **one ERROR log**, then use **Check connection** in onboarding (or open Logs in the dashboard). Continue only when both appear.
