원클릭으로
observability
Use when setting up tracing, logging, analytics, or observability events in a pocopine application—both frontend and backend.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when setting up tracing, logging, analytics, or observability events in a pocopine application—both frontend and backend.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when turning a Claude Design (or any mockup/design) into a well-structured pocopine app — choosing app architecture (a store plus layout/leaf components), translating inline styles into Pine Stylekit, wiring icons and resizable regions, and verifying the result.
Use when working with the pocopine Pine icons feature — the `icon!` proc macro for compile-time Rust SVG embedding, or the `<pine-icon>` template primitive with `register_icons!` for tree-shaking-friendly template rendering.
Use when building styles with Pine Stylekit, the Pocopine-native utility-CSS compiler, or working with @theme tokens and CSS generation in Rust/WASM projects
Use when building enter/leave transitions, layout animations, stagger effects, or spring-physics motion in pocopine components
Use when implementing authentication in pocopine apps — JWT verification, credentials, OAuth providers, session management, or guards
Use when defining background jobs, enqueueing work, configuring workers, or troubleshooting job execution in pocopine apps
| name | observability |
| description | Use when setting up tracing, logging, analytics, or observability events in a pocopine application—both frontend and backend. |
Pocopine's observability system unifies browser logging, backend logging, structured tracing, and analytics under a shared event contract using the tracing crate. It spans three crates: pocopine-observe (event schema and privacy labels), pocopine-logging (log formatting and export), and pocopine-analytics (analytics fan-out with redaction).
Event classes and targets:
ObservedEvent::log(name) → pocopine.log target, operational recordsObservedEvent::trace(name) → pocopine.trace target, timing and causalityObservedEvent::metric(name) → pocopine.metric target, measured valuesObservedEvent::analytics(name) → pocopine.analytics target, product eventsField privacy labels:
FieldPrivacy::Public — exported everywhere by defaultFieldPrivacy::Pseudonymous — requires explicit policy; dropped unless opt-inFieldPrivacy::Sensitive — dropped unless trusted sink explicitly allowsEvent context (optional):
service, environment, route, component, trace_id, session_id, user_id_hashBrowser logging setup:
init_console_logging(ConsoleLoggingConfig::debug()) — compact text logs, filters to pocopine.* targetsinit_console_logging(ConsoleLoggingConfig::json()) — structured console objects with level, target, message, fieldsfrontend_observability() — plugin for app! macro; subscribes to framework lifecycle hooksPlugin<FrontendObservability>.emit(event) — emit custom analytics from componentsServer logging setup:
init_server_logging(ServerLoggingConfig::json()) — structured JSON logs to stdoutinit_server_logging(ServerLoggingConfig::compact()) — human-readable development logswith_env_filter("info,pocopine=debug") — override RUST_LOGwith_otlp(OtlpConfig::grpc("http://localhost:4317")) — export traces to OpenTelemetryServer-side observability plugin:
server_observability() — hooks for boot, HTTP requests, server functionsServerObservabilityConfig::new().with_service("api").with_environment("prod").with_http_requests(true), .with_server_functions(true), .with_boot(true) to selectively enable.with_unmatched_paths(true) to include raw paths for 404s (default omits for privacy)Analytics client and sinks:
AnalyticsClient::new().with_sink(sink) — attach one or more redacting sinksanalytics.emit(event) → AnalyticsReport with all_succeeded(), failed countanalytics.flush() — drain buffered events before graceful shutdownJsonLinesAnalyticsSink::stdout() — write \n-delimited JSON to stdout/stderr/fileBoundedAnalyticsSink::new(sink, capacity) — wrap with backpressure, drop counter, metricssink.metrics() → {pending, enqueued, dropped, delivered, failed}Context and tracing targets:
Always use explicit target:
tracing::info!(target: "pocopine.log", "message");
Without target, logs filter to module path and may not reach console.
Browser console logging with plugin:
// examples/observability-frontend/src/lib.rs
#[wasm_bindgen(start)]
pub fn main() {
let observability = pocopine::logging::frontend_observability_with_config(
FrontendObservabilityConfig::default()
.with_service("observability-frontend")
.with_environment("dev"),
);
pocopine::app! {
components: [AppShell, HomePage],
plugins: [observability],
routes: [("/", HomePage)],
};
}
Emit analytics from a component:
// examples/observability-frontend/src/lib.rs (simplified)
#[handlers]
impl HomePage {
pub fn track_feature(&mut self) {
self.plugin::<FrontendObservability>().emit(
ObservedEvent::analytics("feature_used")
.field("feature", "button_click", FieldPrivacy::Public)
.field("count", self.tracked, FieldPrivacy::Public),
);
}
}
Server logging and observability:
// examples/observability-smoke/src/bin/server.rs
#[tokio::main]
async fn main() -> std::io::Result<()> {
init_server_logging(
ServerLoggingConfig::json()
.with_env_filter("info,pocopine=debug")
.with_otlp(OtlpConfig::from_env()),
)?;
let router = Router::new();
Server::new(router)
.plugin(server_observability_with_config(
ServerObservabilityConfig::new()
.with_service("blog-api")
.with_environment("production"),
))
.serve("0.0.0.0:3000")
.await
}
Analytics with redaction and JSON export:
// examples/observability-smoke/src/bin/analytics_exporter.rs
let exporter = BoundedAnalyticsSink::new(JsonLinesAnalyticsSink::stdout(), 16);
let analytics = AnalyticsClient::new().with_sink(exporter);
analytics.emit(
pocopine::analytics::route_view("/report/:id")
.field("surface", "app", FieldPrivacy::Public)
.field("user_hash", hash, FieldPrivacy::Pseudonymous),
);
analytics.flush()?;
Target filtering: Browser console only shows logs with target starting with pocopine by default. Always emit with target: "pocopine.log", "pocopine.trace", etc., or configure without_target_prefix() to see all logs.
Field count limit: Events reserve eight field slots. If you exceed that, observed_field_overflowed = true is set, but the event still records the full count in observed_field_count. Keep framework events coarse; do not ship wide payloads of internal state.
Privacy redaction happens at dispatch time, not emission: ObservedEvent::analytics(...) defaults to FieldPrivacy::Pseudonymous. Call .field(..., FieldPrivacy::Public) explicitly for fields that are safe to export. AnalyticsClient redacts before invoking sinks, so sinks always receive a safe subset.
Exporter failure does not fail the app: Sink panics are caught and reported as delivery failures. If a sink returns an error, AnalyticsClient continues with other sinks. Use BoundedAnalyticsSink for backpressure; it rejects new events when full and exposes drop counters.
Libraries do not install subscribers: Framework crates emit tracing events or ObservedEvents. The final application binary (in main() or #[wasm_bindgen(start)]) installs logging and analytics.
Context is optional: ObservedEvent context fields (service, route, component, etc.) are all Option<String>. The plugin and app are responsible for populating them. Missing fields export as observed_context_has_service = false so exporters can distinguish absence from empty strings.
/crates/pocopine-observe, /crates/pocopine-logging, /crates/pocopine-analytics/examples/observability-smoke (server logging + OTLP), /examples/observability-frontend (browser + analytics)