observability — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited observability (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Part of Agent Skills™ by googleadsagent.ai™
Observability implements structured logging, distributed tracing, and error monitoring for Cloudflare Workers and edge applications. The agent instruments code with contextual log entries, trace spans, error boundaries, and alerting rules that provide full visibility into production behavior without sacrificing performance.
Workers present unique observability challenges. There are no persistent processes to attach profilers to, no filesystem for log files, and no APM agent to inject. Observability must be built into the application layer through structured log events shipped to external collectors, request-scoped trace contexts, and explicit error capture with stack traces and request metadata.
This skill covers three pillars: Logging (structured JSON events with correlation IDs), Tracing (request-scoped spans with timing and metadata), and Monitoring (error rate tracking, latency percentiles, and alerting thresholds). Together, they answer the three questions of production debugging: what happened, how long did it take, and how often does it fail.
graph TD
A[Incoming Request] --> B[Generate Trace ID]
B --> C[Start Root Span]
C --> D[Execute Handler]
D --> E[Child Spans for Subrequests]
E --> F{Error?}
F -->|Yes| G[Capture Error + Context]
F -->|No| H[Record Success Metrics]
G --> I[Structured Log: ERROR]
H --> J[Structured Log: INFO]
I --> K[Ship to Collector via waitUntil]
J --> K
K --> L[External: Datadog / Grafana / Sentry]
C --> M[End Root Span + Record Latency]
M --> KEvery request receives a trace ID that propagates through all subrequests and log entries. Spans measure duration of individual operations. Logs and spans are batched and shipped asynchronously via waitUntil() to avoid adding latency to the response.
interface LogEntry {
timestamp: string;
level: "debug" | "info" | "warn" | "error";
traceId: string;
spanId: string;
message: string;
data?: Record<string, unknown>;
error?: { name: string; message: string; stack?: string };
duration_ms?: number;
}
class RequestTracer {
private traceId: string;
private spans: LogEntry[] = [];
private startTime: number;
constructor(request: Request) {
this.traceId = request.headers.get("x-trace-id") ?? crypto.randomUUID();
this.startTime = performance.now();
}
span<T>(name: string, fn: () => Promise<T>): Promise<T> {
const spanId = crypto.randomUUID().slice(0, 8);
const start = performance.now();
return fn().then(
result => {
this.log("info", name, { duration_ms: performance.now() - start }, spanId);
return result;
},
error => {
this.log("error", name, {
duration_ms: performance.now() - start,
error: { name: error.name, message: error.message, stack: error.stack },
}, spanId);
throw error;
}
);
}
log(level: LogEntry["level"], message: string, data?: Record<string, unknown>, spanId?: string): void {
this.spans.push({
timestamp: new Date().toISOString(),
level,
traceId: this.traceId,
spanId: spanId ?? "root",
message,
...data,
});
}
async flush(env: { LOG_COLLECTOR: Fetcher }): Promise<void> {
const rootDuration = performance.now() - this.startTime;
this.log("info", "request_complete", { duration_ms: rootDuration });
await env.LOG_COLLECTOR.fetch("https://collector/ingest", {
method: "POST",
body: JSON.stringify(this.spans),
headers: { "Content-Type": "application/json" },
});
}
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const tracer = new RequestTracer(request);
try {
const data = await tracer.span("fetch_data", () => fetchData(env));
const html = await tracer.span("render", () => render(data));
return new Response(html, { status: 200 });
} catch (error) {
tracer.log("error", "unhandled_error", {
error: { name: (error as Error).name, message: (error as Error).message },
url: request.url,
method: request.method,
});
return new Response("Internal Error", { status: 500 });
} finally {
ctx.waitUntil(tracer.flush(env));
}
},
} satisfies ExportedHandler<Env>;waitUntil() to avoid adding latency to responsesconsole.log in productionx-trace-id header| Platform | Support | Notes |
|---|---|---|
| Cursor | Full | Instrumentation code generation |
| VS Code | Full | Log viewer integration |
| Windsurf | Full | Observability patterns |
| Claude Code | Full | Worker instrumentation |
| Cline | Full | Logging + tracing setup |
| aider | Partial | Code-level instrumentation |
observability structured-logging distributed-tracing error-monitoring cloudflare-workers alerting latency trace-id
© 2026 googleadsagent.ai™ | Agent Skills™ | MIT License
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.