Writing traces based ClickHouse queries for building dashboard panels

Traces Schema

Info

The distributed tables in clickhouse have been named by prefixing distributed_ to existing single shard table names. If you want to use clickhouse queries in dashboard or alerts, you should use the distributed table names. Eg, signoz_index_v3 now corresponds to the table of a single shard. To query all the shards, query against distributed_signoz_index_v3.

distributed_signoz_index_v3

This is primary table of Traces which is queried to fetch spans and apply aggregation on spans. It has over 30 different columns which helps in faster filtering on most common attributes following OpenTelemetry Trace Semantic conventions.

(
    `ts_bucket_start` UInt64 CODEC(DoubleDelta, LZ4),
    `resource_fingerprint` String CODEC(ZSTD(1)),
    `timestamp` DateTime64(9) CODEC(DoubleDelta, LZ4),
    `trace_id` FixedString(32) CODEC(ZSTD(1)),
    `span_id` String CODEC(ZSTD(1)),
    `trace_state` String CODEC(ZSTD(1)),
    `parent_span_id` String CODEC(ZSTD(1)),
    `flags` UInt32 CODEC(T64, ZSTD(1)),
    `name` LowCardinality(String) CODEC(ZSTD(1)),
    `kind` Int8 CODEC(T64, ZSTD(1)),
    `kind_string` String CODEC(ZSTD(1)),
    `duration_nano` UInt64 CODEC(T64, ZSTD(1)),
    `status_code` Int16 CODEC(T64, ZSTD(1)),
    `status_message` String CODEC(ZSTD(1)),
    `status_code_string` String CODEC(ZSTD(1)),
    `attributes_string` Map(LowCardinality(String), String) CODEC(ZSTD(1)),
    `attributes_number` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)),
    `attributes_bool` Map(LowCardinality(String), Bool) CODEC(ZSTD(1)),
    `resources_string` Map(LowCardinality(String), String) CODEC(ZSTD(1)),
    `events` Array(String) CODEC(ZSTD(2)),
    `links` String CODEC(ZSTD(1)),
    `response_status_code` LowCardinality(String) CODEC(ZSTD(1)),
    `external_http_url` LowCardinality(String) CODEC(ZSTD(1)),
    `http_url` LowCardinality(String) CODEC(ZSTD(1)),
    `external_http_method` LowCardinality(String) CODEC(ZSTD(1)),
    `http_method` LowCardinality(String) CODEC(ZSTD(1)),
    `http_host` LowCardinality(String) CODEC(ZSTD(1)),
    `db_name` LowCardinality(String) CODEC(ZSTD(1)),
    `db_operation` LowCardinality(String) CODEC(ZSTD(1)),
    `has_error` Bool CODEC(T64, ZSTD(1)),
    `is_remote` LowCardinality(String) CODEC(ZSTD(1)),
    `resource_string_service$$name` LowCardinality(String) DEFAULT resources_string['service.name'] CODEC(ZSTD(1)),
    `attribute_string_http$$route` LowCardinality(String) DEFAULT attributes_string['http.route'] CODEC(ZSTD(1)),
    `attribute_string_messaging$$system` LowCardinality(String) DEFAULT attributes_string['messaging.system'] CODEC(ZSTD(1)),
    `attribute_string_messaging$$operation` LowCardinality(String) DEFAULT attributes_string['messaging.operation'] CODEC(ZSTD(1)),
    `attribute_string_db$$system` LowCardinality(String) DEFAULT attributes_string['db.system'] CODEC(ZSTD(1)),
    `attribute_string_rpc$$system` LowCardinality(String) DEFAULT attributes_string['rpc.system'] CODEC(ZSTD(1)),
    `attribute_string_rpc$$service` LowCardinality(String) DEFAULT attributes_string['rpc.service'] CODEC(ZSTD(1)),
    `attribute_string_rpc$$method` LowCardinality(String) DEFAULT attributes_string['rpc.method'] CODEC(ZSTD(1)),
    `attribute_string_peer$$service` LowCardinality(String) DEFAULT attributes_string['peer.service'] CODEC(ZSTD(1)),
    INDEX idx_trace_id trace_id TYPE tokenbf_v1(10000, 5, 0) GRANULARITY 1,
    INDEX idx_span_id span_id TYPE tokenbf_v1(5000, 5, 0) GRANULARITY 1,
    INDEX idx_duration duration_nano TYPE minmax GRANULARITY 1,
    INDEX idx_name name TYPE ngrambf_v1(4, 5000, 2, 0) GRANULARITY 1,
    INDEX idx_kind kind TYPE minmax GRANULARITY 4,
    INDEX idx_http_route `attribute_string_http$$route` TYPE bloom_filter GRANULARITY 4,
    INDEX idx_http_url http_url TYPE bloom_filter GRANULARITY 4,
    INDEX idx_http_host http_host TYPE bloom_filter GRANULARITY 4,
    INDEX idx_http_method http_method TYPE bloom_filter GRANULARITY 4,
    INDEX idx_timestamp timestamp TYPE minmax GRANULARITY 1,
    INDEX idx_rpc_method `attribute_string_rpc$$method` TYPE bloom_filter GRANULARITY 4,
    INDEX idx_response_statusCode response_status_code TYPE set(0) GRANULARITY 1,
    INDEX idx_status_code_string status_code_string TYPE set(3) GRANULARITY 4,
    INDEX idx_kind_string kind_string TYPE set(5) GRANULARITY 4,
    INDEX attributes_string_idx_key mapKeys(attributes_string) TYPE tokenbf_v1(1024, 2, 0) GRANULARITY 1,
    INDEX attributes_string_idx_val mapValues(attributes_string) TYPE ngrambf_v1(4, 5000, 2, 0) GRANULARITY 1,
    INDEX attributes_number_idx_key mapKeys(attributes_number) TYPE tokenbf_v1(1024, 2, 0) GRANULARITY 1,
    INDEX attributes_number_idx_val mapValues(attributes_number) TYPE bloom_filter GRANULARITY 1,
    INDEX attributes_bool_idx_key mapKeys(attributes_bool) TYPE tokenbf_v1(1024, 2, 0) GRANULARITY 1,
    INDEX resources_string_idx_key mapKeys(resources_string) TYPE tokenbf_v1(1024, 2, 0) GRANULARITY 1,
    INDEX resources_string_idx_val mapValues(resources_string) TYPE ngrambf_v1(4, 5000, 2, 0) GRANULARITY 1
)
ORDER BY (ts_bucket_start, resource_fingerprint, has_error, name, timestamp)

Columns in the distributed_signoz_index_v3 table

NAMEDESCRIPTION
ts_bucket_startStart timestamp of the bucket
resource_fingerprintFingerprint of the resource, generated by combining all the resource attributes
timestampTime when the span generated at the source
trace_idTrace ID. W3C Trace Context
span_idSpan ID
trace_stateTrace state of the span
parent_span_idParent Span ID
flagsFlags of the span
nameName of the span
kindKind of the span. OpenTelemetry Span Kind
kind_stringString representation of the kind of the span
duration_nanoDuration of the span in nanoseconds
status_codeStatus code of the span. OpenTelemetry Status Code
status_messageStatus message of the span
status_code_stringString representation of the status code of the span
attributes_stringMap of all string tags/attributes of the span
attributes_numberMap of all number tags/attributes of the span
attributes_boolMap of all bool tags/attributes of the span
resources_stringMap of all resource tags/attributes of the span
eventsEvents of the span. It is an array of stringified json of span events
linksLinks of the span. It is a stringified json of span links
response_status_codeResponse status code of the span. Derived from http.status_code, rpc.grpc.status_code and rpc.jsonrpc.error_code attribute of a span
external_http_urlExternal HTTP url of the span
http_urlHTTP url of the span
external_http_methodExternal HTTP method of the span
http_methodHTTP method of the span
http_hostHTTP host of the span
db_nameDatabase name of the span. Derived from db.name attribute of a span
db_operationDatabase operation of the span. Derived from db.operation attribute of a span
has_errorWhether the span has error or not
is_remoteWhether the span is remote or not
resource_string_service$$nameName of the service. Derived from resources_string['service.name'] attribute of a span
attribute_string_http$$routeHTTP route of the span. Derived from attributes_string['http.route'] attribute of a span
attribute_string_messaging$$systemMessaging system of the span. Derived from attributes_string['messaging.system'] attribute of a span
attribute_string_messaging$$operationMessaging operation of the span. Derived from attributes_string['messaging.operation'] attribute of a span
attribute_string_db$$systemDatabase system of the span. Derived from attributes_string['db.system'] attribute of a span
attribute_string_rpc$$systemRPC system of the span. Derived from attributes_string['rpc.system'] attribute of a span
attribute_string_rpc$$serviceRPC service of the span. Derived from attributes_string['rpc.service'] attribute of a span
attribute_string_rpc$$methodRPC method of the span. Derived from attributes_string['rpc.method'] attribute of a span
attribute_string_peer$$servicePeer service of the span. Derived from attributes_string['peer.service'] attribute of a span

Timestamp Bucketing

In the new schema for traces i.e distributed_signoz_index_v3, we have a new column ts_bucket_start which is used to store the start timestamp of the bucket. This is used for faster filtering on timestamp attribute.

How to use this column in the queries? If your timestamp query is timestamp BETWEEN {{.start_datetime}} AND {{.end_datetime}} then you will have to add ts_bucket_start BETWEEN {{.start_timestamp}} - 1800 AND {{.end_timestamp}}

We have added -1800, as bucketing is done in 30 minute intervals.

distributed_signoz_error_index_v2

This table stores error events derived from spans

(
    `timestamp` DateTime64(9) CODEC(DoubleDelta, LZ4),
    `errorID` FixedString(32) CODEC(ZSTD(1)),
    `groupID` FixedString(32) CODEC(ZSTD(1)),
    `traceID` FixedString(32) CODEC(ZSTD(1)),
    `spanID` String CODEC(ZSTD(1)),
    `serviceName` LowCardinality(String) CODEC(ZSTD(1)),
    `exceptionType` LowCardinality(String) CODEC(ZSTD(1)),
    `exceptionMessage` String CODEC(ZSTD(1)),
    `exceptionStacktrace` String CODEC(ZSTD(1)),
    `exceptionEscaped` Bool CODEC(T64, ZSTD(1)),
    `resourceTagsMap` Map(LowCardinality(String), String) CODEC(ZSTD(1)),
    INDEX idx_error_id errorID TYPE bloom_filter GRANULARITY 4,
    INDEX idx_resourceTagsMapKeys mapKeys(resourceTagsMap) TYPE bloom_filter(0.01) GRANULARITY 64,
    INDEX idx_resourceTagsMapValues mapValues(resourceTagsMap) TYPE bloom_filter(0.01) GRANULARITY 64
)

Columns in the distributed_signoz_error_index_v2 table

NAMEDESCRIPTION
timestampTime when the span generated at the source
errorIDError ID. W3C Trace Context
groupIDGroup ID of the error
traceIDTrace ID. W3C Trace Context
spanIDSpan ID
serviceNameName of the service. Derived from service.name attribute of a span
exceptionTypeException type of the error. Derived from exception.type attribute of a span
exceptionMessageException message of the error. Derived from exception.message attribute of a span
exceptionStacktraceException stacktrace of the error. Derived from exception.stacktrace attribute of a span
exceptionEscapedWhether the exception is escaped or not. Derived from exception.escaped attribute of a span
resourceTagsMapMap of all resource tags/attributes of the span

distributed_top_level_operations

This table stores top operations and service name.

(
    `name` LowCardinality(String) CODEC(ZSTD(1)),
    `serviceName` LowCardinality(String) CODEC(ZSTD(1))
)

Columns in the distributed_top_level_operations table

NAMEDESCRIPTION
nameName of the span
serviceNameName of the service

distributed_span_attributes_keys

This table stores all the attributes keys of the span.

(
    `tagKey` LowCardinality(String) CODEC(ZSTD(1)),
    `tagType` Enum8('tag' = 1, 'resource' = 2) CODEC(ZSTD(1)),
    `dataType` Enum8('string' = 1, 'bool' = 2, 'float64' = 3) CODEC(ZSTD(1)),
    `isColumn` Bool CODEC(ZSTD(1))
)

Columns in the distributed_span_attributes_keys table

NAMEDESCRIPTION
tagKeyName of the attribute
tagTypeType of the attribute. It can be tag or resource
dataTypeData type of the attribute. It can be string, bool or float64
isColumnWhether the attribute is a column or not

distributed_span_attributes

This table stores all the attributes of the span.

(
    `timestamp` DateTime CODEC(DoubleDelta, ZSTD(1)),
    `tagKey` LowCardinality(String) CODEC(ZSTD(1)),
    `tagType` Enum8('tag' = 1, 'resource' = 2) CODEC(ZSTD(1)),
    `dataType` Enum8('string' = 1, 'bool' = 2, 'float64' = 3) CODEC(ZSTD(1)),
    `stringTagValue` String CODEC(ZSTD(1)),
    `float64TagValue` Nullable(Float64) CODEC(ZSTD(1)),
    `isColumn` Bool CODEC(ZSTD(1))
)

Columns in the distributed_span_attributes table

NAMEDESCRIPTION
timestampTime when the span generated at the source
tagKeyName of the attribute
tagTypeType of the attribute. It can be tag or resource
dataTypeData type of the attribute. It can be string, bool or float64
stringTagValueString value of the attribute
float64TagValueFloat64 value of the attribute
isColumnWhether the attribute is a column or not

Writing Clickhouse Queries for Dashboard Panels

Timeseries

This panel is used when you want to view your aggregated data in a timeseries.

Examples

Plotting a chart on 100ms interval

Plot a chart of 1 minute showing count of spans in 100ms interval of service frontend with duration > 50ms

SELECT fromUnixTimestamp64Milli(intDiv( toUnixTimestamp64Milli ( timestamp ), 100) * 100) AS interval, 
toFloat64(count()) AS count 
FROM (
 SELECT timestamp 
 FROM signoz_traces.distributed_signoz_index_v3
 WHERE resource_string_service$$name='frontend' 
 AND duration_nano>=50*exp10(6) 
 AND timestamp BETWEEN {{.start_datetime}} AND {{.end_datetime}}
 AND ts_bucket_start BETWEEN {{.start_timestamp}} - 1800 AND {{.end_timestamp}})
 GROUP BY interval ORDER BY interval ASC;

Value

For the value type panel, the overall query will be similar to timeseries, just that you will have to get the absolute value at the end. You can reduce your end result to either average, latest, sum, min, or max.

Examples

Average duration of spans where method = 'POST' , service_name = 'sample-service'
SELECT 
    avg(value) as value, 
    any(ts) as ts FROM (
        SELECT 
            toStartOfInterval((timestamp), INTERVAL 1 MINUTE) AS ts, 
            toFloat64(count()) AS value 
        FROM 
            signoz_traces.distributed_signoz_index_v3
        WHERE 
            timestamp BETWEEN {{.start_datetime}} AND {{.end_datetime}} AND
            ts_bucket_start BETWEEN {{.start_timestamp}} - 1800 AND {{.end_timestamp}} AND
            http_method = 'POST' AND 
            resource_string_service$$name = 'sample-service'
        GROUP BY ts 
        ORDER BY ts ASC
    )

Table

This is used when you want to view the timeseries data in a tabular format.

The query is similar to timeseries query but instead of using time interval we use just use now() as ts in select.

Examples

GroupBy a tag/attribute in distributed tracing data
SELECT now() as ts, 
attributes_string['example_string_attribute'] AS attribute_name, 
toFloat64(avg(duration_nano)) AS value 
FROM signoz_traces.distributed_signoz_index_v3  
WHERE timestamp BETWEEN {{.start_datetime}} AND {{.end_datetime}}
AND ts_bucket_start BETWEEN {{.start_timestamp}} - 1800 AND {{.end_timestamp}}
GROUP BY (attribute_name, ts) order by (attribute_name, ts) ASC;

Was this page helpful?