Go SDK
Native Go client for Trefur Observe. Batches and ships structured telemetry for agent observability and drift detection.
Install
go get github.com/trefur-ai/trefur-sdks/go/observe-goInit
package main
import (
"os"
observe "github.com/trefur-ai/trefur-sdks/go/observe-go"
)
func main() {
client := observe.Init(observe.Config{
APIKey: os.Getenv("TREFUR_API_KEY"),
AgentName: os.Getenv("TREFUR_AGENT_NAME"),
})
defer client.Shutdown()
// ... your agent code
}Telemetry is buffered and shipped on a periodic flush. A short program can exit before that timer fires, so always defer client.Shutdown() right after Init. The deferred call runs on a normal return and on a panic, so it flushes the first trace on both the happy path and the error path.
Configuration
| Field | Type | Default | Notes |
|---|---|---|---|
APIKey | string | required | trf_obs_* |
Endpoint | string | https://observe.trefur.com | Ingest endpoint override |
Debug | bool | false | Verbose stderr logging |
BatchSize | int | 10 | Buffer size before auto-flush |
FlushInterval | time.Duration | 5s | Periodic flush interval |
AgentName | string | auto-detected | Explicit agent identity |
AgentFramework | string | "go" | Reported in telemetry |
Agent | *AgentIdentity | auto | Full identity struct override |
HTTPClient | *http.Client | 10s timeout default | Custom HTTP client (TLS pinning, proxies, etc.) |
Recording telemetry
now := time.Now().UTC().Format(time.RFC3339)
client.Record(observe.TelemetryPayload{
AgentName: "search-bot",
Framework: "custom",
Status: "completed",
StartedAt: now,
Steps: []observe.StepPayload{
{
StepType: "tool_call",
ToolName: "search",
Status: "completed",
StartedAt: now,
EndedAt: now,
},
},
})
// Flush before process exit (also called by Shutdown).
client.Flush()Automatic instrumentation
For outbound HTTP, the SDK hands you an *http.Client whose transport records each call as a structured step — no per-call wiring. Use it for your agent's outbound requests and every LLM REST call (Anthropic / OpenAI / Gemini) and known SaaS tool call is captured and classified automatically:
client := observe.Init(observe.Config{
APIKey: os.Getenv("TREFUR_API_KEY"),
})
defer client.Shutdown()
// An *http.Client whose transport records every outbound call.
httpClient := observe.InstrumentedHTTPClientWith(client)
resp, err := httpClient.Get("https://api.openai.com/v1/models")Already have your own *http.Client (custom timeouts, proxy, TLS)? Drop the instrumented transport onto it and keep your configuration:
httpClient := &http.Client{
Transport: observe.NewTransportWithClient(nil, client),
}Subprocess capture is explicit by design in Go (there is no safe way to globally intercept process creation). Swap exec.Command for the instrumented form and the subprocess is recorded as a cli_exec step:
out, err := observe.Command("git", "clone", repoURL).Output()The binary name is classified into an enriched tool name (e.g. aws.s3, git.clone, kubernetes.apply) so subprocess activity is attributed to a known tool in your traces.
Privacy guarantees
The privacy boundary is enforced inside the wrapper — you get the trace (that it happened, the endpoint, the tool, the status, the timing) without the wrapper reaching for your payloads or credentials.
- HTTP: the wrapper records the request method, the normalized endpoint (scheme + host + path, query string stripped), and the response status — and classifies the destination. It does not read or record request/response bodies, headers, or URL query strings.
- Subprocess: the wrapper records the binary name, the redacted argument list, the exit code, and the duration. Arguments that look secret-bearing — the value after a sensitive flag (
--password,--token,--api-key, …), the value half of a sensitive--flag=value/KEY=VALUEpair, and standalone tokens matching a known secret prefix (sk-,ghp_,trf_,Bearer …) or a long opaque string — are replaced with[REDACTED]before recording. Subprocess output is never captured — neither stdout nor stderr leaves the process. - Self-traffic is skipped: calls to Trefur's own ingest endpoints are never recorded, so instrumentation can't loop on itself.
OTel emission
The Go SDK also exposes an OTel exporter (otel_emit.go) and a cloud-detection helper (clouddetect.go) that auto-stamps cloud-provider fingerprint fields on every payload.
Environment variables
Canonical list: env-vars reference.
Troubleshooting
| Symptom | Fix |
|---|---|
| Process exits before telemetry flushes. | Always defer client.Shutdown(). The shutdown blocks for the flush interval or until the buffer drains, whichever comes first. |
| Need a custom transport (e.g. behind a corporate proxy). | Pass HTTPClient: &http.Client{...} with the desired transport. |
Source + tests live in trefur-ai/trefur-sdks under go/observe-go. License: Apache 2.0.