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

# Go

> Send errors and logs from Go applications to Squasher.

## Recommended: OpenTelemetry SDK

Use the official Go OTel SDK to send traces and error spans to Squasher.

### 1. Install

```bash theme={null}
go get go.opentelemetry.io/otel \
  go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp \
  go.opentelemetry.io/otel/sdk/trace
```

### 2. Configure

```go theme={null}
package main

import (
	"context"
	"log"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
)

func initTracer() func() {
	exporter, err := otlptracehttp.New(
		context.Background(),
		otlptracehttp.WithEndpoint("ingest.squasher.ai"),
		otlptracehttp.WithHeaders(map[string]string{
			"x-squasher-key": "sq_pk_your_api_key",
		}),
	)
	if err != nil {
		log.Fatalf("failed to create exporter: %v", err)
	}

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
		sdktrace.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceName("my-go-service"),
			semconv.DeploymentEnvironment("production"),
		)),
	)
	otel.SetTracerProvider(tp)

	return func() { tp.Shutdown(context.Background()) }
}
```

### 3. Use

```go theme={null}
func main() {
	shutdown := initTracer()
	defer shutdown()

	tracer := otel.Tracer("my-app")
	ctx, span := tracer.Start(context.Background(), "process-order")
	defer span.End()

	if err := processOrder(ctx); err != nil {
		span.RecordError(err) // Squasher captures this as an error event
		span.SetStatus(codes.Error, err.Error())
	}
}
```

## Alternative: Direct HTTP API

Send errors directly without OpenTelemetry:

```go theme={null}
package squasher

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"runtime"
	"time"
)

type Event struct {
	Message     string            `json:"message"`
	Type        string            `json:"type,omitempty"`
	Level       string            `json:"level"`
	Stack       string            `json:"stack,omitempty"`
	Environment string            `json:"environment,omitempty"`
	Release     string            `json:"release,omitempty"`
	Tags        map[string]string `json:"tags,omitempty"`
	Timestamp   string            `json:"timestamp,omitempty"`
}

var (
	ProjectID = "YOUR_PROJECT_ID"
	APIKey    = "sq_pk_your_api_key"
	Endpoint  = "https://ingest.squasher.ai"
)

func CaptureError(err error, tags map[string]string) {
	buf := make([]byte, 4096)
	n := runtime.Stack(buf, false)

	event := Event{
		Message:     err.Error(),
		Type:        fmt.Sprintf("%T", err),
		Level:       "error",
		Stack:       string(buf[:n]),
		Environment: "production",
		Tags:        tags,
		Timestamp:   time.Now().UTC().Format(time.RFC3339),
	}

	body, _ := json.Marshal(event)
	req, _ := http.NewRequest("POST",
		fmt.Sprintf("%s/v1/ingest/%s", Endpoint, ProjectID),
		bytes.NewReader(body))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("x-squasher-key", APIKey)

	go http.DefaultClient.Do(req)
}

func Log(level, message string, tags map[string]string) {
	event := Event{
		Message:   message,
		Level:     level,
		Tags:      tags,
		Timestamp: time.Now().UTC().Format(time.RFC3339),
	}

	body, _ := json.Marshal(event)
	req, _ := http.NewRequest("POST",
		fmt.Sprintf("%s/v1/ingest/%s", Endpoint, ProjectID),
		bytes.NewReader(body))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("x-squasher-key", APIKey)

	go http.DefaultClient.Do(req)
}
```

### Usage

```go theme={null}
func main() {
	// Capture errors
	if err := doWork(); err != nil {
		squasher.CaptureError(err, map[string]string{"job": "data-sync"})
	}

// Send structured logs
squasher.Log("info", "Job completed", map[string]string{
	"duration_ms": "1234",
	"records":     "500",
})
}
```

## First-party SDK

If the service already uses `log/slog`, use the [Go SDK](/sdks/go) for a smaller logging-handler integration.

## Agent handoff

```text theme={null}
For Go, prefer the Squasher Go SDK when slog logging is enough and OpenTelemetry when the service already emits traces. Keep SQUASHER_API_KEY and SQUASHER_PROJECT_ID in env, call shutdown/flush paths, and verify with one error event.
```
