1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# Library Distribution
This document describes the considerations and recommendations for using the
OpenTelemetry-cpp library.
## Definitions
### Binary vs Source Distribution
The OpenTelemetry-cpp libraries (API and SDK) and any library that depends on
them are expected to be distributed as either "source" or "binary" artifacts.
This document defines these distribution models as:
* **Source** - The source code is shipped as-is and can be built as desired.
* **Binary** - The library and/or its dependants may be distributed as pre-built
binaries which can be built using different toolchains or compilers.
This document will focus on the specific challenges of the "binary" distribution
model.
### Library Binding Model
The library and its dependants can be distributed and bound (loaded) in multiple
ways which are defined as follows:
* **Static Linkage** - The library is distributed as a compiled artifact (`.a`
extension on Unix-like systems) which is linked and bound at compile-time.
* **Dynamic Linkage with Early Binding** - The library is distributed as a
compiled artifact (`.so` on Unix-like systems), and its binding is defined at
compile-time. It is loaded by the dynamic linker when the application/library
depending on it is started/loaded.
* **Dynamic Linkage with Late Binding** - The library is distributed as a
compiled artifact (`.so` on Unix-like systems), only its interface is known at
compile-time. It is loaded dynamically (using `dlopen` on POSIX).
_NOTE: A library may itself link in other libraries based on any of the above._
### Components
The following components will be considered for analysing the impact of
different binding models and the recommendations.
* **OpenTelemetry Libraries** - The libraries produced from this project, the
API library will contain a minimal implementation including some compiled
globals/singletons such as `TracerProvider`.
* **OpenTelemetry Instrumented Libraries** - A library that depends on the
OpenTelemetry API library to generate telemetry.
* **OpenTelemetry Implementations or Exporters** - A specific implementation of
the OpenTelemetry API or the `exporters` may be provided externally (e.g.
distributed by a vendor).
* **Binary Executable** - The compiled binary that has `main()`, this also
includes interpreters such as Python which will be considered. This binary may
itself instrument using OpenTelemetry or register a specific implementation.
For more information on language-agnostic library, please see: [OpenTelemetry
Specification Library
Guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/library-guidelines.md).
### ABI Compatibility
Some guarantees regarding binary compatibility will be necessary given the
binary distribution model supported by this project. The policies and approach
regarding this will be documented in [ABI Policy](abi-policy.md).
## Recommendations
### Link OpenTelemetry plugins for portability
If you're a vendor and you wish to distribute an OpenTelemetry plugin (either a
full implementation of the API or an exporter), you need to take precautions
when linking your plugin to ensure it's portable. Here are some steps you should
follow:
* Ensure you compile to target portable architectures (e.g. x86-64).
* Statically link most dependencies. You should statically both external
dependencies and the standard C++ library. The exceptions are the standard C
library and other low-level system libraries that need to be dynamically
linked.
* Use an export map to avoid unwanted symbol resolution. When statically linking
dependencies in a dynamic library, care should be taken to make sure that
symbol resolution for dependencies doesn't conflict with that of the app or
other dynamic libraries. See this [StackOverflow
post](https://stackoverflow.com/q/47841812/4447365) for more information.
* Re-map symbols from the standard C library to portable versions. If you want
to plugin to work on systems with different versions of the standard C
library, you need to link to portable symbols. See this [StackOverflow
answer](https://stackoverflow.com/a/20065096/4447365) for how to do this.
## Example Scenarios
### Statically compiled binary executable
Binary executable can be distributed with static linkage ,for all libraries
known at compile time. In this case the OpenTelemetry API Library can be linked
in statically, guaranteeing that only a single symbol is exported for
singletons.
### Dynamically linked binary executable
An application can link to the OpenTelemetry API but dynamically load an
implementation at runtime. Under this mode, an application can work with any
vendor's implementation by using it as a plugin.
For example, a C++ database server might add support for the OpenTelemetry API
and exposes configuration options that let a user point to a vendor's plugin and
load it with a JSON config. (With OpenTracing, Ceph explored a deployment
scenario similar to this. See this
[link](https://www.spinics.net/lists/ceph-devel/msg41007.html))
### Non OpenTelemetry aware application with OpenTelemetry capability library
An application itself may not be OpenTelemetry-aware, but it can support
OpenTelemetry via extensions.
Examples:
* The core NGINX application has no knowledge of tracing. However, through
NGINX's dynamic module capability, tracing can be supported as a plugin. For
instance, the [nginx-opentracing
module](https://github.com/opentracing-contrib/nginx-opentracing) provides
this type of extension and is used by projects such as Kubernete's [ingress
controller](https://kubernetes.github.io/ingress-nginx/user-guide/third-party-addons/opentracing/).
* The CPython binary also has no knowledge of OpenTelemetry, but C++ Python
extension modules can be instrumented for OpenTelemetry.
Additionally, when multiple OpenTelemetry-aware extensions co-exist in the same
application, the extensions should be able to coordinate and share context
through the OpenTelemetry API's singletons.
|