mirror of https://github.com/vapor/docs.git
Adds tracing documentation (#1039)
<!-- 🚀 Thank you for contributing! --> <!-- Describe your changes clearly and use examples if possible. --> Adds new Tracing chapter to document API introduced in https://github.com/vapor/vapor/pull/3253 <!-- When this PR is merged, the title and body will be --> <!-- used to generate a release automatically. -->
This commit is contained in:
parent
399b55f27f
commit
a0d7615b8d
|
|
@ -0,0 +1,83 @@
|
|||
# Tracing
|
||||
|
||||
Tracing is a powerful tool for monitoring and debugging distributed systems. Vapor's tracing API allows developers to easily track request lifecycles, propagate metadata, and integrate with popular backends like OpenTelemetry.
|
||||
|
||||
Vapor's tracing API is built on top of [swift-distributed-tracing](https://github.com/apple/swift-distributed-tracing), which means it is compatible with all of swift-distributed-tracing's [backend implementations](https://github.com/apple/swift-distributed-tracing/blob/main/README.md#tracing-backends).
|
||||
|
||||
If you are unfamiliar with tracing and spans in Swift, review the [OpenTelemetry Trace documentation](https://opentelemetry.io/docs/concepts/signals/traces/) and [swift-distributed-tracing documentation](https://swiftpackageindex.com/apple/swift-distributed-tracing/main/documentation/tracing).
|
||||
|
||||
## TracingMiddleware
|
||||
|
||||
To automatically create a fully annotated span for each request, add the `TracingMiddleware` to your application.
|
||||
|
||||
```swift
|
||||
app.middleware.use(TracingMiddleware())
|
||||
```
|
||||
|
||||
To get accurate span measurements and ensure that tracing identifiers are passed along correctly to other services, add this middleware before other middlewares.
|
||||
|
||||
## Adding Spans
|
||||
|
||||
When adding spans to route handlers, it's ideal for them to be associated with the top-level request span. This is referred to as "span propagation" and can be handled in two different ways: automatic or manual.
|
||||
|
||||
### Automatic Propagation
|
||||
|
||||
Vapor has support to automatically propagate spans between middleware and route callbacks. To do so, set the `Application.traceAutoPropagation` property to true during configuration.
|
||||
|
||||
```swift
|
||||
app.traceAutoPropagation = true
|
||||
```
|
||||
|
||||
!!! note
|
||||
Enabling auto-propagation may degrade performance on high-throughput APIs with minimal tracing needs, since request span metadata must be restored for every route handler regardless of whether spans are created.
|
||||
|
||||
Then spans may be created in the route closure using the ordinary distributed tracing syntax.
|
||||
|
||||
```swift
|
||||
app.get("fetchAndProcess") { req in
|
||||
let result = try await fetch()
|
||||
return try await withSpan("getNameParameter") { _ in
|
||||
try await process(result)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Manual Propagation
|
||||
|
||||
To avoid the performance implications of automatic propagation, you may manually restore span metadata where necessary. `TracingMiddleware` automatically sets a `Request.serviceContext` property which may be used directly in `withSpan`'s `context` parameter.
|
||||
|
||||
```swift
|
||||
app.get("fetchAndProcess") { req in
|
||||
let result = try await fetch()
|
||||
return try await withSpan("getNameParameter", context: req.serviceContext) { _ in
|
||||
try await process(result)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To restore the span metadata without creating a span, use `ServiceContext.withValue`. This is valuable if you know that downstream async libraries emit their own tracing spans, and those should be nested underneath the parent request span.
|
||||
|
||||
```swift
|
||||
app.get("fetchAndProcess") { req in
|
||||
try await ServiceContext.withValue(req.serviceContext) {
|
||||
try await fetch()
|
||||
return try await process(result)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## NIO Considerations
|
||||
|
||||
Because `swift-distributed-tracing` uses [`TaskLocal properties`](https://developer.apple.com/documentation/swift/tasklocal) to propagate, you must manually re-restore the context whenever you cross `NIO EventLoopFuture` boundaries to ensure spans are linked correctly. **This is necessary regardless of whether automatic propagation is enabled**.
|
||||
|
||||
```swift
|
||||
app.get("fetchAndProcessNIO") { req in
|
||||
withSpan("fetch", context: req.serviceContext) { span in
|
||||
fetchSomething().map { result in
|
||||
withSpan("process", context: span.context) { _ in
|
||||
process(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -578,6 +578,7 @@ nav:
|
|||
- Services: "advanced/services.md"
|
||||
- Request: "advanced/request.md"
|
||||
- APNS: "advanced/apns.md"
|
||||
- Tracing: "advanced/tracing.md"
|
||||
- Security:
|
||||
- Authentication: "security/authentication.md"
|
||||
- Crypto: "security/crypto.md"
|
||||
|
|
|
|||
Loading…
Reference in New Issue