04-observability
Effect-TS 4 observability — structured logging, spans, tracing, annotations, and metrics
- License 许可
- MIT
- 最近更新
- 2026-05-31
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- 04-observability
- license
- MIT
- description
- Effect-TS 4 observability — structured logging, spans, tracing, annotations, and metrics
- compatibility
- opencode
03 SKILL.md 正文
Observability
Structured logging
yield * Effect.log("info message");
yield * Effect.logInfo("user:", id);
yield * Effect.logWarning("slow query:", sql);
yield * Effect.logError("fetch failed:", url);
yield * Effect.logDebug("cache hit:", key);
yield * Effect.logTrace("verbose detail:", payload);
Spans — tracing
Effect.fn("name") automatically creates a span from the name argument.
This is the preferred way — no manual withSpan needed.
// ✅ span created automatically from name
export const processItem = Effect.fn("processItem")(function* (id: string) {
return yield* doWork(id);
});
// Manual span — for one-off wrapping
program.pipe(Effect.withSpan("myOperation"));
// Span with attributes
program.pipe(
Effect.withSpan("myOperation", {
attributes: { userId: id, requestId },
}),
);
Annotating the current span
yield * Effect.annotateCurrentSpan({ userId: id, requestId });
Log annotations — attach context to all logs in scope
// Attach to any effect
program.pipe(
Effect.annotateLogs({ component: "auth", requestId }),
)
// As extra arg in Effect.fn — applies to all logs in the function
export const login = Effect.fn("login")(
function* (input: LoginInput) { ... },
Effect.annotateLogs({ method: "login" }),
)
Effect.fn extra-arg pattern — span + annotations together
export const runEval = Effect.fn("runEval")(
function* (taskId: string) {
yield* Effect.log("running eval");
return yield* evaluate(taskId);
},
Effect.withSpan("runEval"),
Effect.annotateLogs({ component: "evaluator" }),
);
Metrics
import { Metric } from "effect";
const requestCount = Metric.counter("http.requests");
const latency = Metric.histogram("http.latency.ms", {
boundaries: Metric.linearBoundaries({ start: 0, width: 50, count: 20 }),
});
yield * Metric.increment(requestCount);
yield * Metric.record(latency, elapsedMs);
DevTools (browser / development)
import { DevTools } from "effect/unstable/devtools";
const runtime = Atom.runtime(
FetchHttpClient.layer.pipe(
Layer.provideMerge(import.meta.env.VITE_ENABLE_DEVTOOLS === "true" ? DevTools.layer() : Layer.empty),
),
);
04 同仓库更多 Skills
tmux-workflow
Development workflow with tmux — run dev servers, Storybook, and background processes in persistent sessions with live logs, while keeping OpenCode free for chat
04-anti-patterns
React anti-patterns to avoid — manual JSX repetition, useEffect misuse, reference instability, prop drilling, conditional hooks, and common performance traps
03-state-management
React state management patterns — lifting state, colocation, URL state, server state with TanStack Query, local state with useState/useReducer
02-component-composition
React component composition patterns — render props, compound components, list rendering with map, slot patterns, and layout primitives
01-fp-style
React functional programming style — pure components, hooks conventions, Effect Atom integration, and Tailwind patterns
react-animation
React animation with react/motion (Framer Motion) — declarative animations, gestures, layout animations, and performance best practices