This project is a fork of the open-telemetry-swift (OTEL) reference implementation, which runs only on Apple operating systems (MacOS, iOS, tvOS, et al.). This port adds support for Linux distributions1. The official open-telemetry-swift project is restricted to Apple operating systems due to its dependency on several Apple-specific libraries; namely, os.log and os.activity. The latter is problematic for other platforms, in that it a) relies on Apple kernel support; b) is poorly documented; and c) has no publicly available source code. However, the original OTEL project has an open feature issue for Linux support, and it is our intention to submit a PR once we have confirmed this work's stability (assuming the authors are interested).
The reference implementation of open-telemetry-swift employs Apple's os.activity library to provide unique contexts for each tracing span created, obviating the need to pass around unique identifiers among code modules. The result is a proper collection of related spans that may be sent to various data collectors, and eventually data sources (eg. Tempo), and viewed via a metric application like Grafana.
Unfortunately, the os.activity library was intended for use by Apple developers when debugging code via logging; it is considered beta software and not intended for other applications (or operating systems). To affect similar behavior on Linux, this port employs Swift's new structured concurrency model; notably Tasks and TaskLocal variables. The open-telemetry-swift library has been adapted to use these Swift constructs internally, which avoids breaking the reference document and the client-visible API. Additionally, both the SDK and API code have been refactored to abstract the underlying operating systems, allowing the library and its clients to continue running within Apple environments, along with Linux.
This port has been tested on both Ubuntu 20.04 LTS and 22.04 LTS; arm64 and amd64 processors, along with regression tests on MacOS (arm64). Note that there is nothing Linux-distribution-specific about this port; thus, theoretically it should run on any Linux version supporting Swift 5.8 or newer.
Apart from the refactoring effort, the central changes for Linux occured within these source files:
- OpenTelemetry.swift: Refactored to support Swift structured concurrency.
- SpanBuilderSdk.swift: Small modifications to reflect changes to the API code base.
In addition, a number of other source files were slightly modified to work with the new abstractions. Also, some modules in OpenTelemetrySdk were originally written using os.log, requiring conditional compilation for them as well. We replaced the original os.log library with SwiftyBeaver, a very simple all-Swift logging package2
For Linux, we have addressed the absence of os.activity using Swift's structured concurrency model; in particular the use of TaskLocal variables and their withValue construct. All spans for every bound instance of the activeSpan variable will be properly collected and related; each separate task will have its own instance value of activeSpan.
To make our open-telemetry-swift port simpler to use by developers, we created the Observability library that provides a clean API for writing tracing blocks, and hiding the implementation details. See that repository's home page for documentation and usage examples.
Recently, we decided to integrate the behavior of open-telemetry-swift on MacOS with its Linux implementation. In other words, the code for both operating systems now employs structured concurrency. This eliminates all dependencies on os.activity and os.log for those platforms. Other Apple-specific devices (tvOS, watchOS, etc.) are ignored. The code specific to those things remains conditionally compiled in the open-telemetry-swift source code.
... is weird right now. The well-used Apple Swift logging package fails to build properly if referenced from within the OpenTelemetryApi code base, but compiles just fine from the SDK. The original authors have several TODO comments about logging from the API; for now we are using SwiftyBeaver, a very simple Swift logging package. This area will be revisited at some point.
- The open-telemetry-swift reference implementation.
- The PassiveLogic Observability library, a thin wrapper around the open-telemetry-swift API. This project is currently restricted to PassiveLogic personnel only. We may decide to Open Source this work to accompany our open-telemetry-swift port.