Swift Opentelemetry Instrumentation
This document contains instructions on how to set up OpenTelemetry instrumentation in your Swift applications and view your application traces in SigNoz.
Requirements
Send traces to SigNoz Cloud
Based on your application environment, you can choose the setup below to send traces to SigNoz Cloud.
From VMs, there are two ways to send data to SigNoz Cloud.
Send traces directly to SigNoz cloud
Here we will be sending traces to SigNoz cloud in 4 easy steps, if you want to send traces to self hosted SigNoz , you can refer to this.
If you are using the sample swift application, then you just need to update the ingestion key and SigNoz endpoint after that you are good to go!
Step 1 : Instrument your application with OpenTelemetry
To configure your Swift application to send traces to OpenTelemetry you need to install opentelemetry-swift and grpc-swift as dependency in your project.
For that, paste the following inside Package.swift
of your project.
dependencies: [
.package(url: "https://github.com/open-telemetry/opentelemetry-swift.git", .upToNextMajor(from: "1.9.1")),
.package(url: "https://github.com/grpc/grpc-swift", from: "1.15.0"),
],
targets: [
.executableTarget(
name: "<service_name>",
dependencies: [
.product(name: "OpenTelemetryApi", package: "opentelemetry-swift"),
.product(name: "OpenTelemetrySdk", package: "opentelemetry-swift"),
.product(name: "StdoutExporter", package: "opentelemetry-swift"),
.product(name: "ResourceExtension", package: "opentelemetry-swift"),
.product(name: "ZipkinExporter", package: "opentelemetry-swift"),
.product(name: "OpenTelemetryProtocolExporter", package: "opentelemetry-swift"),
.product(name: "SignPostIntegration", package: "opentelemetry-swift"),
.product(name: "GRPC", package: "grpc-swift")
],
path: "."
)
]
- Set the
<region>
to match your SigNoz Cloud region
You also need to add the following imports to use the methods and functions from the packages/dependencies which you just imported in Package.swift
file.
import Foundation
import GRPC
import NIO
import NIOSSL
import OpenTelemetryApi
import OpenTelemetryProtocolExporterCommon
import OpenTelemetryProtocolExporterGrpc
import OpenTelemetrySdk
import ResourceExtension
import SignPostIntegration
import StdoutExporter
import ZipkinExporter
Step 2: Initialize the tracer
To enable tracing and send traces to the SigNoz cloud, you need to initialize the tracer, to do that insert the following code snippet into your main.swift
file
var resources = DefaultResources().get()
let instrumentationScopeName = "SwiftExample"
let instrumentationScopeVersion = "semver:0.1.0"
let otlpConfiguration: OtlpConfiguration = OtlpConfiguration(timeout: TimeInterval(10), headers: [("signoz-ingestion-key", <your-ingestion-key>)])
let grpcChannel = ClientConnection.usingPlatformAppropriateTLS(for: MultiThreadedEventLoopGroup(numberOfThreads:1)).connect(host: ingest.<region>.signoz.cloud, port: 443)
let otlpTraceExporter = OtlpTraceExporter(channel: grpcChannel,
config: otlpConfiguration)
let stdoutExporter = StdoutExporter()
let spanExporter = MultiSpanExporter(spanExporters: [otlpTraceExporter, stdoutExporter])
let spanProcessor = SimpleSpanProcessor(spanExporter: spanExporter)
OpenTelemetry.registerTracerProvider(tracerProvider:
TracerProviderBuilder()
.add(spanProcessor: spanProcessor)
.build()
)
- Set the
<region>
to match your SigNoz Cloud region - Replace
<your-ingestion-key>
with your SigNoz ingestion key.
Step 3: Send Telemetry data to SigNoz
To send telemetry data to SigNoz, you can create a function to add spans and data. This is a sample function
let sampleKey = "sampleKey"
let sampleValue = "sampleValue"
func doWork() {
let childSpan = tracer.spanBuilder(spanName: "doWork").setSpanKind(spanKind: .client).startSpan()
childSpan.setAttribute(key: sampleKey, value: sampleValue)
Thread.sleep(forTimeInterval: Double.random(in: 0 ..< 10) / 100)
childSpan.end()
}
Step 4: Run app
Execute your application by issuing the following command in terminal:
swift run
Send traces via OTel Collector binary
Step 1 : Install OTel Collector OTel Collector binary helps to collect logs, hostmetrics, resource and infra attributes. It is recommended to install Otel Collector binary to collect and send traces to SigNoz cloud. You can correlate signals and have rich contextual data through this way.
You can find instructions to install OTel Collector binary here in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Swift application.
Step 2 : Instrument your application with OpenTelemetry
To configure your Swift application to send traces to OpenTelemetry you need to install opentelemetry-swift and grpc-swift as dependency in your project.
For that, paste the following inside Package.swift
of your project.
dependencies: [
.package(url: "https://github.com/open-telemetry/opentelemetry-swift.git", .upToNextMajor(from: "1.9.1")),
.package(url: "https://github.com/grpc/grpc-swift", from: "1.15.0"),
],
targets: [
.executableTarget(
name: "<service_name>",
dependencies: [
.product(name: "OpenTelemetryApi", package: "opentelemetry-swift"),
.product(name: "OpenTelemetrySdk", package: "opentelemetry-swift"),
.product(name: "StdoutExporter", package: "opentelemetry-swift"),
.product(name: "ResourceExtension", package: "opentelemetry-swift"),
.product(name: "ZipkinExporter", package: "opentelemetry-swift"),
.product(name: "OpenTelemetryProtocolExporter", package: "opentelemetry-swift"),
.product(name: "SignPostIntegration", package: "opentelemetry-swift"),
.product(name: "GRPC", package: "grpc-swift")
],
path: "."
)
]
<service_name>
is name of your service
You also need to add the following imports to use the methods and functions from the packages/dependencies which you just imported in Package.swift
file.
import Foundation
import GRPC
import NIO
import NIOSSL
import OpenTelemetryApi
import OpenTelemetryProtocolExporterCommon
import OpenTelemetryProtocolExporterGrpc
import OpenTelemetrySdk
import ResourceExtension
import SignPostIntegration
import StdoutExporter
import ZipkinExporter
Step 3: Initialize the tracer
Add these statements to initialize tracer in the main.swift
file inside the main function or you can create another function for initializing the tracer and call it in some other block of code.
var resources = DefaultResources().get()
let instrumentationScopeName = "SwiftExample"
let instrumentationScopeVersion = "semver:0.1.0"
let otlpConfiguration: OtlpConfiguration = OtlpConfiguration(timeout: TimeInterval(10), headers: [("signoz-ingestion-key", "<your-ingestion-key>")])
let grpcChannel = ClientConnection.usingPlatformAppropriateTLS(for: MultiThreadedEventLoopGroup(numberOfThreads:1)).connect(host: "http://localhost", port: 4317)
let otlpTraceExporter = OtlpTraceExporter(channel: grpcChannel,
config: otlpConfiguration)
let stdoutExporter = StdoutExporter()
let spanExporter = MultiSpanExporter(spanExporters: [otlpTraceExporter, stdoutExporter])
let spanProcessor = SimpleSpanProcessor(spanExporter: spanExporter)
OpenTelemetry.registerTracerProvider(tracerProvider:
TracerProviderBuilder()
.add(spanProcessor: spanProcessor)
.build()
)
let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: instrumentationScopeName, instrumentationVersion: instrumentationScopeVersion)
Step 4: Send Telemetry data to SigNoz
To send telemetry data to SigNoz, you can create a function to add spans and data. This is a sample function
let sampleKey = "sampleKey"
let sampleValue = "sampleValue"
func doWork() {
let childSpan = tracer.spanBuilder(spanName: "doWork").setSpanKind(spanKind: .client).startSpan()
childSpan.setAttribute(key: sampleKey, value: sampleValue)
Thread.sleep(forTimeInterval: Double.random(in: 0 ..< 10) / 100)
childSpan.end()
}
Step 5: Run app
Run your app using the below command to send your traces:
swift run
Sample Swift Application
We have included a sample Swift application at Sample swift App Github Repo,