# OpenTelemetry

Packrat accepts data from any OpenTelemetry SDK. You install the SDK for your language, then point
its exporter at Packrat with a few environment variables.

If your app already exports OpenTelemetry to another vendor, you can keep that vendor and add
Packrat beside it. See [If you already export OpenTelemetry](#if-you-already-export-opentelemetry).

## Before you begin

1. [Sign up for Packrat](https://packrat.sh/start). It's free.
2. Copy your ingest key from the setup page. It starts with `packrat_ingest_`.
3. Install the Packrat CLI and sign in, so you can check what Packrat receives:

   ```sh
   curl -fsSL https://packrat.sh/cli | sh
   packrat login
   ```

## Set up your app

Choose your framework. Each tab has every step for that framework.

#### 1. Install the packages

Add the SDK, the OTLP/HTTP exporter and the `net/http` instrumentation:

```sh
go get go.opentelemetry.io/otel \
  go.opentelemetry.io/otel/sdk \
  go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp \
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
```

#### 2. Start the tracer

The Go SDK doesn't instrument your app automatically, so start the tracer and wrap your handler:

```go
// main.go
package main

import (
	"context"
	"log"
	"net/http"

	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

func main() {
	ctx := context.Background()

	// Reads the endpoint, headers and service name from the environment variables in the next step.
	exporter, err := otlptracehttp.New(ctx)
	if err != nil {
		log.Fatal(err)
	}

	provider := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
	defer provider.Shutdown(ctx)
	otel.SetTracerProvider(provider)

	mux := http.NewServeMux()
	// mux.HandleFunc(...)

	log.Fatal(http.ListenAndServe(":8080", otelhttp.NewHandler(mux, "server")))
}
```

#### 3. Point the exporter at Packrat

Set these environment variables where your app runs. Replace `<your ingest key>`, and set
`OTEL_SERVICE_NAME` to your app's name:

```sh
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.packrat.sh
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_HEADERS=Authorization=<your ingest key>
OTEL_SERVICE_NAME=shop
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production
```

#### 4. Run your app

```sh
go run .
```

## What the variables do

These variables work the same way in every language:

| Variable                      | Value                               | What it does                                                                                                       |
| ----------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `https://ingest.packrat.sh`         | Where the SDK sends data. It adds `/v1/traces`, `/v1/logs` and `/v1/metrics` itself.                              |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `http/protobuf`                     | Packrat accepts OTLP over HTTP as protobuf. It doesn't accept gRPC or JSON.                                        |
| `OTEL_EXPORTER_OTLP_HEADERS`  | `Authorization=<your ingest key>`   | Your ingest key. `Bearer <key>` also works if you write the space as `%20`, because the value is URL-encoded.     |
| `OTEL_SERVICE_NAME`           | `<your app name>`                   | Your app's name in Packrat.                                                                                        |
| `OTEL_RESOURCE_ATTRIBUTES`    | `deployment.environment=production` | Your app's environment in Packrat.                                                                                 |

Packrat keeps each service and environment as a separate app, such as `shop/production`, so you can compare environments.

## Verify

Load a page in your app, then check what Packrat receives:

Run `packrat status` with your app's name, as `<service>/<environment>`:

```sh
packrat status --app shop/production
```

The output lists each signal (exceptions, traces, logs, metrics and replays), the sources that send
it, when each source last sent, and whether Packrat keeps it. A signal with no source hasn't arrived
yet. To see the names your apps report under, run `packrat apps`.

## If you already export OpenTelemetry

Keep your current exporter and its environment variables. Then add a second OTLP/HTTP exporter to
your OpenTelemetry setup that sends to Packrat:

- Traces: `https://ingest.packrat.sh/v1/traces`
- Logs: `https://ingest.packrat.sh/v1/logs`
- Metrics: `https://ingest.packrat.sh/v1/metrics`

Send your ingest key in the `Authorization` header. Both vendors receive every span, and nothing
changes for the other vendor.

---

## Agent instructions

This page is part of the Packrat documentation, published as plain markdown for coding agents: add `.md` to any docs address, or read the index at https://packrat.sh/docs/llms.txt. This page: https://packrat.sh/docs/opentelemetry.md.

Before wiring Packrat into an app, ask the developer for the URL of their setup page at https://packrat.sh/orgs, and read it with `packrat open <URL>`. It has the steps and the org's ingest key.
