Skip to content
This repository was archived by the owner on Jul 11, 2025. It is now read-only.

Commit ff3b3b8

Browse files
authored
Add OTel semantic DB span attributes (#12)
1 parent 119e8d2 commit ff3b3b8

File tree

2 files changed

+401
-0
lines changed

2 files changed

+401
-0
lines changed
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift Distributed Tracing project
6+
// authors
7+
// Licensed under Apache License v2.0
8+
//
9+
// See LICENSE.txt for license information
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import Tracing
16+
17+
extension SpanAttributes {
18+
/// Semantic conventions for database client calls.
19+
///
20+
/// OpenTelemetry Spec: [Semantic conventions for database client calls](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md)
21+
public var db: DatabaseAttributes {
22+
get {
23+
.init(attributes: self)
24+
}
25+
set {
26+
self = newValue.attributes
27+
}
28+
}
29+
}
30+
31+
/// Semantic conventions for database client calls.
32+
///
33+
/// OpenTelemetry Spec: [Semantic conventions for database client calls](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md)
34+
@dynamicMemberLookup
35+
public struct DatabaseAttributes: SpanAttributeNamespace {
36+
public var attributes: SpanAttributes
37+
38+
public init(attributes: SpanAttributes) {
39+
self.attributes = attributes
40+
}
41+
42+
// MARK: - General
43+
44+
public struct NestedSpanAttributes: NestedSpanAttributesProtocol {
45+
public init() {}
46+
47+
// MARK: - Connection-level attributes
48+
49+
/// An identifier for the database management system (DBMS) product being used, e.g. `postgresql`.
50+
///
51+
/// - OpenTelemetry Spec: [Notes and well-known identifiers for db.system](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#notes-and-well-known-identifiers-for-dbsystem)
52+
/// - OpenTelemetry Spec: [Connection-level attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#connection-level-attributes).
53+
public var system: Key<String> { "db.system" }
54+
55+
/// The connection string used to connect to the database, e.g. `Server=(localdb)\v11.0;Integrated Security=true;`.
56+
///
57+
/// OpenTelemetry Spec: [Connection-level attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#connection-level-attributes).
58+
///
59+
/// - Warning: It is recommended to remove embedded credentials.
60+
public var connectionString: Key<String> { "db.connection_string" }
61+
62+
/// Username for accessing the database, e.g. `readonly_user`.
63+
///
64+
/// OpenTelemetry Spec: [Connection-level attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#connection-level-attributes).
65+
public var user: Key<String> { "db.user" }
66+
67+
// MARK: - Call-level attributes
68+
69+
/// The name of the database being accessed. For commands that switch the database,
70+
/// this should be set to the target database (even if the command fails).
71+
///
72+
/// In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for
73+
/// database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name).
74+
///
75+
/// - In `Cassandra`, the value SHOULD be set to the keyspace name.
76+
/// - In `HBase`, the value SHOULD be set to the HBase namespace.
77+
///
78+
/// OpenTelemetry Spec: [Call-level attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes).
79+
public var name: Key<String> { "db.name" }
80+
81+
/// The database statement being executed, e.g. `SELECT * FROM wuser_table`.
82+
///
83+
/// The value may be sanitized to exclude sensitive information.
84+
/// This attribute is required if applicable and not explicitly disabled via instrumentation configuration.
85+
///
86+
/// For `Redis`, the value provided SHOULD correspond to the syntax of the Redis CLI.
87+
/// If, for example, the [HMSET command](https://redis.io/commands/hmset) is invoked, "HMSET myhash field1 'Hello' field2 'World'"
88+
/// would be a suitable value.
89+
///
90+
/// OpenTelemetry Spec: [Call-level attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes).
91+
public var statement: Key<String> { "db.statement" }
92+
93+
/// The name of the operation being executed, e.g. the
94+
/// [`MongoDB` command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as
95+
/// `findAndModify`, or the SQL keyword.
96+
///
97+
/// When setting this to an SQL keyword, it is not recommended to attempt
98+
/// any client-side parsing of ``DatabaseAttributes/NestedSpanAttributes/statement`` just to get this property,
99+
/// but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation,
100+
/// or performs more than one operation, this value may be omitted.
101+
///
102+
/// In `CouchDB`, the value should be set to the HTTP method + the target REST route according to the API reference documentation.
103+
/// For example, when retrieving a document, db.operation would be set to (literally, i.e., without replacing the placeholders with concrete values):
104+
/// [`GET /{db}/{docid}`](http://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid).
105+
///
106+
/// OpenTelemetry Spec: [Call-level attributes](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes).
107+
public var operation: Key<String> { "db.operation" }
108+
}
109+
110+
// MARK: - MSSQL
111+
112+
/// Semantic conventions for Microsoft SQL Server clients.
113+
///
114+
/// OpenTelemetry Spec: [Connection-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#connection-level-attributes-for-specific-technologies)
115+
public var mssql: MSSQLAttributes {
116+
get {
117+
.init(attributes: self.attributes)
118+
}
119+
set {
120+
self.attributes = newValue.attributes
121+
}
122+
}
123+
124+
/// Semantic conventions for Microsoft SQL Server clients.
125+
///
126+
/// OpenTelemetry Spec: [Connection-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#connection-level-attributes-for-specific-technologies)
127+
public struct MSSQLAttributes: SpanAttributeNamespace {
128+
public var attributes: SpanAttributes
129+
130+
public init(attributes: SpanAttributes) {
131+
self.attributes = attributes
132+
}
133+
134+
public struct NestedSpanAttributes: NestedSpanAttributesProtocol {
135+
public init() {}
136+
137+
/// The Microsoft SQL Server instance name connecting to, e.g. `MSSQLSERVER`.
138+
///
139+
/// This name is used to determine the port of a named instance.
140+
///
141+
/// - OpenTelemetry Spec: [Connection-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#connection-level-attributes-for-specific-technologies)
142+
/// - Microsoft SQL Server: [Building the connection URL](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15)
143+
public var instanceName: Key<String> { "db.mssql.instance_name" }
144+
}
145+
}
146+
147+
// MARK: - Redis
148+
149+
/// Semantic conventions for Redis clients.
150+
///
151+
/// OpenTelemetry Spec: [Call-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes-for-specific-technologies)
152+
public var redis: RedisAttributes {
153+
get {
154+
.init(attributes: self.attributes)
155+
}
156+
set {
157+
self.attributes = newValue.attributes
158+
}
159+
}
160+
161+
/// Semantic conventions for Redis clients.
162+
///
163+
/// OpenTelemetry Spec: [Call-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes-for-specific-technologies)
164+
public struct RedisAttributes: SpanAttributeNamespace {
165+
public var attributes: SpanAttributes
166+
167+
public init(attributes: SpanAttributes) {
168+
self.attributes = attributes
169+
}
170+
171+
public struct NestedSpanAttributes: NestedSpanAttributesProtocol {
172+
public init() {}
173+
174+
/// The index of the database being accessed as used in the `SELECT` command.
175+
/// To be used instead of the generic ``DatabaseAttributes/NestedSpanAttributes/name`` attribute.
176+
///
177+
/// The index is required if it's anything other than the default database (`0`).
178+
public var databaseIndex: Key<Int> { "db.redis.database_index" }
179+
}
180+
}
181+
182+
// MARK: - MongoDB
183+
184+
/// Semantic conventions for MongoDB clients.
185+
///
186+
/// OpenTelemetry Spec: [Call-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes-for-specific-technologies)
187+
public var mongoDB: MongoDBAttributes {
188+
get {
189+
.init(attributes: self.attributes)
190+
}
191+
set {
192+
self.attributes = newValue.attributes
193+
}
194+
}
195+
196+
/// Semantic conventions for MongoDB clients.
197+
///
198+
/// OpenTelemetry Spec: [Call-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes-for-specific-technologies)
199+
public struct MongoDBAttributes: SpanAttributeNamespace {
200+
public var attributes: SpanAttributes
201+
202+
public init(attributes: SpanAttributes) {
203+
self.attributes = attributes
204+
}
205+
206+
public struct NestedSpanAttributes: NestedSpanAttributesProtocol {
207+
public init() {}
208+
209+
/// The collection being accessed within the database stated in the ``DatabaseAttributes/NestedSpanAttributes/name`` attribute,
210+
/// e.g. `customers`.
211+
public var collection: Key<String> { "db.mongodb.collection" }
212+
}
213+
}
214+
215+
// MARK: - SQL
216+
217+
/// Semantic conventions for SQL clients.
218+
///
219+
/// OpenTelemetry Spec: [Call-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes-for-specific-technologies)
220+
public var sql: SQLAttributes {
221+
get {
222+
.init(attributes: self.attributes)
223+
}
224+
set {
225+
self.attributes = newValue.attributes
226+
}
227+
}
228+
229+
/// Semantic conventions for SQL clients.
230+
///
231+
/// OpenTelemetry Spec: [Call-level attributes for specific technologies](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#call-level-attributes-for-specific-technologies)
232+
public struct SQLAttributes: SpanAttributeNamespace {
233+
public var attributes: SpanAttributes
234+
235+
public init(attributes: SpanAttributes) {
236+
self.attributes = attributes
237+
}
238+
239+
public struct NestedSpanAttributes: NestedSpanAttributesProtocol {
240+
public init() {}
241+
242+
/// The name of the primary table that the operation is acting upon, including the database name (if applicable), e.g. `public.users`.
243+
///
244+
/// It is not recommended to attempt any client-side parsing of ``DatabaseAttributes/NestedSpanAttributes/statement``
245+
/// just to get this property, but it should be set if it is provided by the library being instrumented.
246+
/// If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.
247+
public var table: Key<String> { "db.sql.table" }
248+
}
249+
}
250+
251+
// MARK: - Cassandra
252+
253+
/// Semantic conventions for Cassandra clients.
254+
///
255+
/// OpenTelemetry Spec: [Cassandra](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#cassandra)
256+
public var cassandra: CassandraAttributes {
257+
get {
258+
.init(attributes: self.attributes)
259+
}
260+
set {
261+
self.attributes = newValue.attributes
262+
}
263+
}
264+
265+
/// Semantic conventions for Cassandra clients.
266+
///
267+
/// OpenTelemetry Spec: [Cassandra](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/database.md#cassandra)
268+
public struct CassandraAttributes: SpanAttributeNamespace {
269+
public var attributes: SpanAttributes
270+
271+
public init(attributes: SpanAttributes) {
272+
self.attributes = attributes
273+
}
274+
275+
public struct NestedSpanAttributes: NestedSpanAttributesProtocol {
276+
public init() {}
277+
278+
/// The fetch size used for paging, i.e. how many rows will be returned at once, e.g. `5000`.
279+
public var pageSize: Key<Int> { "db.cassandra.page_size" }
280+
281+
/// The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html).
282+
/// E.g. `all`.
283+
public var consistencyLevel: Key<String> { "db.cassandra.consistency_level" }
284+
285+
/// The name of the primary table that the operation is acting upon, including the keyspace name (if applicable).
286+
/// This mirrors the ``DatabaseAttributes/SQLAttributes/NestedSpanAttributes/table`` attribute but references `cassandra`
287+
/// rather than `sql`.
288+
///
289+
/// It is not recommended to attempt any client-side parsing of ``DatabaseAttributes/NestedSpanAttributes/statement``
290+
/// just to get this property, but it should be set if it is provided by the library being instrumented.
291+
/// If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.
292+
public var table: Key<String> { "db.cassandra.table" }
293+
294+
/// Whether or not the query is idempotent.
295+
public var idempotence: Key<Bool> { "db.cassandra.idempotence" }
296+
297+
/// The number of times a query was speculatively executed. Not set or 0 if the query was not executed speculatively.
298+
public var speculativeExecutionCount: Key<Int> { "db.cassandra.speculative_execution_count" }
299+
300+
/// The ID of the coordinating node for a query.
301+
public var coordinatorID: Key<String> { "db.cassandra.coordinator.id" }
302+
303+
/// The data center of the coordinating node for a query. E.g. `us-west-2`.
304+
public var coordinatorDataCenter: Key<String> { "db.cassandra.coordinator.dc" }
305+
}
306+
}
307+
}

0 commit comments

Comments
 (0)