Overview
This document contains instructions on how to set up OpenTelemetry instrumentation in your iOS applications built using Swift and view your application traces in SigNoz.
Prerequisites
- A SwiftUI-based iOS application in Xcode.
- Swift toolchain installed; see Swift getting started.
- Access to a SigNoz Cloud account or self-hosted SigNoz instance.
Send traces to SigNoz
You can test the sample app for SwiftUI.
Step 1: Add OpenTelemetry dependencies
Install opentelemetry-swift and grpc-swift in Package.swift.
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 the name of your service.
Step 2: Initialize the tracer
Create OpentelemetrySetup.swift and configure the exporter.
// OpenTelemetrySetup.swift
import Foundation
import GRPC
import NIO
import NIOSSL
import OpenTelemetryApi
import OpenTelemetryProtocolExporterCommon
import OpenTelemetryProtocolExporterGrpc
import OpenTelemetrySdk
import ResourceExtension
import StdoutExporter
struct OpenTelemetrySetup {
static func configureOpenTelemetry() {
let resource = DefaultResources().get().merging(other: Resource(attributes: [
"service.name": AttributeValue.string("<service_name>"),
]))
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)
.with(resource: resource)
.build()
)
}
}
Replace the placeholders:
<service_name>: logical name of your iOS service; this is what you will see in SigNoz.<your-ingestion-key>: ingestion key for your SigNoz Cloud organization.<region>: your SigNoz Cloud region, for exampleus,eu, orin.
Using self-hosted SigNoz? Most steps are identical. Update the endpoint and remove the ingestion key header as shown in Cloud → Self-Hosted.
Once you replace the content of the file, you need to add init in the <project_name>.swift file
init() {
OpenTelemetrySetup.configureOpenTelemetry()
}
Step 3: Send telemetry data to SigNoz
To send telemetry data to SigNoz, you can create a function to add spans and data. But prior to that you need to import OpenTelemetryApi & create instance of tracer, using the following snippet
import OpenTelemetryApi // Import OpenTelemetryApi for the tracer
//this should be inside ContentView Struct
let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: "SwiftExample", instrumentationVersion: "semver:0.1.0")
// Function to simulate work and create a span
func doWork() {
let sampleKey = "sampleKey"
let sampleValue = "sampleValue"
// Start a new span named "doWork"
let childSpan = tracer.spanBuilder(spanName: "doWork")
.setSpanKind(spanKind: .client)
.startSpan()
// Set an attribute on the span
childSpan.setAttribute(key: sampleKey, value: sampleValue)
// Simulate some work by sleeping for a random interval
Thread.sleep(forTimeInterval: Double.random(in: 0 ..< 10) / 100)
// End the span
childSpan.end()
}
Step 4: Run the app
Run your application from Xcode.
Validate
- In SigNoz, go to Traces Explorer and confirm that the traces for your service (for example
<service_name>) are present. - Open a recent trace and verify that spans from your iOS app are present with the attributes you set.
Troubleshooting
- If you do not see your iOS service in SigNoz, confirm the endpoint/port is reachable from the simulator or device and that the ingestion key (for Cloud) is correct.
Next steps
- Explore your mobile traces in the Trace Explorer.
- Create latency and error alerts for your service using Alert Management.