Skip to content

Data model

Fixter stores three signals (logs, spans, metrics), built for fast time-scoped search and aggregation. Everything you send over OTLP is normalized into these shapes, and everything you query reads them. All access is scoped to your workspace.

FieldNotes
timestampnanosecond precision
log_idserver-generated ULID, a stable identity for permalinks and lookups
servicefrom service.name, the primary grouping dimension
levelupper-cased, but not normalized to a fixed set. See the note below
messagethe log body, indexed for token and substring search
trace_id / span_id / parent_span_idcorrelation to traces, when present
source_instance_idwhich instance of the service emitted the record
resourceresource attributes (host, deployment, …), queryable as resource.<key>
payloadlog attributes, queryable directly by attribute name

Your own attributes are first-class: whatever keys your instrumentation emits become queryable fields by name, no schema registration needed (see dynamic attributes).

A note on level, because it affects the queries you write. When your SDK sends a severity text, Fixter stores that text upper-cased, exactly as sent. Only when severity text is absent does it derive a level from the OTLP severity number, and then you get one of TRACE, DEBUG, INFO, WARN, ERROR, or FATAL. So level holds whatever your logging library calls things: CRITICAL, SEVERE, PANIC, ERR, WARNING and others all occur in practice. Filtering on level = 'ERROR' alone can therefore miss real errors. Prefer a set: level IN ('ERROR', 'FATAL', 'CRITICAL', 'PANIC'), matched to what your services actually emit.

Where to see logs: the Logs page (filter bar, live tail, SQL mode), the logs, get_log, and get_log_neighbors MCP tools, or SELECT ... FROM logs in QuerySQL.

FieldNotes
timestampwhen the span started
duration_mshow long it took (fractional milliseconds)
trace_id / span_id / parent_span_idthe trace identity triple
servicethe emitting service
namethe operation (an endpoint, a query, a job step)
kindSERVER, CLIENT, PRODUCER, CONSUMER, INTERNAL, or UNSPECIFIED
status_codeUNSET, OK, or ERROR, with status_message for detail
source_instance_idwhich instance emitted the span
resource / payloadresource and span attributes, queryable by name
end_customerthe customer_id span attribute, lifted to a field so you can slice by your own tenant

Span events and links are stored on the span (exception events land there) but are not queryable fields in QuerySQL. Read them through the trace view or the get_trace MCP tool.

Fixter continuously maintains rollups on top of spans, so service-level RED metrics (request rate, error rate, latency percentiles) answer fast without scanning raw data.

Where to see spans: any log with a trace opens its full trace view in the app (/traces/<trace-id>), and the spans, get_trace, and aggregate_spans MCP tools or SELECT ... FROM spans in QuerySQL query them directly.

FieldNotes
timestampsample time
metric_namethe metric’s name
servicethe emitting service
source_instance_idwhich instance emitted the sample
valuethe scalar value, for gauges and counters
attributesmetric attributes, queryable by name

Metrics are stored with the full OTLP model behind these fields: the metric type (GAUGE, SUM, HISTOGRAM, EXPONENTIAL_HISTOGRAM, SUMMARY), delta and cumulative temporality, histogram buckets, summary quantiles, count/sum/min/max, and exemplars that link a sample back to the trace that produced it.

Those are not queryable columns in QuerySQL, which exposes the five fields above plus your own attributes. Reach the rest through the Metrics page or the list_metrics and metrics MCP tools. A query like WHERE type = 'HISTOGRAM' will not compile.

Where to see metrics: the Metrics page in the app, the list_metrics and metrics MCP tools, or SELECT ... FROM metrics in QuerySQL.

Retention means how far back your data stays accessible for query. It is two years across all three signals. Nothing expires sooner, and you do not manage or tune it.

When point-and-click runs out, QuerySQL (Fixter’s read-only SQL dialect) queries logs, spans, and metrics directly, with monitoring-flavored functions (latency percentiles, time bucketing, full-text matching) on top of familiar SQL. It is the same language the Logs page’s SQL mode, the run_sql MCP tool, and alert rule conditions all speak.