Skip to content

Commit 4018353

Browse files
ktosoMaxDesiatovyim-leeporglezomp
authored
[Docs] Combined initial documentation work (#121)
* [Docs] Combined initial documentation work Update Samples/Dinner/docker/collector-config.yaml Co-authored-by: Moritz Lang <[email protected]> minor cleanup wip * Showcase setting whole attributes to avoid fine grained locking **Motivation:** Since modifying an attribute needs to hit a lock this pattern is more efficient * fix warnings * Adjust licensing headers * Explain soon deprecation of LegacyTracer **Motivation:** This type will be deprecated as soon as possible and only serves as a bridge for Swift 5.6 adopters. * Apply suggestions from code review Co-authored-by: Max Desiatov <[email protected]> * Update Sources/Tracing/Docs.docc/Guides/InstrumentYourLibrary.md Co-authored-by: Yim Lee <[email protected]> * Explain soon deprecation of LegacyTracer **Motivation:** This type will be deprecated as soon as possible and only serves as a bridge for Swift 5.6 adopters. * minor cleanup * Update Sources/Tracing/Docs.docc/Guides/TraceYourApplication.md Co-authored-by: Cassie Jones <[email protected]> --------- Co-authored-by: Max Desiatov <[email protected]> Co-authored-by: Yim Lee <[email protected]> Co-authored-by: Cassie Jones <[email protected]>
1 parent 3d152af commit 4018353

35 files changed

+1476
-540
lines changed

Docs/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Documentation landing page
2+
3+
This documentation target exists only to serve as a landing page for self-hosted documentation.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# ``SwiftDistributedTracing``
2+
3+
A Distributed Tracing API for Swift.
4+
5+
## Overview
6+
7+
This is a collection of Swift libraries enabling the instrumentation of server side applications using tools such as tracers. Our goal is to provide a common foundation that allows to freely choose how to instrument systems with minimal changes to your actual code.
8+
9+
While Swift Distributed Tracing allows building all kinds of _instruments_, which can co-exist in applications transparently, its primary use is instrumenting multi-threaded and distributed systems with Distributed Traces.
10+
11+
### Quickstart Guides
12+
13+
We provide a number of guides aimed at getting your started with tracing your systems and have prepared them from three "angles":
14+
15+
1. **Application developers** who create server-side applications
16+
* please refer to the <doc:TraceYourApplication> guide.
17+
2. **Library/Framework developers** who provide building blocks to create these applications
18+
* please refer to the <doc:InstrumentYourLibrary> guide.
19+
3. **Instrument developers** who provide tools to collect distributed metadata about your application
20+
* please refer to the <doc:ImplementATracer> guide.
21+
22+
23+
## Topics
24+
25+
### Guides
26+
27+
- <doc:TraceYourApplication>
28+
- <doc:InstrumentYourLibrary>
29+
- <doc:ImplementATracer>
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020-2021 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+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //
16+
// This module is left purposefully empty of any source files, as it serves
17+
// only as a "landing page" for the documentation. This is in-place until docc
18+
// gains the ability to support package-wide documentation.
19+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //

Samples/Dinner/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.build
2+
Package.resolved

Samples/Dinner/Package.swift

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// swift-tools-version:5.3
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "onboarding",
6+
platforms: [
7+
.macOS("13.0.0"),
8+
],
9+
products: [
10+
.executable(name: "onboarding", targets: ["Onboarding"]),
11+
],
12+
dependencies: [
13+
// This example uses the following tracer implementation:
14+
.package(url: "https://github.com/slashmo/swift-otel", .branch("main")),
15+
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.0"),
16+
],
17+
targets: [
18+
.target(name: "Onboarding", dependencies: [
19+
.product(name: "OpenTelemetry", package: "swift-otel"),
20+
.product(name: "OtlpGRPCSpanExporting", package: "swift-otel"),
21+
]),
22+
]
23+
)

Samples/Dinner/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## Tracing Dinner Sample App
2+
3+
In order to try this sample app, and visualize traces it produces, you should first run `docker-compose` in order
4+
to launch a docker containers which host a Zipkin UI and collector:
5+
6+
```
7+
# cd Samples/Dinner
8+
9+
docker-compose -f docker/docker-compose.yaml up --build
10+
```
11+
12+
and then run the sample app which will produce a number of traces:
13+
14+
```
15+
swift run -c release
16+
```
17+
18+
Refer to the "Trace Your Application" guide in the documentation to learn more about how to interpret this sample.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020-2023 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+
//
16+
// This source file is part of the Swift OpenTelemetry open source project
17+
//
18+
// Copyright (c) 2021 Moritz Lang and the Swift OpenTelemetry project authors
19+
// Licensed under Apache License v2.0
20+
//
21+
// See LICENSE.txt for license information
22+
//
23+
// SPDX-License-Identifier: Apache-2.0
24+
//
25+
//===----------------------------------------------------------------------===//
26+
27+
func sleep(for duration: ContinuousClock.Duration) async {
28+
try? await Task.sleep(until: ContinuousClock.now + duration, clock: .continuous)
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020-2023 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+
//
16+
// This source file is part of the Swift OpenTelemetry open source project
17+
//
18+
// Copyright (c) 2021 Moritz Lang and the Swift OpenTelemetry project authors
19+
// Licensed under Apache License v2.0
20+
//
21+
// See LICENSE.txt for license information
22+
//
23+
// SPDX-License-Identifier: Apache-2.0
24+
//
25+
//===----------------------------------------------------------------------===//
26+
27+
28+
import Tracing
29+
30+
func makeDinner() async throws -> Meal {
31+
try await InstrumentationSystem.tracer.withSpan("makeDinner") { _ in
32+
await sleep(for: .milliseconds(200))
33+
34+
async let veggies = try chopVegetables()
35+
async let meat = marinateMeat()
36+
async let oven = preheatOven(temperature: 350)
37+
// ...
38+
return try await cook(veggies, meat, oven)
39+
}
40+
}
41+
42+
func chopVegetables() async throws -> [Vegetable] {
43+
try await otelChopping1.tracer().withSpan("chopVegetables") { _ in
44+
// Chop the vegetables...!
45+
//
46+
// However, since chopping is a very difficult operation,
47+
// one chopping task can be performed at the same time on a single service!
48+
// (Imagine that... we cannot parallelize these two tasks, and need to involve another service).
49+
async let carrot = try chop(.carrot, tracer: otelChopping1.tracer())
50+
async let potato = try chop(.potato, tracer: otelChopping2.tracer())
51+
return try await [carrot, potato]
52+
}
53+
}
54+
55+
func chop(_ vegetable: Vegetable, tracer: any Tracer) async throws -> Vegetable {
56+
await tracer.withSpan("chop-\(vegetable)") { _ in
57+
await sleep(for: .seconds(5))
58+
// ...
59+
return vegetable // "chopped"
60+
}
61+
}
62+
63+
func marinateMeat() async -> Meat {
64+
await sleep(for: .milliseconds(620))
65+
66+
return await InstrumentationSystem.tracer.withSpan("marinateMeat") { _ in
67+
await sleep(for: .seconds(3))
68+
// ...
69+
return Meat()
70+
}
71+
}
72+
73+
func preheatOven(temperature: Int) async -> Oven {
74+
await InstrumentationSystem.tracer.withSpan("preheatOven") { _ in
75+
// ...
76+
await sleep(for: .seconds(6))
77+
return Oven()
78+
}
79+
}
80+
81+
func cook(_: Any, _: Any, _: Any) async -> Meal {
82+
await InstrumentationSystem.tracer.withSpan("cook") { span in
83+
span.addEvent("children-asking-if-done-already")
84+
await sleep(for: .seconds(3))
85+
span.addEvent("children-asking-if-done-already-again")
86+
await sleep(for: .seconds(2))
87+
// ...
88+
return Meal()
89+
}
90+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020-2023 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+
//
16+
// This source file is part of the Swift OpenTelemetry open source project
17+
//
18+
// Copyright (c) 2021 Moritz Lang and the Swift OpenTelemetry project authors
19+
// Licensed under Apache License v2.0
20+
//
21+
// See LICENSE.txt for license information
22+
//
23+
// SPDX-License-Identifier: Apache-2.0
24+
//
25+
//===----------------------------------------------------------------------===//
26+
27+
28+
struct Meal: Sendable {}
29+
struct Meat: Sendable {}
30+
struct Oven: Sendable {}
31+
enum Vegetable: Sendable {
32+
case potato
33+
case carrot
34+
}
35+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Distributed Tracing open source project
4+
//
5+
// Copyright (c) 2020-2023 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+
//
16+
// This source file is part of the Swift OpenTelemetry open source project
17+
//
18+
// Copyright (c) 2021 Moritz Lang and the Swift OpenTelemetry project authors
19+
// Licensed under Apache License v2.0
20+
//
21+
// See LICENSE.txt for license information
22+
//
23+
// SPDX-License-Identifier: Apache-2.0
24+
//
25+
//===----------------------------------------------------------------------===//
26+
27+
28+
import Logging
29+
import NIO
30+
import OpenTelemetry
31+
import OtlpGRPCSpanExporting
32+
import Tracing
33+
34+
// ==== ----------------------------------------------------------------------------------------------------------------
35+
36+
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
37+
38+
LoggingSystem.bootstrap { label in
39+
var handler = StreamLogHandler.standardOutput(label: label)
40+
handler.logLevel = .trace
41+
return handler
42+
}
43+
44+
// ==== ----------------------------------------------------------------------------------------------------------------
45+
// MARK: - Configure OTel
46+
47+
let exporter = OtlpGRPCSpanExporter(config: OtlpGRPCSpanExporter.Config(eventLoopGroup: group))
48+
let processor = OTel.SimpleSpanProcessor(exportingTo: exporter)
49+
let otel = OTel(serviceName: "DinnerService", eventLoopGroup: group, processor: processor)
50+
51+
let otelChopping1 = OTel(serviceName: "ChoppingService-1", eventLoopGroup: group, processor: processor)
52+
let otelChopping2 = OTel(serviceName: "ChoppingService-2", eventLoopGroup: group, processor: processor)
53+
54+
// First start `OTel`, then bootstrap the instrumentation system.
55+
// This makes sure that all components are ready to begin handling spans.
56+
try otel.start().wait()
57+
try otelChopping1.start().wait()
58+
try otelChopping2.start().wait()
59+
60+
// By bootstrapping the instrumentation system, our dependencies
61+
// compatible with "Swift Distributed Tracing" will also automatically
62+
// use the "OpenTelemetry Swift" Tracer 🚀.
63+
InstrumentationSystem.bootstrap(otel.tracer())
64+
65+
// ==== ----------------------------------------------------------------------------------------------------------------
66+
// MARK: - Run the sample app
67+
68+
let dinner = try await makeDinner()
69+
70+
// ==== ----------------------------------------------------------------------------------------------------------------
71+
// MARK: - Shutdown
72+
73+
// Wait a second to let the exporter finish before shutting down.
74+
sleep(2)
75+
76+
try otel.shutdown().wait()
77+
try group.syncShutdownGracefully()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
receivers:
2+
otlp:
3+
protocols:
4+
grpc:
5+
endpoint: otel-collector:4317
6+
7+
exporters:
8+
logging:
9+
verbosity: detailed
10+
11+
jaeger:
12+
endpoint: "jaeger:14250"
13+
tls:
14+
insecure: true
15+
16+
zipkin:
17+
endpoint: "http://zipkin:9411/api/v2/spans"
18+
19+
20+
service:
21+
pipelines:
22+
traces:
23+
receivers: otlp
24+
exporters: [logging, jaeger, zipkin]
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
version: '3'
2+
services:
3+
otel-collector:
4+
image: otel/opentelemetry-collector-contrib:latest
5+
command: ["--config=/etc/config.yaml"]
6+
volumes:
7+
- ./collector-config.yaml:/etc/config.yaml
8+
ports:
9+
- "4317:4317"
10+
networks: [exporter]
11+
depends_on: [zipkin, jaeger]
12+
13+
zipkin:
14+
image: openzipkin/zipkin:latest
15+
ports:
16+
- "9411:9411"
17+
networks: [exporter]
18+
19+
jaeger:
20+
image: jaegertracing/all-in-one
21+
ports:
22+
- "16686:16686"
23+
networks: [exporter]
24+
25+
networks:
26+
exporter:

0 commit comments

Comments
 (0)