← Back to blog
Product 4 min read 炬鲸团队

JJHub OBSERVE Unified Observability: Logs, Metrics, and Traces in One Plane

A look at how JJHub OBSERVE folds logs, metrics, and traces into one data plane with SQL-like log search, dimensional alert governance, and native OTLP tracing, so teams switch tools less and diagnose faster.

Ask an on-call engineer what a real incident feels like, and you'll usually hear about the tool switching rather than the debugging. Metrics in one product, logs in another, traces in a third — and the join key is whatever timestamp and trace ID you can copy between tabs. This post walks through how OBSERVE is designed around closing that gap, and what that design means day to day.

1. One platform, three data types

The slowest part of troubleshooting is rarely understanding the fault; it's switching between systems. Metrics sit in the monitoring tool, logs in the log platform, and traces in the APM product, and engineers align the three by hand using timestamps and trace IDs, ending up with a dozen browser tabs open. JJHub OBSERVE folds logs, metrics, and traces into one data plane sharing a single field index and label taxonomy. Click an alert to jump to the matching log lines; see a trace_id in a log line to expand the full call graph. The data stays in place; you just stop switching tabs.

The point of the shared plane isn't convenience alone — it's that the three signals become mutually reinforcing. A metric tells you that error rate climbed; the linked logs tell you which error code is driving it; the trace tells you which upstream call produced it. Reconstructing that chain across three separate products is a manual, lossy process. Inside one platform it is a continuous drill-down path.

2. Log search: SQL-like, not a keyword box

Most log platforms are a keyword box plus a regex field. Once you have many fields, regex becomes unreadable. OBSERVE's log search uses a SQL-like syntax, with structured fields parsed at ingestion and indexed at write time:

level='ERROR' AND service='order-svc' AND trace_id != ''
| stats count() by host, error_code

This single query answers "which node and which error code are failing." At a hundred-gigabyte daily volume, conditional queries return in seconds, while unstructured fields like message keep full-text search — the two coexist rather than being an either-or. Parsing ships with built-in templates for nginx access logs, Java stack traces, and JSON logs, and custom Grok patterns cover the formats the defaults miss.

Two design choices are worth calling out. First, fields are indexed at write time rather than computed at query time, which is exactly why filtering on level, service, and host stays fast at scale. Second, the | stats aggregation runs server-side over the filtered set, so group-and-count work stays in the storage engine instead of shipping raw rows to the browser.

3. Alerting: treat alert fatigue as an engineering problem

The most realistic failure of an alerting system isn't missing incidents; it's that people stop looking. OBSERVE alert rules support dimensional aggregation — one rule fans out into separate alerts per service or per host, so a single flapping link won't flood the screen. You can require N consecutive samples over threshold before triggering to filter transient spikes, and you get silence windows and severity routing: P0 goes to phone/SMS, P2 lands in IM, so nobody is paged repeatedly by the same batch. Alert configurations are versioned, so who changed what and when is on record.

Operationally, this means a rule describes the signal (the error rate of order-svc broken down by host), and the platform handles the fan-out and routing. Teams stop writing a dozen near-identical rules and start tuning one rule per service — which is the difference between a page you trust and a page you mute.

4. Tracing: OTLP only, no private protocols

Tracing products too easily turn into black boxes that support only the vendor's own SDK. OBSERVE natively ingests OTLP; Go, Java, Python, and Node.js services export with the standard OpenTelemetry SDKs and no extra dependencies. The ingestion layer applies head-based and tail-based sampling — head sampling throttles overall volume, tail sampling keeps every span carrying an error — so you control storage cost without discarding the evidence that matters.

All three views share the same trace_id dimension, making the path from trace to log to metric one continuous drill-down rather than three disconnected screenshots. For the on-call engineer, that's the entire difference between a platform and three tools: the question "what happened, and why" gets answered in one place, in order.