mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-10-03 10:35:35 +00:00
* 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>
166 lines
8.8 KiB
SQL
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;
|