Examples
These examples demonstrate how to integrate TelemetryLane into common web frameworks. Each example instruments a service with distributed tracing, structured logging, and request metrics.
Go net/http
Instrument a standard Go HTTP server with trace propagation and request metrics.
package main
import (
"context"
"encoding/json"
"log"
"net/http"
"time"
"github.com/telemetrylane/agent"
)
var a *agent.Agent
func main() {
var err error
a, err = agent.Init(agent.Config{
ServiceName: "user-api",
Exporter: "otlp",
})
if err != nil {
log.Fatal(err)
}
defer a.Shutdown(context.Background())
mux := http.NewServeMux()
mux.HandleFunc("/api/users", handleUsers)
mux.HandleFunc("/api/health", handleHealth)
// Wrap with telemetry middleware
handler := telemetryMiddleware(mux)
log.Println("listening on :8080")
http.ListenAndServe(":8080", handler)
}
func telemetryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ctx, span := a.Trace(r.Context(), r.Method+" "+r.URL.Path)
defer span.End()
a.Log(ctx, agent.Info, "request started",
"method", r.Method,
"path", r.URL.Path,
)
next.ServeHTTP(w, r.WithContext(ctx))
duration := time.Since(start).Seconds()
a.Metric("http_request_duration_seconds", duration,
agent.Tag("method", r.Method),
agent.Tag("path", r.URL.Path),
)
a.Metric("http_requests_total", 1,
agent.Tag("method", r.Method),
agent.Tag("path", r.URL.Path),
)
})
}
func handleUsers(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]any{
"users": []string{"alice", "bob"},
})
}
func handleHealth(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]string{
"status": "ok",
})
}
Rust Actix-web
Add telemetry collection to an Actix-web service using middleware.
use actix_web::{web, App, HttpServer, HttpRequest, HttpResponse, middleware};
use telemetrylane::{Agent, Config, Level};
use std::sync::Arc;
use std::time::Instant;
struct AppState {
agent: Arc<Agent>,
}
async fn get_users(data: web::Data<AppState>, req: HttpRequest) -> HttpResponse {
let _span = data.agent.trace("get_users");
data.agent.log(Level::Info, "fetching user list");
HttpResponse::Ok().json(serde_json::json!({
"users": ["alice", "bob", "charlie"]
}))
}
async fn health() -> HttpResponse {
HttpResponse::Ok().json(serde_json::json!({"status": "ok"}))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let agent = Agent::init(Config {
service_name: "user-api".into(),
exporter: "otlp".into(),
..Config::default()
}).expect("failed to initialize agent");
let agent = Arc::new(agent);
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(AppState {
agent: agent.clone(),
}))
.route("/api/users", web::get().to(get_users))
.route("/api/health", web::get().to(health))
})
.bind("0.0.0.0:8080")?
.run()
.await
}
Python FastAPI
Instrument a FastAPI application with automatic trace propagation and request metrics.
import time
from fastapi import FastAPI, Request
import telemetrylane
app = FastAPI()
tl = telemetrylane.init(
service_name="user-api",
exporter="otlp",
otlp={"endpoint": "http://localhost:4317"},
)
@app.middleware("http")
async def telemetry_middleware(request: Request, call_next):
start = time.monotonic()
ctx, span = tl.trace(
f"{request.method} {request.url.path}"
)
tl.log(ctx, "info", "request started",
method=request.method,
path=request.url.path,
)
response = await call_next(request)
duration = time.monotonic() - start
tl.metric("http_request_duration_seconds", duration,
method=request.method,
path=request.url.path,
status=str(response.status_code),
)
tl.metric("http_requests_total", 1,
method=request.method,
path=request.url.path,
status=str(response.status_code),
)
span.end()
return response
@app.get("/api/users")
async def get_users():
return {"users": ["alice", "bob", "charlie"]}
@app.get("/api/health")
async def health():
return {"status": "ok"}