Skip to content

Commit f2f1ff7

Browse files
author
Ignacio Bonafonte
committed
Add new SignPostIntegration instrumentation, it allow to integrate spans created in opentelemetry with os_signpost functionality, allowing the spans to appear automatically in Instruments when profiling the app.
1 parent 19a2d0e commit f2f1ff7

File tree

5 files changed

+75
-2
lines changed

5 files changed

+75
-2
lines changed

Examples/Simple Exporter/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
### Simple Exporter
22

3-
This example shows the Jaeger an Stdout exporters in action using a MultiSpanExporter
3+
This example shows the Jaeger an Stdout exporters in action using a MultiSpanExporter. It also adds support for SignPostIntegration, so running this app in `Instruments` will show the span creation and duration
44

55
The sample expects a local Jaeger installation as explained in [Jaeger docs](https://www.jaegertracing.io/docs/1.16/getting-started/#all-in-one):
66

Examples/Simple Exporter/main.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import OpenTelemetrySdk
2020
import ResourceExtension
2121
import StdoutExporter
2222
import ZipkinExporter
23+
import SignPostIntegration
2324

2425
let sampleKey = "sampleKey"
2526
let sampleValue = "sampleValue"
@@ -36,15 +37,18 @@ tracer = OpenTelemetrySDK.instance.tracerProvider.get(instrumentationName: instr
3637
func simpleSpan() {
3738
let span = tracer.spanBuilder(spanName: "SimpleSpan").setSpanKind(spanKind: .client).startSpan()
3839
span.setAttribute(key: sampleKey, value: sampleValue)
40+
Thread.sleep(forTimeInterval: 0.5)
3941
span.end()
4042
}
4143

4244
func childSpan() {
4345
let span = tracer.spanBuilder(spanName: "parentSpan").setSpanKind(spanKind: .client).startSpan()
4446
span.setAttribute(key: sampleKey, value: sampleValue)
47+
Thread.sleep(forTimeInterval: 0.2)
4548
OpenTelemetry.instance.contextProvider.setActiveSpan(span)
4649
let childSpan = tracer.spanBuilder(spanName: "childSpan").setSpanKind(spanKind: .client).startSpan()
4750
childSpan.setAttribute(key: sampleKey, value: sampleValue)
51+
Thread.sleep(forTimeInterval: 0.5)
4852
childSpan.end()
4953
span.end()
5054
}
@@ -61,6 +65,11 @@ let spanExporter = MultiSpanExporter(spanExporters: [jaegerExporter, stdoutExpor
6165
let spanProcessor = SimpleSpanProcessor(spanExporter: spanExporter)
6266
OpenTelemetrySDK.instance.tracerProvider.addSpanProcessor(spanProcessor)
6367

68+
if #available(macOS 10.14, *) {
69+
OpenTelemetrySDK.instance.tracerProvider.addSpanProcessor(SignPostIntegration())
70+
}
71+
72+
6473
simpleSpan()
6574
sleep(1)
6675
childSpan()

Package.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ let package = Package(
1818
.library(name: "libResourceExtension", type: .static, targets: ["ResourceExtension"]),
1919
.library(name: "URLSessionInstrumentation", type: .dynamic, targets: ["URLSessionInstrumentation"]),
2020
.library(name: "libURLSessionInstrumentation", type: .static, targets: ["URLSessionInstrumentation"]),
21+
.library(name: "SignPostIntegration", type: .dynamic, targets: ["SignPostIntegration"]),
22+
.library(name: "libSignPostIntegration", type: .static, targets: ["SignPostIntegration"]),
2123
.library(name: "OpenTracingShim-experimental", type: .dynamic, targets: ["OpenTracingShim"]),
2224
.library(name: "libOpenTracingShim-experimental", type: .static, targets: ["OpenTracingShim"]),
2325
.library(name: "SwiftMetricsShim-experimental", type: .dynamic, targets: ["SwiftMetricsShim"]),
@@ -61,6 +63,10 @@ let package = Package(
6163
dependencies: ["OpenTelemetrySdk"],
6264
path: "Sources/Instrumentation/URLSession",
6365
exclude: ["README.md"]),
66+
.target(name: "SignPostIntegration",
67+
dependencies: ["OpenTelemetrySdk"],
68+
path: "Sources/Instrumentation/SignPostIntegration",
69+
exclude: ["README.md"]),
6470
.target(name: "OpenTracingShim",
6571
dependencies: ["OpenTelemetrySdk",
6672
"Opentracing"],
@@ -145,7 +151,7 @@ let package = Package(
145151
dependencies: ["OpenTelemetryApi"],
146152
path: "Examples/Logging Tracer"),
147153
.target(name: "SimpleExporter",
148-
dependencies: ["OpenTelemetrySdk", "JaegerExporter", "StdoutExporter", "ZipkinExporter", "ResourceExtension"],
154+
dependencies: ["OpenTelemetrySdk", "JaegerExporter", "StdoutExporter", "ZipkinExporter", "ResourceExtension", "SignPostIntegration"],
149155
path: "Examples/Simple Exporter",
150156
exclude: ["README.md"]),
151157
.target(name: "PrometheusSample",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# SignPost Integration
2+
3+
This package creates `os_signpost` `begin` and `end` calls when spans are started or ended. It allows automatic integration of applications
4+
instrumented with opentelemetry to show their spans in a profiling app like `Instruments`. It also exports the `OSLog` it uses for posting so the user can add extra signpost events. This functionality is shown in `Simple Exporter` example
5+
6+
7+
## Usage
8+
9+
Just add SignpostIntegration as any other Span Processor:
10+
11+
```
12+
OpenTelemetry.instance.tracerProvider.addSpanProcessor(SignPostIntegration())`
13+
```
14+
15+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2020, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
16+
17+
import Foundation
18+
import os
19+
import OpenTelemetryApi
20+
import OpenTelemetrySdk
21+
22+
/// A span processor that decorates spans with the origin attribute
23+
@available(macOS 10.14, *)
24+
public class SignPostIntegration: SpanProcessor {
25+
public let isStartRequired = true
26+
public let isEndRequired = true
27+
public let osLog = OSLog(subsystem: "OpenTelemetry", category: .pointsOfInterest)
28+
29+
public init() {}
30+
31+
public func onStart(parentContext: SpanContext?, span: ReadableSpan) {
32+
let signpostID = OSSignpostID(log: osLog, object: self)
33+
os_signpost(.begin, log: osLog, name: "Span", signpostID: signpostID, "%{public}@", span.name)
34+
}
35+
36+
public func onEnd(span: ReadableSpan) {
37+
let signpostID = OSSignpostID(log: osLog, object: self)
38+
os_signpost(.end, log: osLog, name: "Span", signpostID: signpostID)
39+
}
40+
41+
public func shutdown() {}
42+
public func forceFlush() {}
43+
}

0 commit comments

Comments
 (0)