You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Sources/Tracing/Docs.docc/Guides/ImplementATracer.md
+7-7Lines changed: 7 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@
4
4
5
5
This guide is aimed at ``TracerProtocol`` and ``InstrumentProtocol`` implementation authors.
6
6
7
-
This guide is for you, if you find yourself in need of implementing your own tracing client such as Zipkin, Jaeger, X-Trace, OpenTelemetry or something similar that is custom to your company or distributed system.
7
+
This guide is for you if you find yourself in need of implementing your own tracing client such as Zipkin, Jaeger, X-Trace, OpenTelemetry or something similar that is custom to your company or distributed system.
8
8
9
9
## Do you need an Instrument or a Tracer?
10
10
@@ -14,12 +14,12 @@ A tracer is-an instrument as well, and further refines it with the ability to st
14
14
15
15
## Creating an instrument
16
16
17
-
Creating an instrument means adopting the ``Instrument`` protocol (or ``Tracer`` in case you develop a tracer).
18
-
`Instrument` is part of the `Instrumentation` library &`Tracing` contains the ``Tracer`` protocol.
17
+
Creating an instrument means adopting the ``InstrumentProtocol`` protocol (or ``TracerProtocol`` in case you develop a tracer).
18
+
``InstrumentProtocol`` is part of the `Instrumentation` library and`Tracing` contains the ``TracerProtocol`` protocol.
19
19
20
20
`Instrument` has two requirements:
21
21
22
-
1. A method to inject values inside a `FIXME!!!` into a generic carrier (e.g. HTTP headers)
22
+
1. A method to inject values into a `FIXME!!!` a generic carrier (e.g. HTTP headers)
23
23
2. A method to extract values from a generic carrier (e.g. HTTP headers) and store them in a `FIXME!!!`
24
24
25
25
The two methods will be called by instrumented libraries/frameworks at asynchronous boundaries, giving you a chance to
> In case your library makes use of the `NIOHTTP1.HTTPHeaders` type we already have an `HTTPHeadersInjector`&
97
+
> In case your library makes use of the `NIOHTTP1.HTTPHeaders` type we already have an `HTTPHeadersInjector`and
98
98
`HTTPHeadersExtractor` available as part of the `NIOInstrumentation` library.
99
99
100
100
For your library/framework to be able to carry `FIXME!!!` across asynchronous boundaries, it's crucial that you carry the context throughout your entire call chain in order to avoid dropping metadata.
Copy file name to clipboardExpand all lines: Sources/Tracing/Docs.docc/Guides/InstrumentYourLibrary.md
+14-14Lines changed: 14 additions & 14 deletions
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ This guide is aimed at library and framework developers who wish to instrument t
7
7
Doing so within a library may enable automatic trace propagation and is key to propagating trace information across
8
8
distributed nodes, e.g. by instrumenting the HTTP client used by such system.
9
9
10
-
Other examples of libraries which benefit _the most_ from being instrumented using distributed tracing include:
10
+
Other examples of libraries which would benefit _the most_ from being instrumented using distributed tracing include:
11
11
12
12
- HTTP Clients (e.g. AsyncHTTPClient),
13
13
- HTTP Servers (e.g. Vapor or Smoke),
@@ -20,16 +20,16 @@ it is them who must inject and extract contextual baggage metadata to enable dis
20
20
21
21
Following those, any database or other complex library which may be able to emit useful information about its internals are
22
22
also good candidates to being instrumented. Note that libraries may do so optionally, or hide the "verboseness" of such traces
23
-
behind options, or only attach information if a Span is already active etc. Please review your library's documentation to learn
23
+
behind options, or only attach information if a ``Span`` is already active etc. Please review your library's documentation to learn
24
24
more about it has integrated tracing support.
25
25
26
26
### Propagating baggage metadata
27
27
28
-
When crossing boundaries between processes, such as making or receiving an HTTP request, the library responsible for doing so, should invoke instrumentation in order to inject or extract the contextual baggage metadata into/from the "carrier" type (such as the `HTTPResponse`) type.
28
+
When crossing boundaries between processes, such as making or receiving an HTTP request, the library responsible for doing so should invoke instrumentation in order to inject or extract the contextual baggage metadata into/from the "carrier" type (such as the `HTTPResponse`) type.
29
29
30
30
#### Handling outbound requests
31
31
32
-
When a library makes an "outgoing" request or message interaction, it should invoke the method of a configured instrument. This will invoke whichever instrument the end-user has configured and allow them to customize what metadata gets to be propagated. This can be by the following diagram:
32
+
When a library makes an "outgoing" request or message interaction, it should invoke the method of a configured instrument. This will invoke whichever instrument the end-user has configured and allow them to customize what metadata gets to be propagated. This can be depicted by the following diagram:
33
33
34
34
```
35
35
┌──────────────────────────────────┐
@@ -74,7 +74,7 @@ As you can see, the library does not know anything about what tracing system or
74
74
75
75
All it has to do is query for the current [task-local](https://developer.apple.com/documentation/swift/tasklocal)`Baggage` value, and if one is present, call on the instrumentation system to inject it into the request.
76
76
77
-
Since neither, the tracing API, or the specific tracer backend are aware of this library's specific `HTTPRequest` type, we also need to implement an ``Injector`` which takes on the responsibility of adding the metadata into the carrier type (which in our case is the `HTTPRequest`). An injector could for example be implemented like this:
77
+
Since neither the tracing API nor the specific tracer backend is aware of this library's specific `HTTPRequest` type, we also need to implement an ``Injector`` which takes on the responsibility of adding the metadata into the carrier type (which in our case is the `HTTPRequest`). An injector could for example be implemented like this:
Once the metadat has been injected, the request–including all the additional metadata–is sent over the network.
87
+
Once the metadata has been injected, the request–including all the additional metadatais sent over the network.
88
88
89
89
> Note: The actual logic of deciding what baggage values to inject depend on the tracer implementation, and thus we are not covering it in this _end-user_ focused guide. Refer to <doc:ImplementATracer> if you'd like to learn about implementing a ``TracerProtocol``.
90
90
91
91
#### Handling inbound requests
92
92
93
-
On the receiving side, an HTTP server needs to perform the inverse operation, as it receives the request from the network and forms an `HTTPRequest` object, and before it passed it to user-code, it must extract any trace metadata from the request headers into the `Baggage`.
93
+
On the receiving side, an HTTP server needs to perform the inverse operation, as it receives the request from the network and forms an `HTTPRequest` object, and before it passes it to user-code, it must extract any trace metadata from the request headers into the `Baggage`:
94
94
95
95
```
96
96
┌──────────────────────────────────┐
@@ -113,7 +113,7 @@ On the receiving side, an HTTP server needs to perform the inverse operation, as
113
113
└────
114
114
```
115
115
116
-
This is very similar to what we were doing on the outbound side, but the roles of baggage and request are somewhat inversed: we're extracting values from the carrier into the baggage. The code performing this task could look something like this:
116
+
This is very similar to what we were doing on the outbound side, but the roles of baggage and request are somewhat reversed: we're extracting values from the carrier into the baggage. The code performing this task could look something like this:
Similarily to the outbound side, we need to implement an ``Extractor`` because the tracing libraries don't know about our specific HTTP types, yet we need to have them decide for which values to extract keys.
135
+
Similarly to the outbound side, we need to implement an ``Extractor`` because the tracing libraries don't know about our specific HTTP types, yet we need to have them decide for which values to extract keys.
This sets the task-local value `Baggage.current` which is used by [swift-log](https://github.com/apple/swift-log), as well as ``TracerProtocol`` APIs in order to later "*pick up*" the baggage and and e.g. include it in log statements, or start new trace spans using the information stored in the baggage.
161
+
This sets the task-local value `Baggage.current` which is used by [swift-log](https://github.com/apple/swift-log), as well as ``TracerProtocol`` APIs in order to later "*pick up*" the baggage and e.g. include it in log statements, or start new trace spans using the information stored in the baggage.
162
162
163
163
> Note: The end goal here being that when end-users of your library write `log.info("Hello")` the logger is able to pick up the contextual baggage information and include the e.g. the `trace-id` in such log statement automatically! This way, every log made during the handling of this request would include the trade-id automatically, e.g. like this:
164
164
>
@@ -200,15 +200,15 @@ actor MySampleServer {
200
200
}
201
201
```
202
202
203
-
While this code is very simple for illustration purposes, and it may seem suprising why there are those two separate places where we need to call into user-code separately. But in practice such situations can happen when using asynchronous network or database libraries which offer their API in terms of such callbacks. Always consider if and when to restore baggage such that it makes sense for the end user.
203
+
While this code is very simple for illustration purposes, and it may seem surprising why there are two separate places where we need to call into user-code separately, in practice such situations can happen when using asynchronous network or database libraries which offer their API in terms of callbacks. Always consider if and when to restore baggage such that it makes sense for the end user.
204
204
205
205
### Starting Trace Spans in Your Library
206
206
207
207
The above steps are enough if you wanted to provide contextual baggage propagation, and already enables techniques such as *correlation ids* which can be set once, in one system, and then carried through to any downstream services the code makes calls from while the baggage is set.
208
208
209
-
Many libraries also have the opportunity to start trace spans themselfes, on behalf of users, in pieces of the library that can provide useful insight in the behavior or the library in production. For example, the HTTPServer can start spans as soon as it begins handling HTTP requests, and this way provide a parent span to any spans the user-code would be creating itself.
209
+
Many libraries also have the opportunity to start trace spans themselves, on behalf of users, in pieces of the library that can provide useful insight in the behavior or the library in production. For example, the HTTPServer can start spans as soon as it begins handling HTTP requests, and this way provide a parent span to any spans the user-code would be creating itself.
210
210
211
-
Let us revisit the previous sample HTTPServer which restored baggage around invoking the user-code, and further extend it to start a span including basic information about the HTTPRequest being handled:
211
+
Let us revisit the previous sample HTTPServer which restores baggage around invoking the user-code, and further extend it to start a span including basic information about the HTTPRequest being handled:
It is very important to _always_ end spans that are started, as otherwise resources they use may keep accumulating and lead to memory leaks, or worse issues in tracing backends dependin on their implementation.
275
+
It is very important to _always_ end spans that have been started, as otherwise resources they use may keep accumulating and lead to memory leaks, or worse issues in tracing backends depending on their implementation.
276
276
277
277
The manual way of managing spans also means that error paths need to be treated with increased attention. This is something the `withSpan` APIs handle automatically, but we cannot rely on the `withSpan` detecting an error thrown out of its body closure anymore when using the `startSpan`/`end` APIs.
Copy file name to clipboardExpand all lines: Sources/Tracing/Docs.docc/Guides/TraceYourApplication.md
+5-6Lines changed: 5 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -2,13 +2,12 @@
2
2
3
3
## Overview
4
4
5
-
This guide is aimed at **application developers** who have some server-side system and with to make use of distributed tracing
6
-
in order to improve their experience understanding, and performance tuning and debugging their services in production or development.
5
+
This guide is aimed at **application developers** who have some server-side system and want to make use of distributed tracing
6
+
in order to improve their understanding and facilitate performance tuning and debugging their services in production or development.
7
7
8
-
Distributed tracing offers a way to gain additional insight into your application is performing in production,
9
-
without having to reconstruct the "big picture" from manually piecing together log lines and figuring out what happened
8
+
Distributed tracing offers a way to gain additional insight into how your application is performing in production, without having to reconstruct the "big picture" from manually piecing together log lines and figuring out what happened
10
9
after what else and _why_. Distributed traces, as the name implies, also span multiple nodes in a micro-service architecture
11
-
or clustered system, and provide a profilerlike experience to debugging the handling of a "request" or otherwise defined span.
10
+
or clustered system, and provide a profiler-like experience to debugging the handling of a "request" or otherwise defined span.
12
11
13
12
### Setting up instruments & tracers
14
13
@@ -92,7 +91,7 @@ Libraries which support tracing are expected to accept a `FIXME!!!` parameter, w
92
91
93
92
> 💡 This general style recommendation has been ironed out together with the Swift standard library, core team, the SSWG as well as members of the community. Please respect these recommendations when designing APIs such that all APIs are able to "feel the same" yielding a great user experience for our end users ❤️
94
93
>
95
-
> It is possible that the ongoing Swift Concurrency efforts, and "Task Local" values will resolve this explicit context passing problem, however until these arrive in the language, please adopt the "context is the last parameter" style as outlined here.
94
+
> It is possible that the ongoing Swift Concurrency efforts and "Task Local" values will resolve this explicit context passing problem, however until these arrive in the language, please adopt the "context is the last parameter" style as outlined here.
96
95
97
96
Propagating baggage context through your system is to be done explicitly, meaning as a parameter in function calls, following the "flow" of execution.
0 commit comments