Files
greptimedb/tests/cases/standalone/common/system/semantic_graph_trace_v2.sql
T
LFC 16978cf6c2 feat(trace): support Semantic Graph for Trace V2 (follow-up to #9192) (#9278)
* feat(trace): support Semantic Graph for Trace V2

Signed-off-by: luofucong <luofc@foxmail.com>

* fix: remove unused annotation context import

Signed-off-by: luofucong <luofc@foxmail.com>

---------

Signed-off-by: luofucong <luofc@foxmail.com>
2026-09-22 02:39:36 +00:00

166 lines
8.8 KiB
SQL

-- Trace V2 uses the same flattened attribute references as V1.
-- Everything after the root column is one literal key, including dots.
create table graph_trace_v2 (
"timestamp" timestamp(9) time index,
timestamp_end timestamp(9),
duration_nano bigint,
parent_span_id string,
trace_id string,
span_id string,
span_kind string,
span_name string,
span_status_code string,
span_status_message string,
trace_state string,
scope_name string,
scope_version string,
service_name string,
span_attributes json2,
scope_attributes json2,
resource_attributes json2,
span_events json,
span_links json,
primary key (service_name)
) with (
'table_data_model' = 'greptime_trace_v2',
'append_mode' = 'true',
'greptime.semantic.entity.gen_ai.agent.id' = 'span_attributes.gen_ai.agent.id',
'greptime.semantic.entity.gen_ai.agent.scope' = 'scope_attributes.environment',
'greptime.semantic.entity.gen_ai.model.id' = 'span_attributes.gen_ai.request.model',
'greptime.semantic.entity.literal_peer.id' = 'span_attributes.db.namespace',
'greptime.semantic.entity.literal_resource.id' = 'resource_attributes.host.name',
'greptime.semantic.entity.literal_span.id' = 'span_attributes.gen_ai.agent.id',
'greptime.semantic.entity.literal_scope.id' = 'scope_attributes.deployment.region.name'
);
insert into graph_trace_v2
("timestamp", duration_nano, trace_id, span_id, span_kind, span_status_code,
service_name, span_attributes, scope_attributes, resource_attributes)
values
('2026-01-01 00:00:01', 100000000, 'paired', 'client', 'SPAN_KIND_CLIENT', 'STATUS_CODE_UNSET',
'frontend', '{"gen_ai.agent.id":"agent-a","gen_ai.request.model":"model-a","gen_ai":{"agent":{"id":"nested-agent"}}}',
'{"environment":"prod","deployment.region.name":"literal-region","deployment":{"region.name":"nested-region"},"a\"b\\c.d":7}', '{"service.namespace":"shop","service.instance.id":"front-1","host.id":"host-1","host.name":"node-1","host":{"name":"nested-node"},"service":{"namespace":"wrong-namespace"}}'),
('2026-01-01 00:00:02', 200000000, 'virtual', 'client', 'SPAN_KIND_CLIENT', 'STATUS_CODE_ERROR',
'frontend', '{"service.peer.name":"","db.namespace":"orders","db":{"namespace":"wrong-orders"}}', '{}',
'{"service.namespace":"shop","service.instance.id":"front-1","host.id":"host-1","host.name":"node-1"}'),
('2026-01-01 00:00:03', 100, 'missing', 'internal', 'SPAN_KIND_INTERNAL', 'STATUS_CODE_UNSET',
'no-resource', '{"gen_ai.agent.id":null}', '{}', '{}');
-- Agent parent/child references are independent of span kind.
insert into graph_trace_v2
("timestamp", duration_nano, trace_id, span_id, parent_span_id, span_kind,
span_status_code, service_name, span_attributes, scope_attributes, resource_attributes)
values ('2026-01-01 00:00:01', 30000000, 'paired', 'agent-child', 'client',
'SPAN_KIND_INTERNAL', 'STATUS_CODE_UNSET', 'frontend',
'{"gen_ai.agent.id":"agent-b"}', '{"environment":"prod"}', '{"service.namespace":"shop"}');
-- Calls can pair a V2 client with a V1 server. The literal_resource declaration
-- has exactly the same spelling in both models, including its output JSON keys.
create table graph_trace_v1_peer (
"timestamp" timestamp(9) time index,
trace_id string, span_id string, parent_span_id string,
span_kind string, span_status_code string, duration_nano bigint,
service_name string,
"resource_attributes.service.namespace" string,
"resource_attributes.host.name" string,
primary key (service_name)
) with ('table_data_model' = 'greptime_trace_v1', 'append_mode' = 'true',
'greptime.semantic.entity.literal_resource.id' = 'resource_attributes.host.name');
insert into graph_trace_v1_peer values
('2026-01-01 00:00:01', 'paired', 'server', 'client', 'SPAN_KIND_SERVER', 'STATUS_CODE_UNSET', 50000000, 'backend', 'shop', 'node-v1');
select entity_type, entity_id, scope
from greptime_private.semantic_entities
where observed_at >= '2026-01-01 00:00:00' and observed_at < '2026-01-01 00:01:00'
order by entity_type, entity_id;
select src_type, src_id, dst_type, dst_id, rel_type, request_count, error_count
from greptime_private.semantic_relationships
where observed_at >= '2026-01-01 00:00:00' and observed_at < '2026-01-01 00:01:00'
order by rel_type, src_type, src_id, dst_id;
-- Empty components in the V1-compatible comma-separated list remain invalid.
alter table graph_trace_v2 set 'greptime.semantic.entity.invalid.id' = 'resource_attributes.host.id,';
alter table graph_trace_v2 set 'greptime.semantic.entity.invalid.id' = 'resource_attributes.host.id,,service_name';
-- ALTER accepts JSON2 references; a missing key simply yields no entity.
alter table graph_trace_v2 set 'greptime.semantic.entity.custom.id' = 'scope_attributes.missing';
alter table graph_trace_v2 set 'greptime.semantic.entity.host.descriptive' = 'resource_attributes.host.name';
-- Preserve implicit host identity by explicitly declaring it as well.
alter table graph_trace_v2 set 'greptime.semantic.entity.host.id' = 'resource_attributes.host.id';
admin flush_table('graph_trace_v2');
admin flush_table('graph_trace_v1_peer');
-- SQLNESS PROTOCOL MYSQL
select entity_type, entity_id, scope, entity_id_attrs, descriptive
from greptime_private.semantic_entities
where observed_at >= '2026-01-01 00:00:00' and observed_at < '2026-01-01 00:01:00'
order by entity_type, entity_id;
select src_type, src_id, dst_type, dst_id, rel_type, request_count, error_count
from greptime_private.semantic_relationships
where observed_at >= '2026-01-01 00:00:00' and observed_at < '2026-01-01 00:01:00'
order by rel_type, src_type, src_id, dst_id;
-- Quotes, backslashes and dots remain a literal key; numbers render as strings.
alter table graph_trace_v2 set 'greptime.semantic.entity.custom.id' = 'scope_attributes.a"b\c.d';
select entity_type, entity_id
from greptime_private.semantic_entities
where entity_type = 'custom'
and observed_at >= '2026-01-01 00:00:00' and observed_at < '2026-01-01 00:01:00';
-- Path-looking suffixes are literal keys, not nested traversal or array access.
-- These missing keys are valid declarations and produce no entities.
alter table graph_trace_v2 set 'greptime.semantic.entity.literal_missing.id' = 'resource_attributes.host..name';
alter table graph_trace_v2 set 'greptime.semantic.entity.literal_index.id' = 'resource_attributes.host[0]';
-- The root must exist and be one of the three JSON2 attribute columns.
alter table graph_trace_v2 set 'greptime.semantic.entity.invalid.id' = 'span_events.name';
alter table graph_trace_v2 set 'greptime.semantic.entity.invalid.id' = 'resource_attributes.';
alter table graph_trace_v2 set 'greptime.semantic.entity.invalid.id' = 'missing.key';
alter table graph_trace_v2 set 'greptime.semantic.entity.invalid.id' = 'resource_attributes';
create table graph_bad_v2 (
ts timestamp time index, resource_attributes string
) with ('table_data_model' = 'greptime_trace_v2',
'greptime.semantic.entity.host.id' = 'resource_attributes.host.id');
-- Ordinary JSON2 tables do not acquire Trace V2 attribute-reference semantics.
create table graph_not_trace (
ts timestamp time index, resource_attributes json2
) with ('append_mode' = 'true',
'greptime.semantic.entity.host.id' = 'resource_attributes.host.id');
-- Physical convention columns win over conflicting JSON2 keys.
alter table graph_trace_v2 add column "resource_attributes.host.id" string;
alter table graph_trace_v2 add column "resource_attributes.service.namespace" string;
alter table graph_trace_v2 add column "span_attributes.db.namespace" string;
-- Restore the implicit host declaration for the physical-column check.
alter table graph_trace_v2 unset 'greptime.semantic.entity.host.id';
alter table graph_trace_v2 unset 'greptime.semantic.entity.host.descriptive';
insert into graph_trace_v2
("timestamp", duration_nano, trace_id, span_id, span_kind, span_status_code,
service_name, resource_attributes, span_attributes,
"resource_attributes.host.id", "resource_attributes.service.namespace", "span_attributes.db.namespace")
values ('2026-01-01 00:00:04', 100, 'physical', 'physical-client', 'SPAN_KIND_CLIENT', 'STATUS_CODE_UNSET',
'physical-service', '{"host.id":"json-host","service.namespace":"json-namespace"}',
'{"db.namespace":"json-database","db":{"namespace":"nested-database"}}',
'physical-host', 'physical-namespace', 'physical-database');
select entity_type, entity_id
from greptime_private.semantic_entities
where entity_type in ('host', 'service')
and observed_at >= '2026-01-01 00:00:00' and observed_at < '2026-01-01 00:01:00'
order by entity_type, entity_id;
select src_id, dst_id, rel_type
from greptime_private.semantic_relationships
where src_id = 'physical-namespace/physical-service'
and observed_at >= '2026-01-01 00:00:00' and observed_at < '2026-01-01 00:01:00'
order by rel_type, dst_id;
drop table graph_trace_v2;
drop table graph_trace_v1_peer;