Documentation

OpenTelemetry Instrumentation for Swift

Overview

OpenTelemetry provides instrumentation for Swift applications, enabling you to collect telemetry data such as traces and metrics. Although Lumigo does not offer its own OpenTelemetry Distribution for Swift, you can still configure it. This guide explains how to set up OpenTelemetry Swift Instrumentation and configure it to report data to Lumigo.

Prerequisites

Before you begin, ensure you have the following:

  • Swift Package Manager (SPM): OpenTelemetry for Swift is distributed via SPM.
  • A Lumigo Token, which can be found in Settings > Tracing > Manual Tracing. For more details, see the Lumigo Tokens documentation.

Installation Steps

Install OpenTelemetry Swift Instrumentation and instrument your Erlang/Elixir application using the provided packages.

1. Add OpenTelemetry to Your Project

Add OpenTelemetry as a dependency in your project's Package.swift file:

// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "YourAppName",
    platforms: [
        .macOS(.v13),
        .iOS(.v16)
    ],
    dependencies: [
        .package(url: "https://github.com/open-telemetry/opentelemetry-swift.git", from: "1.0.0"),
        // Add other dependencies here
    ],
    targets: [
        .target(
            name: "YourAppName",
            dependencies: [
                .product(name: "OpenTelemetryApi", package: "opentelemetry-swift"),
                .product(name: "OpenTelemetrySdk", package: "opentelemetry-swift"),
                // Add other target dependencies here
            ],
            path: "Sources"
        )
    ]
)

Then run the following command to fetch the dependencies:

swift package update

2. Configuring the OpenTelemetry SDK

a. Import the required OpenTelemetry modules:

import OpenTelemetryApi
import OpenTelemetrySdk
import OpenTelemetryProtocolExporter

b. Set up the OpenTelemetry SDK with an appropriate exporter, such as the OTLP exporter:

import GRPC
import NIO

// Create an event loop group
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)

// Configure the OTLP exporter
let otlpConfiguration = OtlpConfiguration(timeout: OtlpConfiguration.DefaultTimeoutInterval)
let channel = ClientConnection.usingPlatformAppropriateTLS(for: group)
    .connect(host: "ga-otlp.lumigo-tracer-edge.golumigo.com", port: 443)
let traceExporter = OtlpTraceExporter(channel: channel, config: otlpConfiguration)

// Create a tracer provider with the exporter
let tracerProvider = TracerProviderBuilder()
    .add(spanProcessor: SimpleSpanProcessor(spanExporter: traceExporter))
    .build()

// Register the tracer provider
OpenTelemetry.registerTracerProvider(tracerProvider: tracerProvider)

3. Integrate Distributed Tracing

Tracing involves capturing information about the execution of operations in your application.

a. Obtain a tracer instance to create spans:

let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: "YourAppName", instrumentationVersion: "1.0")

b. Use the tracer to create spans that represent operations:

let span = tracer.spanBuilder(spanName: "operationName").startSpan()
span.setAttribute(key: "attributeKey", value: "attributeValue")
// Perform the operation
span.end()

Ensure that each span is properly ended to accurately represent the operation's duration.

4. Set Up Logging

Integrate basic logging:

import OpenTelemetryApi
import os.log

let logger = Logger(subsystem: "com.yourcompany.app", category: "networking")
let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: "YourApp", instrumentationVersion: "1.0")

let span = tracer.spanBuilder(spanName: "networkRequest").startSpan()
OpenTelemetry.instance.contextProvider.setActiveSpan(span)

logger.info("Starting network request with traceID: \(span.spanContext.traceId.description)")

// Simulate some operation
do {
    // Simulated success or failure
    logger.info("Network request successful")
} catch {
    logger.error("Network request failed: \(error.localizedDescription)")
}

span.end()