frontend/instance/otlp/
trace_semconv.rs1use api::v1::ColumnDataType;
16use opentelemetry_semantic_conventions::{attribute, resource};
17
18pub(super) fn trace_semconv_fixed_type(column_name: &str) -> Option<ColumnDataType> {
28 if let Some(resource_attribute) = column_name.strip_prefix("resource_attributes.") {
29 return match resource_attribute {
30 resource::SERVICE_NAME
34 | resource::SERVICE_INSTANCE_ID
35 | resource::SERVICE_NAMESPACE
36 | resource::SERVICE_VERSION => Some(ColumnDataType::String),
37
38 resource::TELEMETRY_SDK_LANGUAGE
42 | resource::TELEMETRY_SDK_NAME
43 | resource::TELEMETRY_SDK_VERSION => Some(ColumnDataType::String),
44
45 resource::CONTAINER_ID => Some(ColumnDataType::String),
48
49 resource::USER_AGENT_ORIGINAL => Some(ColumnDataType::String),
52
53 resource::K8S_CLUSTER_NAME
56 | resource::K8S_CLUSTER_UID
57 | resource::K8S_CONTAINER_NAME
58 | resource::K8S_CRONJOB_NAME
59 | resource::K8S_CRONJOB_UID
60 | resource::K8S_DAEMONSET_NAME
61 | resource::K8S_DAEMONSET_UID
62 | resource::K8S_DEPLOYMENT_NAME
63 | resource::K8S_DEPLOYMENT_UID
64 | resource::K8S_JOB_NAME
65 | resource::K8S_JOB_UID
66 | resource::K8S_NAMESPACE_NAME
67 | resource::K8S_NODE_NAME
68 | resource::K8S_NODE_UID
69 | resource::K8S_POD_NAME
70 | resource::K8S_POD_UID
71 | resource::K8S_REPLICASET_NAME
72 | resource::K8S_REPLICASET_UID
73 | resource::K8S_STATEFULSET_NAME
74 | resource::K8S_STATEFULSET_UID
75 | "k8s.pod.hostname"
78 | "k8s.pod.ip"
79 | "k8s.pod.start_time" => Some(ColumnDataType::String),
80 resource::K8S_CONTAINER_RESTART_COUNT => Some(ColumnDataType::Int64),
81
82 _ => None,
83 };
84 }
85
86 if let Some(span_attribute) = column_name.strip_prefix("span_attributes.") {
87 return match span_attribute {
88 attribute::CLIENT_ADDRESS
91 | attribute::SERVER_ADDRESS
92 | attribute::NETWORK_LOCAL_ADDRESS
93 | attribute::NETWORK_PEER_ADDRESS
94 | attribute::NETWORK_PROTOCOL_NAME
95 | attribute::NETWORK_PROTOCOL_VERSION
96 | attribute::NETWORK_TRANSPORT
97 | attribute::NETWORK_TYPE => Some(ColumnDataType::String),
98 attribute::CLIENT_PORT
99 | attribute::SERVER_PORT
100 | attribute::NETWORK_LOCAL_PORT
101 | attribute::NETWORK_PEER_PORT => Some(ColumnDataType::Int64),
102
103 attribute::HTTP_REQUEST_METHOD
107 | attribute::HTTP_REQUEST_METHOD_ORIGINAL
108 | attribute::HTTP_ROUTE
109 | attribute::URL_FULL
110 | attribute::URL_PATH
111 | attribute::URL_QUERY
112 | attribute::URL_SCHEME
113 | attribute::USER_AGENT_ORIGINAL => Some(ColumnDataType::String),
114 attribute::HTTP_REQUEST_RESEND_COUNT | attribute::HTTP_RESPONSE_STATUS_CODE => {
115 Some(ColumnDataType::Int64)
116 }
117
118 attribute::RPC_METHOD
122 | attribute::RPC_SYSTEM
123 | "rpc.system.name"
126 | "rpc.method_original"
127 | "rpc.response.status_code" => Some(ColumnDataType::String),
128
129 attribute::DB_COLLECTION_NAME
133 | attribute::DB_NAMESPACE
134 | attribute::DB_OPERATION_NAME
135 | attribute::DB_QUERY_SUMMARY
136 | attribute::DB_QUERY_TEXT
137 | attribute::DB_RESPONSE_STATUS_CODE
138 | attribute::DB_STORED_PROCEDURE_NAME
139 | attribute::DB_SYSTEM_NAME => Some(ColumnDataType::String),
140 attribute::DB_OPERATION_BATCH_SIZE => Some(ColumnDataType::Int64),
141
142 attribute::ERROR_TYPE => Some(ColumnDataType::String),
145
146 _ => None,
147 };
148 }
149
150 None
151}
152
153#[cfg(test)]
154mod tests {
155 use api::v1::ColumnDataType;
156 use opentelemetry_semantic_conventions::{attribute, resource};
157
158 use super::trace_semconv_fixed_type;
159
160 fn resource_column(key: &str) -> String {
161 format!("resource_attributes.{key}")
162 }
163
164 fn span_column(key: &str) -> String {
165 format!("span_attributes.{key}")
166 }
167
168 #[test]
169 fn test_trace_semconv_fixed_type_includes_stable_service_key() {
170 assert_eq!(
171 trace_semconv_fixed_type(&resource_column(resource::SERVICE_NAME)),
172 Some(ColumnDataType::String)
173 );
174 assert_eq!(
175 trace_semconv_fixed_type(&resource_column(resource::SERVICE_VERSION)),
176 Some(ColumnDataType::String)
177 );
178 assert_eq!(
179 trace_semconv_fixed_type(&resource_column(resource::SERVICE_INSTANCE_ID)),
180 Some(ColumnDataType::String)
181 );
182 assert_eq!(
183 trace_semconv_fixed_type(&resource_column(resource::SERVICE_NAMESPACE)),
184 Some(ColumnDataType::String)
185 );
186 }
187
188 #[test]
189 fn test_trace_semconv_fixed_type_includes_http_server_and_error_keys() {
190 assert_eq!(
191 trace_semconv_fixed_type(&span_column(attribute::HTTP_RESPONSE_STATUS_CODE)),
192 Some(ColumnDataType::Int64)
193 );
194 assert_eq!(
195 trace_semconv_fixed_type(&span_column(attribute::SERVER_PORT)),
196 Some(ColumnDataType::Int64)
197 );
198 assert_eq!(
199 trace_semconv_fixed_type(&span_column(attribute::ERROR_TYPE)),
200 Some(ColumnDataType::String)
201 );
202 assert_eq!(
203 trace_semconv_fixed_type(&span_column(attribute::CLIENT_ADDRESS)),
204 Some(ColumnDataType::String)
205 );
206 assert_eq!(
207 trace_semconv_fixed_type(&span_column(attribute::CLIENT_PORT)),
208 Some(ColumnDataType::Int64)
209 );
210 assert_eq!(
211 trace_semconv_fixed_type(&span_column(attribute::URL_FULL)),
212 Some(ColumnDataType::String)
213 );
214 assert_eq!(
215 trace_semconv_fixed_type(&span_column(attribute::URL_PATH)),
216 Some(ColumnDataType::String)
217 );
218 assert_eq!(
219 trace_semconv_fixed_type(&span_column(attribute::URL_QUERY)),
220 Some(ColumnDataType::String)
221 );
222 assert_eq!(
223 trace_semconv_fixed_type(&span_column(attribute::URL_SCHEME)),
224 Some(ColumnDataType::String)
225 );
226 assert_eq!(
227 trace_semconv_fixed_type(&span_column(attribute::USER_AGENT_ORIGINAL)),
228 Some(ColumnDataType::String)
229 );
230 }
231
232 #[test]
233 fn test_trace_semconv_fixed_type_includes_rc_rpc_key() {
234 assert_eq!(
235 trace_semconv_fixed_type(&span_column(attribute::RPC_SYSTEM)),
236 Some(ColumnDataType::String)
237 );
238 assert_eq!(
239 trace_semconv_fixed_type("span_attributes.rpc.system.name"),
240 Some(ColumnDataType::String)
241 );
242 assert_eq!(
243 trace_semconv_fixed_type(&span_column("rpc.response.status_code")),
244 Some(ColumnDataType::String)
245 );
246 }
247
248 #[test]
249 fn test_trace_semconv_fixed_type_includes_db_and_network_keys() {
250 assert_eq!(
251 trace_semconv_fixed_type(&span_column(attribute::DB_SYSTEM_NAME)),
252 Some(ColumnDataType::String)
253 );
254 assert_eq!(
255 trace_semconv_fixed_type(&span_column(attribute::DB_OPERATION_BATCH_SIZE)),
256 Some(ColumnDataType::Int64)
257 );
258 assert_eq!(
259 trace_semconv_fixed_type(&span_column(attribute::NETWORK_PEER_PORT)),
260 Some(ColumnDataType::Int64)
261 );
262 }
263
264 #[test]
265 fn test_trace_semconv_fixed_type_includes_resource_semconv_keys() {
266 assert_eq!(
267 trace_semconv_fixed_type(&resource_column(resource::CONTAINER_ID)),
268 Some(ColumnDataType::String)
269 );
270 assert_eq!(
271 trace_semconv_fixed_type(&resource_column(resource::K8S_CONTAINER_RESTART_COUNT)),
272 Some(ColumnDataType::Int64)
273 );
274 assert_eq!(
275 trace_semconv_fixed_type(&resource_column(resource::TELEMETRY_SDK_LANGUAGE)),
276 Some(ColumnDataType::String)
277 );
278 assert_eq!(
279 trace_semconv_fixed_type(&resource_column(resource::TELEMETRY_SDK_NAME)),
280 Some(ColumnDataType::String)
281 );
282 assert_eq!(
283 trace_semconv_fixed_type(&resource_column(resource::TELEMETRY_SDK_VERSION)),
284 Some(ColumnDataType::String)
285 );
286 }
287
288 #[test]
289 fn test_trace_semconv_fixed_type_excludes_development_keys() {
290 assert_eq!(
291 trace_semconv_fixed_type(&span_column("messaging.system")),
292 None
293 );
294 assert_eq!(
295 trace_semconv_fixed_type(&span_column("rpc.request.metadata.x-request-id")),
296 None
297 );
298 assert_eq!(
299 trace_semconv_fixed_type(&resource_column("k8s.pod.label.app")),
300 None
301 );
302 }
303
304 #[test]
305 fn test_trace_semconv_fixed_type_unknown_key() {
306 assert_eq!(trace_semconv_fixed_type(&span_column("custom.attr")), None);
307 }
308}