Skip to content

Commit ae5d45d

Browse files
slashmoktoso
andauthored
Add semantic span attributes (#103)
Co-authored-by: Konrad `ktoso` Malawski <[email protected]> Co-authored-by: Konrad `ktoso` Malawski <[email protected]>
1 parent fc6d007 commit ae5d45d

File tree

10 files changed

+576
-131
lines changed

10 files changed

+576
-131
lines changed

Package.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,28 @@ let package = Package(
7474
.product(name: "NIO", package: "swift-nio"),
7575
.product(name: "NIOHTTP1", package: "swift-nio"),
7676
"Instrumentation",
77-
]),
77+
]
78+
),
7879
.testTarget(
7980
name: "NIOInstrumentationTests",
8081
dependencies: [
8182
"NIOInstrumentation",
8283
]
8384
),
8485

86+
.target(
87+
name: "OpenTelemetryInstrumentationSupport",
88+
dependencies: [
89+
.target(name: "TracingInstrumentation")
90+
]
91+
),
92+
.testTarget(
93+
name: "OpenTelemetryInstrumentationSupportTests",
94+
dependencies: [
95+
"OpenTelemetryInstrumentationSupport"
96+
]
97+
),
98+
8599
// ==== --------------------------------------------------------------------------------------------------------
86100
// MARK: Performance / Benchmarks
87101

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
import TracingInstrumentation
15+
16+
extension SpanAttributes {
17+
/// Semantic end-user attributes.
18+
public var endUser: EndUserAttributes {
19+
get {
20+
.init(attributes: self)
21+
}
22+
set {
23+
self = newValue.attributes
24+
}
25+
}
26+
}
27+
28+
/// End-user-related semantic conventions as defined in the OpenTelemetry spec.
29+
@dynamicMemberLookup
30+
public struct EndUserAttributes: SpanAttributeNamespace {
31+
public var attributes: SpanAttributes
32+
33+
public init(attributes: SpanAttributes) {
34+
self.attributes = attributes
35+
}
36+
37+
public struct NestedAttributes: NestedSpanAttributesProtocol {
38+
public init() {}
39+
40+
/// Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system.
41+
public var id: SpanAttributeKey<String> { "enduser.id" }
42+
43+
/// Actual/assumed role the client is making the request under extracted from token or application security context.
44+
public var role: SpanAttributeKey<String> { "enduser.role" }
45+
46+
/// Scopes or granted authorities the client currently possesses extracted from token or application security context.
47+
/// The value would come from the scope associated with an OAuth 2.0 Access Token or an attribute value in a SAML 2.0 Assertion.
48+
public var scope: SpanAttributeKey<String> { "enduser.scope" }
49+
}
50+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
import TracingInstrumentation
15+
16+
extension SpanAttributes {
17+
/// Semantic conventions for HTTP spans.
18+
public var http: HTTPAttributes {
19+
get {
20+
.init(attributes: self)
21+
}
22+
set {
23+
self = newValue.attributes
24+
}
25+
}
26+
}
27+
28+
/// Semantic conventions for HTTP spans as defined in the OpenTelemetry spec.
29+
@dynamicMemberLookup
30+
public struct HTTPAttributes: SpanAttributeNamespace {
31+
public var attributes: SpanAttributes
32+
33+
public init(attributes: SpanAttributes) {
34+
self.attributes = attributes
35+
}
36+
37+
public struct NestedAttributes: NestedSpanAttributesProtocol {
38+
public init() {}
39+
40+
/// HTTP request method. E.g. "GET".
41+
public var method: SpanAttributeKey<String> { "http.method" }
42+
43+
/// Full HTTP request URL in the form scheme://host[:port]/path?query[#fragment].
44+
/// Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless.
45+
public var url: SpanAttributeKey<String> { "http.url" }
46+
47+
/// The full request target as passed in a HTTP request line or equivalent, e.g. "/path/12314/?q=ddds#123".
48+
public var target: SpanAttributeKey<String> { "http.target" }
49+
50+
/// The value of the HTTP host header. When the header is empty or not present, this attribute should be the same.
51+
public var host: SpanAttributeKey<String> { "http.host" }
52+
53+
/// The URI scheme identifying the used protocol: "http" or "https"
54+
public var scheme: SpanAttributeKey<String> { "http.scheme" }
55+
56+
/// HTTP response status code. E.g. 200.
57+
public var statusCode: SpanAttributeKey<Int> { "http.status_code" }
58+
59+
/// HTTP reason phrase. E.g. "OK".
60+
public var statusText: SpanAttributeKey<String> { "http.status_text" }
61+
62+
/// Kind of HTTP protocol used: "1.0", "1.1", "2", "SPDY" or "QUIC".
63+
public var flavor: SpanAttributeKey<String> { "http.flavor" }
64+
65+
/// Value of the HTTP User-Agent header sent by the client.
66+
public var userAgent: SpanAttributeKey<String> { "http.user_agent" }
67+
68+
/// The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often,
69+
/// but not always, present as the Content-Length header. For requests using transport encoding, this should be the
70+
/// compressed size.
71+
public var requestContentLength: SpanAttributeKey<Int> { "http.request_content_length" }
72+
73+
/// The size of the uncompressed request payload body after transport decoding. Not set if transport encoding not used.
74+
public var requestContentLengthUncompressed: SpanAttributeKey<Int> {
75+
"http.request_content_length_uncompressed"
76+
}
77+
78+
/// The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and
79+
/// is often, but not always, present as the Content-Length header. For requests using transport encoding, this
80+
/// should be the compressed size.
81+
public var responseContentLength: SpanAttributeKey<Int> { "http.response_content_length" }
82+
83+
/// The size of the uncompressed response payload body after transport decoding. Not set if transport encoding not used.
84+
public var responseContentLengthUncompressed: SpanAttributeKey<Int> {
85+
"http.response_content_length_uncompressed"
86+
}
87+
88+
/// The primary server name of the matched virtual host. This should be obtained via configuration.
89+
/// If no such configuration can be obtained, this attribute MUST NOT be set (`net.hostName` should be used instead).
90+
public var serverName: SpanAttributeKey<String> { "http.server_name" }
91+
92+
/// The matched route (path template). E.g. "/users/:userID?".
93+
public var serverRoute: SpanAttributeKey<String> { "http.route" }
94+
95+
/// The IP address of the original client behind all proxies, if known (e.g. from X-Forwarded-For).
96+
/// Note that this is not necessarily the same as `net.peerIP`, which would identify the network-level peer,
97+
/// which may be a proxy.
98+
public var serverClientIP: SpanAttributeKey<String> { "http.client_ip" }
99+
}
100+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
import TracingInstrumentation
15+
16+
extension SpanAttributes {
17+
/// Semantic network attributes.
18+
public var net: NetAttributes {
19+
get {
20+
.init(attributes: self)
21+
}
22+
set {
23+
self = newValue.attributes
24+
}
25+
}
26+
}
27+
28+
/// Network-related semantic conventions as defined in the OpenTelemetry spec.
29+
@dynamicMemberLookup
30+
public struct NetAttributes: SpanAttributeNamespace {
31+
public var attributes: SpanAttributes
32+
33+
public init(attributes: SpanAttributes) {
34+
self.attributes = attributes
35+
}
36+
37+
public struct NestedAttributes: NestedSpanAttributesProtocol {
38+
public init() {}
39+
40+
/// Transport protocol used.
41+
public var transport: SpanAttributeKey<String> { "net.transport" }
42+
43+
/// Remote address of the peer (dotted decimal for IPv4 or RFC5952 for IPv6).
44+
public var peerIP: SpanAttributeKey<String> { "net.peer.ip" }
45+
46+
/// Remote port number as an integer. E.g., 80.
47+
public var peerPort: SpanAttributeKey<Int> { "net.peer.port" }
48+
49+
/// Remote hostname or similar.
50+
public var peerName: SpanAttributeKey<String> { "net.peer.name" }
51+
52+
/// Like `peerIP` but for the host IP. Useful in case of a multi-IP host.
53+
public var hostIP: SpanAttributeKey<String> { "net.host.ip" }
54+
55+
/// Like `peerPort` but for the host port.
56+
public var hostPort: SpanAttributeKey<Int> { "net.host.port" }
57+
58+
/// Local hostname or similar.
59+
public var hostName: SpanAttributeKey<String> { "net.host.name" }
60+
}
61+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020 Moritz Lang and the Swift Tracing project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
//
10+
// SPDX-License-Identifier: Apache-2.0
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
import TracingInstrumentation
15+
16+
extension SpanAttributes {
17+
/// General semantic attributes.
18+
public var peer: PeerAttributes {
19+
get {
20+
.init(attributes: self)
21+
}
22+
set {
23+
self = newValue.attributes
24+
}
25+
}
26+
}
27+
28+
/// Peer-related semantic conventions as defined in the OpenTelemetry spec.
29+
@dynamicMemberLookup
30+
public struct PeerAttributes: SpanAttributeNamespace {
31+
public var attributes: SpanAttributes
32+
33+
public init(attributes: SpanAttributes) {
34+
self.attributes = attributes
35+
}
36+
37+
public struct NestedAttributes: NestedSpanAttributesProtocol {
38+
public init() {}
39+
40+
/// The service.name of the remote service. SHOULD be equal to the actual service.name resource attribute of the remote service if any.
41+
public var service: SpanAttributeKey<String> { "peer.service" }
42+
}
43+
}

0 commit comments

Comments
 (0)