1559 changed files with 236288 additions and 140 deletions
@ -0,0 +1,41 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
# bazel configurations for running tests under sanitizers. |
||||
# Based on https://github.com/bazelment/trunk/blob/master/tools/bazel.rc |
||||
|
||||
# Enable automatic configs based on platform |
||||
common --enable_platform_specific_config |
||||
|
||||
# Make globs that don't match anything fail |
||||
common --incompatible_disallow_empty_glob |
||||
|
||||
# Needed by gRPC to build on some platforms. |
||||
build --copt -DGRPC_BAZEL_BUILD |
||||
|
||||
# Workaround abseil libraries missing symbols |
||||
build:windows --dynamic_mode=off |
||||
|
||||
# Set minimum supported C++ version |
||||
build:macos --host_cxxopt=-std=c++14 --cxxopt=-std=c++14 |
||||
build:linux --host_cxxopt=-std=c++14 --cxxopt=-std=c++14 |
||||
build:windows --host_cxxopt=/std:c++14 --cxxopt=/std:c++14 |
||||
|
||||
# --config=asan : Address Sanitizer. |
||||
common:asan --copt -DADDRESS_SANITIZER |
||||
common:asan --copt -fsanitize=address,bool,float-cast-overflow,integer-divide-by-zero,null,return,returns-nonnull-attribute,shift-exponent,signed-integer-overflow,unreachable,vla-bound |
||||
common:asan --copt -fsanitize-address-use-after-scope |
||||
common:asan --copt -fno-sanitize-recover=all |
||||
common:asan --linkopt -fsanitize=address,bool,float-cast-overflow,integer-divide-by-zero,null,return,returns-nonnull-attribute,shift-exponent,signed-integer-overflow,unreachable,vla-bound |
||||
common:asan --linkopt -fsanitize-address-use-after-scope |
||||
common:asan --linkopt -fno-sanitize-recover=all |
||||
common:asan --cc_output_directory_tag=asan |
||||
|
||||
# --config=tsan : Thread Sanitizer. |
||||
common:tsan --copt -fsanitize=thread |
||||
common:tsan --copt -DTHREAD_SANITIZER |
||||
common:tsan --linkopt -fsanitize=thread |
||||
common:tsan --cc_output_directory_tag=tsan |
||||
# This is needed to address false positive problem with abseil.The same setting as gRPC |
||||
# https://github.com/google/sanitizers/issues/953 |
||||
common:tsan --test_env=TSAN_OPTIONS=report_atomic_races=0 |
||||
@ -0,0 +1,73 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
# See Clang docs: http://clang.llvm.org/docs/ClangFormatStyleOptions.html |
||||
BasedOnStyle: Chromium |
||||
|
||||
# Allow double brackets such as std::vector<std::vector<int>>. |
||||
Standard: Cpp11 |
||||
|
||||
# Indent 2 spaces at a time. |
||||
IndentWidth: 2 |
||||
|
||||
# Keep lines under 100 columns long. |
||||
ColumnLimit: 100 |
||||
|
||||
# Always break before braces |
||||
BreakBeforeBraces: Custom |
||||
BraceWrapping: |
||||
# TODO(lujc) wait for clang-format-9 support in Chromium tools |
||||
# AfterCaseLabel: true |
||||
AfterClass: true |
||||
AfterControlStatement: true |
||||
AfterEnum: true |
||||
AfterFunction: true |
||||
AfterNamespace: true |
||||
AfterStruct: true |
||||
AfterUnion: true |
||||
BeforeCatch: true |
||||
BeforeElse: true |
||||
IndentBraces: false |
||||
SplitEmptyFunction: false |
||||
SplitEmptyRecord: false |
||||
SplitEmptyNamespace: false |
||||
|
||||
# Keeps extern "C" blocks unindented. |
||||
AfterExternBlock: false |
||||
|
||||
# Indent case labels. |
||||
IndentCaseLabels: true |
||||
|
||||
# Right-align pointers and references |
||||
PointerAlignment: Right |
||||
|
||||
# ANGLE likes to align things as much as possible. |
||||
AlignOperands: true |
||||
AlignConsecutiveAssignments: true |
||||
|
||||
# Use 2 space negative offset for access modifiers |
||||
AccessModifierOffset: -2 |
||||
|
||||
# TODO(jmadill): Decide if we want this on. Doesn't have an "all or none" mode. |
||||
AllowShortCaseLabelsOnASingleLine: false |
||||
|
||||
# Useful for spacing out functions in classes |
||||
KeepEmptyLinesAtTheStartOfBlocks: true |
||||
|
||||
# Indent nested PP directives. |
||||
IndentPPDirectives: AfterHash |
||||
|
||||
# Include blocks style |
||||
IncludeBlocks: Preserve |
||||
|
||||
AttributeMacros: |
||||
- OPENTELEMETRY_UNLIKELY |
||||
- OPENTELEMETRY_LIKELY |
||||
- OPENTELEMETRY_MAYBE_UNUSED |
||||
- OPENTELEMETRY_DEPRECATED |
||||
- OPENTELEMETRY_API_SINGLETON |
||||
- OPENTELEMETRY_LOCAL_SYMBOL |
||||
- OPENTELEMETRY_EXPORT |
||||
- OPENTELEMETRY_SANITIZER_NO_MEMORY |
||||
- OPENTELEMETRY_SANITIZER_NO_THREAD |
||||
- OPENTELEMETRY_SANITIZER_NO_ADDRESS |
||||
@ -0,0 +1,42 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
Checks: > |
||||
-*, |
||||
performance-*, |
||||
portability-*, |
||||
abseil-*, |
||||
-abseil-string-find-str-contains, |
||||
bugprone-*, |
||||
-bugprone-easily-swappable-parameters, |
||||
-bugprone-implicit-widening-of-multiplication-result, |
||||
-bugprone-inc-dec-in-conditions, |
||||
-bugprone-narrowing-conversions, |
||||
-bugprone-unchecked-optional-access, |
||||
-bugprone-unhandled-exception-at-new, |
||||
-bugprone-unused-local-non-trivial-variable, |
||||
google-*, |
||||
-google-build-using-namespace, |
||||
-google-default-arguments, |
||||
-google-explicit-constructor, |
||||
-google-readability-avoid-underscore-in-googletest-name, |
||||
-google-readability-braces-around-statements, |
||||
-google-readability-namespace-comments, |
||||
-google-readability-todo, |
||||
-google-runtime-references, |
||||
misc-*, |
||||
-misc-const-correctness, |
||||
-misc-include-cleaner, |
||||
-misc-non-private-member-variables-in-classes, |
||||
-misc-unused-alias-decls, |
||||
-misc-use-anonymous-namespace, |
||||
cppcoreguidelines-*, |
||||
-cppcoreguidelines-owning-memory, |
||||
-cppcoreguidelines-avoid-do-while, |
||||
-cppcoreguidelines-avoid-c-arrays, |
||||
-cppcoreguidelines-avoid-magic-numbers, |
||||
-cppcoreguidelines-init-variables, |
||||
-cppcoreguidelines-macro-usage, |
||||
-cppcoreguidelines-non-private-member-variables-in-classes, |
||||
-cppcoreguidelines-avoid-non-const-global-variables, |
||||
-cppcoreguidelines-pro-* |
||||
@ -0,0 +1,7 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
# If comment markup is enabled, don't reflow the first comment block in |
||||
# eachlistfile. Use this to preserve formatting of your |
||||
# copyright/licensestatements. |
||||
first_comment_is_literal = True |
||||
@ -0,0 +1,52 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
# Ignore the following directories |
||||
|
||||
./.git/* |
||||
./.github/* |
||||
./third_party/benchmark/* |
||||
./third_party/boost/* |
||||
./third_party/googletest/* |
||||
./third_party/ms-gsl/* |
||||
./third_party/nlohmann-json/* |
||||
./third_party/opentelemetry-proto/* |
||||
./third_party/prometheus-cpp/* |
||||
./tools/vcpkg/* |
||||
./tools/ports/* |
||||
|
||||
# Third party code |
||||
|
||||
./api/include/opentelemetry/nostd/internal/absl/* |
||||
./exporters/jaeger/thrift-gen/* |
||||
./exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h |
||||
|
||||
# Doc |
||||
|
||||
./docs/* |
||||
|
||||
## Ignore the following files patterns |
||||
|
||||
*.md |
||||
*.rst |
||||
*.png |
||||
*.log |
||||
*.patch |
||||
*.json |
||||
*.nuspec |
||||
*.pem |
||||
|
||||
# Packaging |
||||
*/CONTROL |
||||
|
||||
# LICENSE files |
||||
*/LICENSE |
||||
|
||||
# Ignore the following misc files |
||||
|
||||
./.bazelignore |
||||
./.bazelversion |
||||
./docker/.gitignore |
||||
.markdownlintignore |
||||
./ci/toc.yml |
||||
./ci/valgrind-suppressions |
||||
@ -0,0 +1,55 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
FROM ubuntu:24.04@sha256:1e622c5f073b4f6bfad6632f2616c7f59ef256e96fe78bf6a595d1dc4376ac02 |
||||
|
||||
RUN apt update && apt install -y \ |
||||
build-essential \ |
||||
ca-certificates \ |
||||
wget \ |
||||
cmake \ |
||||
git \ |
||||
sudo \ |
||||
nano \ |
||||
pkg-config \ |
||||
ninja-build \ |
||||
clang-format \ |
||||
clang-tidy \ |
||||
autoconf \ |
||||
automake \ |
||||
libtool \ |
||||
python3-pip |
||||
|
||||
RUN pip install "conan==2.15.1" --break-system-packages |
||||
|
||||
ARG USER_UID=1000 |
||||
ARG USER_GID=1000 |
||||
ARG USER_NAME=devuser |
||||
ENV USER_NAME=devuser |
||||
ENV USER_UID=${USER_UID} |
||||
ENV USER_GID=${USER_GID} |
||||
ENV INSTALL_PACKAGES= |
||||
ENV IS_CONTAINER_BUILD=true |
||||
|
||||
COPY ./.devcontainer/customize_container.sh /tmp/opentelemetry_cpp/devcontainer/customize_container.sh |
||||
RUN /tmp/opentelemetry_cpp/devcontainer/customize_container.sh |
||||
USER devuser |
||||
|
||||
RUN conan profile detect --force |
||||
|
||||
ARG CONAN_FILE=conanfile_stable.txt |
||||
ARG CONAN_BUILD_TYPE=Debug |
||||
ARG CXX_STANDARD=17 |
||||
WORKDIR /home/devuser/conan |
||||
COPY ./install/conan/ . |
||||
|
||||
RUN conan install ./${CONAN_FILE} --build=missing -s build_type=${CONAN_BUILD_TYPE} |
||||
ENV CMAKE_TOOLCHAIN_FILE=/home/devuser/conan/build/${CONAN_BUILD_TYPE}/generators/conan_toolchain.cmake |
||||
ENV CXX_STANDARD=${CXX_STANDARD} |
||||
ENV BUILD_TYPE=${CONAN_BUILD_TYPE} |
||||
ENV CONAN_FILE=${CONAN_FILE} |
||||
|
||||
WORKDIR /workspaces/opentelemetry-cpp |
||||
|
||||
ENTRYPOINT [] |
||||
|
||||
CMD ["/bin/bash"] |
||||
@ -0,0 +1,58 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
FROM otel/cpp_format_tools |
||||
|
||||
ARG USER_UID=1000 |
||||
ARG USER_GID=1000 |
||||
ARG INSTALL_PACKAGES= |
||||
|
||||
ARG CXX_STANDARD=17 |
||||
ARG CMAKE_VERSION=3.31.6 |
||||
ARG ABSEIL_CPP_VERSION=20230125.3 |
||||
ARG PROTOBUF_VERSION=23.3 |
||||
ARG GRPC_VERSION=v1.55.0 |
||||
|
||||
ENV CXX_STANDARD=${CXX_STANDARD} |
||||
ENV CMAKE_VERSION=${CMAKE_VERSION} |
||||
ENV ABSEIL_CPP_VERSION=${ABSEIL_CPP_VERSION} |
||||
ENV PROTOBUF_VERSION=${PROTOBUF_VERSION} |
||||
ENV GRPC_VERSION=${GRPC_VERSION} |
||||
|
||||
COPY ci /opt/ci |
||||
|
||||
RUN apt update && apt install -y wget \ |
||||
ninja-build \ |
||||
libcurl4-openssl-dev \ |
||||
clang-tidy \ |
||||
shellcheck |
||||
|
||||
RUN cd /opt/ci && bash setup_cmake.sh |
||||
RUN cd /opt/ci && bash setup_ci_environment.sh |
||||
RUN cd /opt && bash ci/setup_googletest.sh \ |
||||
&& bash ci/install_abseil.sh \ |
||||
&& bash ci/install_protobuf.sh \ |
||||
&& bash ci/setup_grpc.sh -r $GRPC_VERSION -s $CXX_STANDARD -p protobuf -p abseil-cpp |
||||
|
||||
ADD https://github.com/bazelbuild/bazelisk/releases/download/v1.22.1/bazelisk-linux-amd64 /usr/local/bin |
||||
|
||||
RUN git config --global core.autocrlf input \ |
||||
&& chmod +x /usr/local/bin/bazelisk-linux-amd64 |
||||
|
||||
ENV INSTALL_PACKAGES=${INSTALL_PACKAGES} |
||||
ENV USER_NAME=devuser |
||||
ENV USER_UID=${USER_UID} |
||||
ENV USER_GID=${USER_GID} |
||||
ENV IS_CONTAINER_BUILD=true |
||||
|
||||
COPY ./.devcontainer/customize_container.sh /tmp/opentelemetry_cpp/devcontainer/customize_container.sh |
||||
RUN /tmp/opentelemetry_cpp/devcontainer/customize_container.sh |
||||
RUN apt install -y npm && npm install -g markdownlint-cli@0.44.0 |
||||
|
||||
USER devuser |
||||
|
||||
WORKDIR /workspaces/opentelemetry-cpp |
||||
|
||||
ENTRYPOINT [] |
||||
|
||||
CMD ["/bin/bash"] |
||||
@ -0,0 +1,65 @@
|
||||
# Customizing Your Dev Container |
||||
|
||||
Customize your dev container using build arguments (for direct Docker builds) or |
||||
environment variables (for evaluation in `devcontainer.json`). |
||||
|
||||
* **CMake version:** |
||||
The version of cmake to install. (Default: 3.31.6) |
||||
* Docker ARG: |
||||
`CMAKE_VERSION` |
||||
* Host Environment Variable: |
||||
`OTEL_CPP_DEVCONTAINER_CMAKE_VERSION` |
||||
|
||||
* **CXX standard:** |
||||
This is the C++ standard to build from (eg: 17, 20, ...). (Default: 17) |
||||
* Docker ARG: |
||||
`CXX_STANDARD` |
||||
* Host Environment Variable: |
||||
`OTEL_CPP_DEVCONTAINER_CXX_STANDARD` |
||||
|
||||
* **abseil-cpp version:** |
||||
This is the version of abseil-cpp that will be used to build protobuf, gRPC, |
||||
and opentelemetry-cpp. |
||||
* Docker ARG: |
||||
`ABSEIL_CPP_VERSION` |
||||
* Host Environment Variable: |
||||
`OTEL_CPP_DEVCONTAINER_ABSEIL_CPP_VERSION` |
||||
|
||||
* **Protobuf version:** |
||||
* Docker ARG: |
||||
`PROTOBUF_VERSION` |
||||
* Host Environment Variable: |
||||
`OTEL_CPP_DEVCONTAINER_PROTOBUF_VERSION` |
||||
|
||||
* **gRPC version:** |
||||
* Docker ARG: |
||||
`GRPC_VERSION` |
||||
* Host Environment Variable: |
||||
`OTEL_CPP_DEVCONTAINER_GRPC_VERSION` |
||||
|
||||
* **User ID (UID):** |
||||
User ID (Default: `1000`) |
||||
* Docker ARG: |
||||
`USER_UID` |
||||
* Host Environment Variable: |
||||
`OTEL_CPP_DEVCONTAINER_USER_UID` |
||||
|
||||
* **Group ID (GID):** |
||||
User group ID (Default: `1000`) |
||||
* Docker ARG: |
||||
`USER_GID` |
||||
* Host Environment Variable: |
||||
`OTEL_CPP_DEVCONTAINER_USER_GID` |
||||
|
||||
* **Install Packages:** |
||||
These are the additional packages that will be installed via `apt install` in the devcontainer. This is a space separated list. |
||||
* Docker ARG: |
||||
`INSTALL_PACKAGES` (Default: ``) |
||||
* Host Environment Variable: |
||||
`OTEL_CPP_DEVCONTAINER_INSTALL_PACKAGES` (Default: ``) |
||||
|
||||
## Examples |
||||
|
||||
* `docker build --build-arg CXX_STANDARD="20" --build-arg INSTALL_PACKAGES="nano gitk"...` |
||||
* `export OTEL_CPP_DEVCONTAINER_CXX_STANDARD=20` |
||||
* `export OTEL_CPP_DEVCONTAINER_INSTALL_PACKAGES="nano gitk"` |
||||
@ -0,0 +1,39 @@
|
||||
#!/bin/bash |
||||
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
set -eu |
||||
|
||||
if [[ $IS_CONTAINER_BUILD != "true" ]]; then |
||||
echo "This script should only run inside a Docker container." |
||||
exit 1 |
||||
fi |
||||
|
||||
if [[ -n "$INSTALL_PACKAGES" ]]; then |
||||
packages=($INSTALL_PACKAGES) |
||||
for package in "${packages[@]}"; do |
||||
apt install -y "$package" |
||||
done |
||||
fi |
||||
|
||||
if [[ $(id "$USER_NAME" 2>/dev/null) ]]; then |
||||
echo "User '$USER_NAME' already exists. Removing it." |
||||
userdel -rf "$USER_NAME" |
||||
elif [[ $(id -u "$USER_UID" 2>/dev/null) ]]; then |
||||
OTHER_USER=$(getent passwd "$USER_UID" | cut -d: -f1) |
||||
echo "User '$OTHER_USER' exists with UID $USER_UID. Removing it." |
||||
userdel -rf "$OTHER_USER" |
||||
fi |
||||
|
||||
if [[ ! $(getent group "$USER_GID" 2>/dev/null) ]]; then |
||||
echo "Group '$USER_GID' does not exist. Adding it." |
||||
groupadd -g "$USER_GID" "$USER_NAME" |
||||
fi |
||||
|
||||
useradd -m -u "$USER_UID" -g "$USER_GID" -s /bin/bash "$USER_NAME" |
||||
echo "Created user '$USER_NAME' (UID: $USER_UID, GID: $USER_GID)." |
||||
|
||||
echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" | tee /etc/sudoers.d/"$USER_NAME" |
||||
|
||||
echo "User and group setup complete." |
||||
@ -0,0 +1,35 @@
|
||||
// Copyright The OpenTelemetry Authors |
||||
// SPDX-License-Identifier: Apache-2.0 |
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: |
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/javascript-node |
||||
{ |
||||
"name": "opentelemetry-cpp", |
||||
"build": { |
||||
"context": "..", |
||||
"dockerfile": "Dockerfile.dev", |
||||
"args": { |
||||
"USER_UID": "${localEnv:OTEL_CPP_DEVCONTAINER_USER_UID:1000}", |
||||
"USER_GID": "${localEnv:OTEL_CPP_DEVCONTAINER_USER_GID:1000}", |
||||
"INSTALL_PACKAGES": "${localEnv:OTEL_CPP_DEVCONTAINER_INSTALL_PACKAGES:}", |
||||
"CMAKE_VERSION": "${localEnv:OTEL_CPP_DEVCONTAINER_CMAKE_VERSION:3.31.6}", |
||||
"CXX_STANDARD": "${localEnv:OTEL_CPP_DEVCONTAINER_CXX_STANDARD:17}", |
||||
"GRPC_VERSION": "${localEnv:OTEL_CPP_DEVCONTAINER_GRPC_VERSION:v1.55.0}", |
||||
"PROTOBUF_VERSION": "${localEnv:OTEL_CPP_DEVCONTAINER_PROTOBUF_VERSION:23.3}", |
||||
"ABSEIL_CPP_VERSION":"${localEnv:OTEL_CPP_DEVCONTAINER_ABSEIL_CPP_VERSION:20230125.3}" |
||||
} |
||||
}, |
||||
"customizations": { |
||||
"vscode": { |
||||
"extensions": [ |
||||
"ms-vscode.cpptools", |
||||
"ms-azuretools.vscode-docker", |
||||
"ms-vscode.cpptools-extension-pack" |
||||
], |
||||
"settings": { |
||||
"terminal.integrated.shell.linux": "/bin/bash", |
||||
} |
||||
} |
||||
}, |
||||
|
||||
"remoteUser": "devuser" |
||||
} |
||||
@ -0,0 +1,47 @@
|
||||
##### Source code ##### |
||||
|
||||
## C++ and C source files |
||||
*.c text eol=lf diff=cpp |
||||
*.h text eol=lf diff=cpp |
||||
*.cc text eol=lf diff=cpp |
||||
*.cpp text eol=lf diff=cpp |
||||
*.cxx text eol=lf diff=cpp |
||||
*.hpp text eol=lf diff=cpp |
||||
|
||||
## Python scripts |
||||
*.py text eol=lf diff=python |
||||
|
||||
## Perl scripts/libraries/modules |
||||
*.perl text eol=lf diff=perl |
||||
*.pl text eol=lf diff=perl |
||||
*.pm text eol=lf diff=perl |
||||
|
||||
## Shell scripts |
||||
*.sh text eol=lf |
||||
*.bash text eol=lf |
||||
|
||||
## Windows batch and PowerShell scripts |
||||
*.bat text eol=crlf |
||||
*.cmd text eol=crlf |
||||
*.ps1 text eol=crlf |
||||
|
||||
##### Other file types ##### |
||||
|
||||
## Text files and documentation |
||||
*.txt text |
||||
README* text |
||||
INSTALL* text |
||||
LICENSE* text |
||||
|
||||
## Non-text documentation |
||||
*.html text diff=html |
||||
*.pdf binary |
||||
*.rtf binary |
||||
|
||||
## git files |
||||
.gitignore text eol=lf |
||||
.gitattributes text eol=lf |
||||
|
||||
## bazel files |
||||
WORKSPACE text eol=lf |
||||
BUILD text eol=lf |
||||
@ -0,0 +1,50 @@
|
||||
codecov: |
||||
require_ci_to_pass: false |
||||
max_report_age: off |
||||
|
||||
coverage: |
||||
precision: 2 |
||||
round: up |
||||
range: "80...100" |
||||
status: |
||||
project: |
||||
default: |
||||
informational: true |
||||
target: auto |
||||
threshold: 10% |
||||
patch: false |
||||
|
||||
parsers: |
||||
gcov: |
||||
branch_detection: |
||||
conditional: yes |
||||
loop: yes |
||||
method: no |
||||
macro: no |
||||
|
||||
comment: |
||||
layout: "reach,diff,flags,tree" |
||||
behavior: default |
||||
require_changes: false |
||||
|
||||
# Relative file path fixing. |
||||
# CI file paths must match Git file paths. |
||||
# This fix removes the "/home/runner/" prefix |
||||
# to coverage report file paths. |
||||
fixes: |
||||
- "/home/runner/::" |
||||
|
||||
ignore: |
||||
- "docs/**/*" |
||||
- "docker/**/*" |
||||
- "examples/**/*" |
||||
- "bazel/**/*" |
||||
- "cmake/**/*" |
||||
- "buildscripts/**/*" |
||||
- "third_party/**/*" |
||||
- "test_common/**/*" |
||||
- "tools/**/*" |
||||
- ".vscode/**/*" |
||||
- ".github/**/*" |
||||
- "**/test/**/*" |
||||
- "**.md" |
||||
@ -0,0 +1,8 @@
|
||||
# Code owners file. |
||||
# This file controls who is tagged for review for any given pull request. |
||||
|
||||
# For ETW exporter |
||||
exporters/etw/* @reyang @maxgolov @lalitb @ThomsonTan @open-telemetry/cpp-approvers |
||||
|
||||
# For anything not explicitly taken by someone else: |
||||
* @open-telemetry/cpp-approvers |
||||
@ -0,0 +1,19 @@
|
||||
--- |
||||
name: Bug Report |
||||
about: Create a report to help us improve |
||||
labels: bug |
||||
--- |
||||
|
||||
**Describe your environment** Describe any aspect of your environment relevant to the problem, including your platform, build system, version numbers of installed dependencies, etc. If you're reporting a problem with a specific version of a library in this repo, please check whether the problem has been fixed on main branch. |
||||
|
||||
**Steps to reproduce** |
||||
Describe exactly how to reproduce the error. Include a code sample if applicable. |
||||
|
||||
**What is the expected behavior?** |
||||
What did you expect to see? |
||||
|
||||
**What is the actual behavior?** |
||||
What did you see instead? |
||||
|
||||
**Additional context** |
||||
Add any other context about the problem here. |
||||
@ -0,0 +1,19 @@
|
||||
--- |
||||
name: Feature Request |
||||
about: Suggest an idea for this project |
||||
labels: feature-request |
||||
--- |
||||
|
||||
Before opening a feature request against this repo, consider whether the feature should/could be implemented in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first. |
||||
|
||||
**Is your feature request related to a problem?** |
||||
If so, provide a concise description of the problem. |
||||
|
||||
**Describe the solution you'd like** |
||||
What do you want to happen instead? What is the expected behavior? |
||||
|
||||
**Describe alternatives you've considered** |
||||
Which alternative solutions or features have you considered? |
||||
|
||||
**Additional context** |
||||
Add any other context about the feature request here. |
||||
@ -0,0 +1,13 @@
|
||||
version: 2 |
||||
updates: |
||||
- package-ecosystem: "github-actions" |
||||
directory: "/" |
||||
schedule: |
||||
interval: "daily" |
||||
labels: |
||||
- "GHA" |
||||
|
||||
- package-ecosystem: "devcontainers" |
||||
directory: "/" |
||||
schedule: |
||||
interval: daily |
||||
@ -0,0 +1,11 @@
|
||||
Fixes # (issue) |
||||
|
||||
## Changes |
||||
|
||||
Please provide a brief description of the changes here. |
||||
|
||||
For significant contributions please make sure you have completed the following items: |
||||
|
||||
* [ ] `CHANGELOG.md` updated for non-trivial changes |
||||
* [ ] Unit tests have been added |
||||
* [ ] Changes in public API reviewed |
||||
@ -0,0 +1,38 @@
|
||||
# Process |
||||
|
||||
This file documents local admin changes for opentelemetry-cpp, |
||||
per the community process: https://github.com/open-telemetry/community/blob/main/docs/how-to-configure-new-repository.md |
||||
|
||||
Please note that the EasyCLA check **MUST** stay **REQUIRED**, |
||||
it should never be disabled or bypassed, at the risk of tainting the repository. |
||||
|
||||
# Guidelines |
||||
|
||||
The best is to open a PR first that describes the change, |
||||
so it can be discussed during review (maybe it is not needed, |
||||
maybe there is an alternate solution, ...). |
||||
|
||||
The PR must add a log entry in this file, detailing: |
||||
|
||||
* the date the change is implemented |
||||
* what is changed exactly (which setting) |
||||
* a short rationale |
||||
|
||||
Admin changes are then applied only when the PR is merged. |
||||
|
||||
If for some reason a change is implemented in emergency, |
||||
before a PR can be discussed and merged, |
||||
a PR should still be prepared and pushed after the fact to |
||||
describe the settings changed. |
||||
|
||||
# Log of local changes |
||||
|
||||
## 2023-11-03 |
||||
|
||||
Created log file `.github/repository-settings.md`, since admin permissions are now granted to maintainers. |
||||
|
||||
See https://github.com/open-telemetry/community/issues/1727 |
||||
|
||||
No setting changed. |
||||
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
name: OpenTelemetry-cpp benchmarks |
||||
on: |
||||
push: |
||||
branches: |
||||
- main |
||||
|
||||
permissions: |
||||
contents: write |
||||
deployments: write |
||||
|
||||
jobs: |
||||
benchmark: |
||||
name: Run OpenTelemetry-cpp benchmarks |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Mount Bazel Cache |
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 |
||||
env: |
||||
cache-name: bazel_cache |
||||
with: |
||||
path: /home/runner/.cache/bazel |
||||
key: bazel_benchmark |
||||
- name: setup |
||||
run: | |
||||
sudo ./ci/setup_ci_environment.sh |
||||
sudo ./ci/install_bazelisk.sh |
||||
- name: Run benchmark |
||||
id: run_benchmarks |
||||
run: | |
||||
./ci/do_ci.sh bazel.benchmark |
||||
mkdir -p benchmarks |
||||
mv api-benchmark_result.json benchmarks |
||||
mv sdk-benchmark_result.json benchmarks |
||||
mv exporters-benchmark_result.json benchmarks |
||||
- uses: actions/upload-artifact@6027e3dd177782cd8ab9af838c04fd81a07f1d47 # main March 2025 |
||||
with: |
||||
name: benchmark_results |
||||
path: benchmarks |
||||
store_benchmark: |
||||
needs: benchmark |
||||
strategy: |
||||
matrix: |
||||
components: ["api", "sdk", "exporters"] |
||||
name: Store benchmark result |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # main March 2025 |
||||
with: |
||||
name: benchmark_results |
||||
path: benchmarks |
||||
- name: Print json files |
||||
id: print_json |
||||
run: | |
||||
cat benchmarks/* |
||||
- name: Push benchmark result |
||||
uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4 |
||||
with: |
||||
name: OpenTelemetry-cpp ${{ matrix.components }} Benchmark |
||||
tool: 'googlecpp' |
||||
output-file-path: benchmarks/${{ matrix.components }}-benchmark_result.json |
||||
github-token: ${{ secrets.GITHUB_TOKEN }} |
||||
auto-push: true |
||||
# Show alert with commit comment on detecting possible performance regression |
||||
alert-threshold: '200%' |
||||
comment-on-alert: true |
||||
fail-on-alert: false |
||||
gh-pages-branch: gh-pages |
||||
benchmark-data-dir-path: benchmarks |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,89 @@
|
||||
name: clang-tidy |
||||
|
||||
on: |
||||
push: |
||||
branches: [main] |
||||
pull_request: |
||||
branches: [main] |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
clang-tidy: |
||||
runs-on: ubuntu-24.04 |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: recursive |
||||
|
||||
- name: Setup Environment |
||||
env: |
||||
PROTOBUF_VERSION: '23.3' |
||||
ABSEIL_CPP_VERSION: '20230125.3' |
||||
CXX_STANDARD: '14' |
||||
run: | |
||||
sudo apt update -y |
||||
sudo apt install -y --no-install-recommends --no-install-suggests \ |
||||
build-essential \ |
||||
iwyu \ |
||||
cmake \ |
||||
libssl-dev \ |
||||
libcurl4-openssl-dev \ |
||||
libprotobuf-dev \ |
||||
protobuf-compiler \ |
||||
libgmock-dev \ |
||||
libgtest-dev \ |
||||
libbenchmark-dev |
||||
|
||||
if ! command -v clang-tidy &> /dev/null; then |
||||
echo "clang-tidy could not be found" |
||||
exit 1 |
||||
fi |
||||
echo "Using clang-tidy version: $(clang-tidy --version)" |
||||
echo "clang-tidy installed at: $(which clang-tidy)" |
||||
|
||||
|
||||
- name: Prepare CMake |
||||
env: |
||||
CC: clang |
||||
CXX: clang++ |
||||
run: | |
||||
echo "Running cmake..." |
||||
cmake -B build \ |
||||
-DCMAKE_CXX_STANDARD=14 \ |
||||
-DWITH_STL=CXX14 \ |
||||
-DWITH_OTLP_HTTP=ON \ |
||||
-DWITH_OTLP_FILE=ON \ |
||||
-DWITH_PROMETHEUS=ON \ |
||||
-DWITH_ZIPKIN=ON \ |
||||
-DWITH_ELASTICSEARCH=ON \ |
||||
-DWITH_OTLP_HTTP_COMPRESSION=ON \ |
||||
-DWITH_EXAMPLES=ON \ |
||||
-DWITH_EXAMPLES_HTTP=ON \ |
||||
-DBUILD_W3CTRACECONTEXT_TEST=ON \ |
||||
-DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ |
||||
-DWITH_ASYNC_EXPORT_PREVIEW=ON \ |
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON |
||||
|
||||
- name: Run clang-tidy |
||||
run: | |
||||
cmake --build build --target opentelemetry_proto |
||||
jq -r .[].file build/compile_commands.json | grep -vE '/(generated|third_party)/' | xargs -P $(nproc) -n 1 clang-tidy --quiet -p build 2>&1 | tee -a clang-tidy.log |
||||
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 |
||||
with: |
||||
name: Logs (clang-tidy) |
||||
path: ./clang-tidy.log |
||||
|
||||
- name: Count warnings |
||||
run: | |
||||
COUNT=$(grep -c "warning:" clang-tidy.log) |
||||
echo "clang-tidy reported ${COUNT} warning(s)" |
||||
|
||||
# TODO: include WITH_OTLP_GRPC flags. |
||||
@ -0,0 +1,372 @@
|
||||
name: CMake Install Tests |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
push: |
||||
branches: [ main ] |
||||
pull_request: |
||||
branches: [ main ] |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
windows_2022_vcpkg_submodule: |
||||
name: Windows 2022 vcpkg submodule versions cxx17 (static libs - dll) |
||||
runs-on: windows-2022 |
||||
env: |
||||
# Set to the latest version of cmake 3.x |
||||
CMAKE_VERSION: '3.31.6' |
||||
# cxx17 is the default for windows-2022 |
||||
CXX_STANDARD: '17' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Build dependencies with vcpkg submodule |
||||
run: | |
||||
./ci/setup_cmake.ps1 |
||||
./ci/setup_windows_ci_environment.ps1 |
||||
- name: Run Tests |
||||
run: ./ci/do_ci.ps1 cmake.install.test |
||||
- name: Run DLL Tests |
||||
run: ./ci/do_ci.ps1 cmake.dll.install.test |
||||
|
||||
windows_2019_vcpkg_submodule_min_cmake: |
||||
name: Windows 2019 vcpkg submodule versions minimum cmake cxx14 (static libs) |
||||
runs-on: windows-2019 |
||||
env: |
||||
# cmake 3.15 is the minimum for windows builds (See https://github.com/open-telemetry/opentelemetry-cpp/pull/3349#discussion_r2030319430) |
||||
CMAKE_VERSION: '3.15.0' |
||||
# cxx14 is the default for windows-2019 |
||||
CXX_STANDARD: '14' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Build dependencies with vcpkg submodule |
||||
run: | |
||||
./ci/setup_cmake.ps1 |
||||
./ci/setup_windows_ci_environment.ps1 |
||||
- name: Run Tests |
||||
run: ./ci/do_ci.ps1 cmake.install.test |
||||
|
||||
ubuntu_2404_system_packages: |
||||
name: Ubuntu 24.04 apt packages cxx17 (static libs - shared libs) |
||||
runs-on: ubuntu-24.04 |
||||
env: |
||||
INSTALL_TEST_DIR: '/home/runner/install_test' |
||||
# CMake 3.28 is apt package version for Ubuntu 24.04 |
||||
CMAKE_VERSION: '3.28.3' |
||||
# cxx17 is the default for Ubuntu 24.04 |
||||
CXX_STANDARD: '17' |
||||
BUILD_TYPE: 'Debug' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Install libcurl, zlib, nlohmann-json with apt |
||||
run: | |
||||
sudo -E ./ci/setup_ci_environment.sh |
||||
sudo -E ./ci/setup_cmake.sh |
||||
sudo -E ./ci/setup_googletest.sh |
||||
- name: Install abseil, protobuf, and grpc with apt |
||||
run: | |
||||
sudo -E apt-get update |
||||
sudo -E apt-get install -y libabsl-dev libprotobuf-dev libgrpc++-dev protobuf-compiler protobuf-compiler-grpc |
||||
- name: Run Tests (static libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'OFF' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
- name: Run Tests (shared libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'ON' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
|
||||
ubuntu_2404_latest: |
||||
name: Ubuntu 24.04 latest versions cxx20 (static libs) |
||||
runs-on: ubuntu-24.04 |
||||
env: |
||||
INSTALL_TEST_DIR: '/home/runner/install_test' |
||||
# Set to the latest version of cmake 3.x |
||||
CMAKE_VERSION: '3.31.6' |
||||
# Set to the latest cxx standard supported by opentelemetry-cpp |
||||
CXX_STANDARD: '20' |
||||
# Versions below set to the latest version available |
||||
# The abseil and protobuf versions are taken from |
||||
# the grpc submodules at the GRPC_VERSION tag |
||||
GOOGLETEST_VERSION: '1.16.0' |
||||
ABSEIL_CPP_VERSION: '20240722.1' |
||||
PROTOBUF_VERSION: '29.0' |
||||
GRPC_VERSION: 'v1.71.0' |
||||
BUILD_TYPE: 'Debug' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Install gtest, libcurl, zlib, nlohmann-json with apt |
||||
run: | |
||||
sudo -E ./ci/setup_ci_environment.sh |
||||
sudo -E ./ci/setup_cmake.sh |
||||
sudo -E ./ci/setup_googletest.sh |
||||
- name: Build abseil, protobuf, and grpc with ci scripts |
||||
run: | |
||||
sudo -E ./ci/install_abseil.sh |
||||
sudo -E ./ci/install_protobuf.sh |
||||
sudo -E ./ci/setup_grpc.sh -r $GRPC_VERSION -s $CXX_STANDARD -p protobuf -p abseil-cpp |
||||
- name: Run Tests (static libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'OFF' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
|
||||
ubuntu_2204_stable: |
||||
name: Ubuntu 22.04 stable versions cxx17 (static libs - shared libs) |
||||
runs-on: ubuntu-22.04 |
||||
env: |
||||
INSTALL_TEST_DIR: '/home/runner/install_test' |
||||
# CMake 3.22 is the apt package version for Ubuntu 22.04 |
||||
CMAKE_VERSION: '3.22.0' |
||||
CXX_STANDARD: '17' |
||||
# These are stable versions tested in the main ci workflow |
||||
# and defaults in the devcontainer |
||||
GOOGLETEST_VERSION: '1.14.0' |
||||
ABSEIL_CPP_VERSION: '20230125.3' |
||||
PROTOBUF_VERSION: '23.3' |
||||
GRPC_VERSION: 'v1.55.0' |
||||
BUILD_TYPE: 'Debug' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Install gtest, libcurl, zlib, nlohmann-json with apt |
||||
run: | |
||||
sudo -E ./ci/setup_ci_environment.sh |
||||
sudo -E ./ci/setup_cmake.sh |
||||
sudo -E ./ci/setup_googletest.sh |
||||
- name: Build abseil, protobuf, and grpc with ci scripts |
||||
run: | |
||||
sudo -E ./ci/install_abseil.sh |
||||
sudo -E ./ci/install_protobuf.sh |
||||
sudo -E ./ci/setup_grpc.sh -r $GRPC_VERSION -s $CXX_STANDARD -p protobuf -p abseil-cpp |
||||
- name: Run Tests (static libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'OFF' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
- name: Run Tests (shared libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'ON' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
|
||||
ubuntu_2204_minimum: |
||||
name: Ubuntu 22.04 minimum versions cxx14 (static libs - shared libs) |
||||
runs-on: ubuntu-22.04 |
||||
env: |
||||
INSTALL_TEST_DIR: '/home/runner/install_test' |
||||
# Set to the current minimum version of cmake |
||||
CMAKE_VERSION: '3.14.0' |
||||
# cxx14 is the default for Ubuntu 22.04 |
||||
CXX_STANDARD: '14' |
||||
# This is the apt package version of googletest for Ubuntu 22.04 |
||||
GOOGLETEST_VERSION: '1.11.0' |
||||
# These are minimum versions tested in the main ci workflow |
||||
ABSEIL_CPP_VERSION: '20220623.2' |
||||
PROTOBUF_VERSION: '21.12' |
||||
GRPC_VERSION: 'v1.49.2' |
||||
BUILD_TYPE: 'Debug' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Install gtest, libcurl, zlib, nlohmann-json with apt |
||||
run: | |
||||
sudo -E ./ci/setup_ci_environment.sh |
||||
sudo -E ./ci/setup_cmake.sh |
||||
sudo -E ./ci/setup_googletest.sh |
||||
- name: Build abseil, protobuf, and grpc with ci scripts |
||||
run: | |
||||
sudo -E ./ci/install_abseil.sh |
||||
sudo -E ./ci/install_protobuf.sh |
||||
sudo -E ./ci/setup_grpc.sh -r $GRPC_VERSION -s $CXX_STANDARD -p protobuf -p abseil-cpp |
||||
- name: Run Tests (static libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'OFF' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
- name: Run Tests (shared libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'ON' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
|
||||
ubuntu_2404_conan_stable: |
||||
name: Ubuntu 24.04 conan stable versions cxx17 (static libs - shared libs - opentracing shim) |
||||
runs-on: ubuntu-24.04 |
||||
env: |
||||
INSTALL_TEST_DIR: '/home/runner/install_test' |
||||
# CMake 3.28 is apt package version for Ubuntu 24.04 |
||||
CMAKE_VERSION: '3.28.3' |
||||
CXX_STANDARD: '17' |
||||
CMAKE_TOOLCHAIN_FILE: /home/runner/conan/build/Debug/generators/conan_toolchain.cmake |
||||
BUILD_TYPE: 'Debug' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Install Conan |
||||
run: | |
||||
python3 -m pip install pip==25.0.1 |
||||
pip install "conan==2.15.1" |
||||
conan profile detect --force |
||||
- name: Install or build all dependencies with Conan |
||||
run: | |
||||
sudo -E ./ci/setup_cmake.sh |
||||
conan install install/conan/conanfile_stable.txt --build=missing -of /home/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD} |
||||
- name: Run Tests (static libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'OFF' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
- name: Run Tests (shared libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'ON' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
- name: verify pkgconfig packages |
||||
run: | |
||||
export PKG_CONFIG_PATH=$INSTALL_TEST_DIR/lib/pkgconfig:$PKG_CONFIG_PATH |
||||
./ci/verify_packages.sh |
||||
- name: Run OpenTracing Shim Test |
||||
run: ./ci/do_ci.sh cmake.opentracing_shim.install.test |
||||
|
||||
ubuntu_2404_conan_latest: |
||||
name: Ubuntu 24.04 conan latest versions cxx17 (static libs) |
||||
runs-on: ubuntu-24.04 |
||||
env: |
||||
INSTALL_TEST_DIR: '/home/runner/install_test' |
||||
# Set to the latest version of cmake 3.x |
||||
CMAKE_VERSION: '3.31.6' |
||||
CXX_STANDARD: '17' |
||||
CMAKE_TOOLCHAIN_FILE: /home/runner/conan/build/Debug/generators/conan_toolchain.cmake |
||||
BUILD_TYPE: 'Debug' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Install Conan |
||||
run: | |
||||
python3 -m pip install pip==25.0.1 |
||||
pip install "conan==2.15.1" |
||||
conan profile detect --force |
||||
- name: Install or build all dependencies with Conan |
||||
run: | |
||||
sudo -E ./ci/setup_cmake.sh |
||||
conan install install/conan/conanfile_latest.txt --build=missing -of /home/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD} |
||||
- name: Run Tests (static libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'OFF' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
- name: verify pkgconfig packages |
||||
run: | |
||||
export PKG_CONFIG_PATH=$INSTALL_TEST_DIR/lib/pkgconfig:$PKG_CONFIG_PATH |
||||
./ci/verify_packages.sh |
||||
|
||||
macos_14_conan_stable: |
||||
name: macOS 14 conan stable versions cxx17 (static libs) |
||||
runs-on: macos-14 |
||||
env: |
||||
INSTALL_TEST_DIR: '/Users/runner/install_test' |
||||
CMAKE_VERSION: '3.28.3' |
||||
CXX_STANDARD: '17' |
||||
CMAKE_TOOLCHAIN_FILE: '/Users/runner/conan/build/Debug/generators/conan_toolchain.cmake' |
||||
BUILD_TYPE: 'Debug' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Install Conan and tools |
||||
run: | |
||||
brew install conan autoconf automake libtool coreutils |
||||
./ci/setup_cmake_macos.sh |
||||
conan profile detect --force |
||||
- name: Install or build all dependencies with Conan |
||||
run: conan install install/conan/conanfile_stable.txt --build=missing -of /Users/runner/conan -s build_type=${BUILD_TYPE} -s compiler.cppstd=${CXX_STANDARD} |
||||
- name: Run Tests (static libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'OFF' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
|
||||
macos_14_brew_packages: |
||||
name: macOS 14 brew latest versions cxx17 (static libs) |
||||
runs-on: macos-14 |
||||
env: |
||||
INSTALL_TEST_DIR: '/Users/runner/install_test' |
||||
# Set to the latest version of cmake 3.x |
||||
CMAKE_VERSION: '3.31.6' |
||||
CXX_STANDARD: '17' |
||||
BUILD_TYPE: 'Debug' |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Install Dependencies with Homebrew |
||||
run: | |
||||
./ci/setup_cmake_macos.sh |
||||
brew install coreutils |
||||
brew install googletest |
||||
brew install google-benchmark |
||||
brew install zlib |
||||
brew install abseil |
||||
brew install protobuf |
||||
brew install grpc |
||||
brew install nlohmann-json |
||||
brew install prometheus-cpp |
||||
- name: Run Tests (static libs) |
||||
env: |
||||
BUILD_SHARED_LIBS: 'OFF' |
||||
run: ./ci/do_ci.sh cmake.install.test |
||||
@ -0,0 +1,48 @@
|
||||
name: "CodeQL" |
||||
|
||||
on: |
||||
push: |
||||
branches: [main] |
||||
pull_request: |
||||
# The branches below must be a subset of the branches above |
||||
branches: [main] |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
CodeQL-Build: |
||||
permissions: |
||||
actions: read # for github/codeql-action/init to get workflow details |
||||
contents: read # for actions/checkout to fetch code |
||||
security-events: write # for github/codeql-action/autobuild to send a status report |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- name: Checkout repository |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
- name: Remove Third_party Modules from Code Scan |
||||
run: | |
||||
rm -rf third_party |
||||
- name: Setup |
||||
env: |
||||
CC: /usr/bin/gcc-12 |
||||
CXX: /usr/bin/g++-12 |
||||
GOOGLETEST_VERSION: 1.12.1 |
||||
run: | |
||||
sudo -E ./ci/setup_googletest.sh |
||||
sudo -E ./ci/setup_ci_environment.sh |
||||
- name: Initialize CodeQL |
||||
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 |
||||
with: |
||||
languages: cpp |
||||
- name: Autobuild |
||||
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 |
||||
- name: Perform CodeQL Analysis |
||||
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 |
||||
@ -0,0 +1,77 @@
|
||||
|
||||
name: cppcheck |
||||
|
||||
on: |
||||
push: |
||||
branches: [ main ] |
||||
pull_request: |
||||
branches: [ main ] |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
cppcheck: |
||||
runs-on: ubuntu-24.04 |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
|
||||
- name: Set up dependencies |
||||
run: | |
||||
sudo apt update -y |
||||
sudo apt install -y cppcheck |
||||
|
||||
- name: Run cppcheck |
||||
run: | |
||||
cppcheck --version | tee cppcheck.log |
||||
cppcheck \ |
||||
--force \ |
||||
--enable=warning,performance,portability \ |
||||
--inline-suppr \ |
||||
--suppress=unknownMacro:exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h \ |
||||
--language=c++ \ |
||||
--std=c++14 \ |
||||
-I api/include \ |
||||
-I exporters/elasticsearch/include \ |
||||
-I exporters/etw/include \ |
||||
-I exporters/memory/include \ |
||||
-I exporters/ostream/include \ |
||||
-I exporters/otlp/include \ |
||||
-I exporters/prometheus/include \ |
||||
-I exporters/zipkin/include \ |
||||
-I ext/include \ |
||||
-I opentracing-shim/include \ |
||||
-I sdk/include \ |
||||
-i build \ |
||||
-i test \ |
||||
-i third_party \ |
||||
-j $(nproc) \ |
||||
. 2>&1 | tee --append cppcheck.log |
||||
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 |
||||
if: success() || failure() |
||||
with: |
||||
name: Logs (cppcheck) |
||||
path: ./cppcheck.log |
||||
|
||||
- name: Count warnings |
||||
run: | |
||||
set +e |
||||
readonly WARNING_COUNT=`grep -c -E "\[.+\]" cppcheck.log` |
||||
echo "cppcheck reported ${WARNING_COUNT} warning(s)" |
||||
# Acceptable limit, to decrease over time down to 0 |
||||
readonly WARNING_LIMIT=10 |
||||
# FAIL the build if WARNING_COUNT > WARNING_LIMIT |
||||
if [ $WARNING_COUNT -gt $WARNING_LIMIT ] ; then |
||||
exit 1 |
||||
# WARN in annotations if WARNING_COUNT > 0 |
||||
elif [ $WARNING_COUNT -gt 0 ] ; then |
||||
echo "::warning::cppcheck reported ${WARNING_COUNT} warning(s)" |
||||
fi |
||||
@ -0,0 +1,54 @@
|
||||
name: 'OpenTelemetry-cpp dependencies image' |
||||
on: |
||||
schedule: |
||||
- cron: "0 3 * * 6" |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
docker_image: |
||||
name: Docker Image |
||||
runs-on: ubuntu-latest |
||||
timeout-minutes: 300 |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- |
||||
name: checkout |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
- |
||||
name: Set up QEMU |
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 |
||||
- |
||||
name: Set up Docker Buildx |
||||
id: buildx |
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 |
||||
- |
||||
name: Build Image |
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 |
||||
with: |
||||
builder: ${{ steps.buildx.outputs.name }} |
||||
context: ci/ |
||||
file: ./docker/Dockerfile |
||||
build-args: BASE_IMAGE=ubuntu:latest |
||||
platforms: linux/amd64 |
||||
# platforms: linux/amd64,linux/arm64 |
||||
push: false |
||||
tags: otel-cpp-deps |
||||
load: true |
||||
- |
||||
name: Save Image |
||||
run: | |
||||
docker images |
||||
docker save -o /opt/otel-cpp-deps-debian.tar otel-cpp-deps |
||||
- |
||||
name: Upload Image |
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 |
||||
with: |
||||
name: otel-cpp-deps |
||||
path: /opt/otel-cpp-deps-debian.tar |
||||
retention-days: 14 |
||||
@ -0,0 +1,25 @@
|
||||
name: FOSSA scanning |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- main |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
fossa: |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
|
||||
- uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0 |
||||
with: |
||||
api-key: ${{secrets.FOSSA_API_KEY}} |
||||
team: OpenTelemetry |
||||
@ -0,0 +1,92 @@
|
||||
|
||||
name: include-what-you-use |
||||
|
||||
on: |
||||
push: |
||||
branches: [ main ] |
||||
pull_request: |
||||
branches: [ main ] |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
iwyu: |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
submodules: 'recursive' |
||||
|
||||
- name: setup dependencies |
||||
run: | |
||||
sudo apt update -y |
||||
sudo apt install -y --no-install-recommends --no-install-suggests \ |
||||
build-essential \ |
||||
iwyu \ |
||||
ninja-build \ |
||||
libssl-dev \ |
||||
libcurl4-openssl-dev \ |
||||
libprotobuf-dev \ |
||||
protobuf-compiler \ |
||||
libgmock-dev \ |
||||
libgtest-dev \ |
||||
libbenchmark-dev |
||||
sudo ./ci/setup_cmake.sh |
||||
|
||||
|
||||
- name: setup grpc |
||||
run: | |
||||
sudo ./ci/setup_grpc.sh |
||||
|
||||
- name: Prepare CMake |
||||
run: | |
||||
TOPDIR=`pwd` |
||||
mkdir build && cd build |
||||
CC="clang" CXX="clang++" cmake \ |
||||
-DCMAKE_CXX_STANDARD=14 \ |
||||
-DWITH_STL=CXX14 \ |
||||
-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE="include-what-you-use;-w;-Xiwyu;--mapping_file=${TOPDIR}/.iwyu.imp;" \ |
||||
-DBUILD_TESTING=ON \ |
||||
-DBUILD_W3CTRACECONTEXT_TEST=ON \ |
||||
-DWITH_OTLP_GRPC=ON \ |
||||
-DWITH_OTLP_HTTP=ON \ |
||||
-DWITH_OTLP_FILE=ON \ |
||||
-DWITH_OPENTRACING=ON \ |
||||
-DWITH_OTLP_HTTP_COMPRESSION=ON \ |
||||
-DWITH_THREAD_INSTRUMENTATION=ON \ |
||||
-DWITH_ZIPKIN=ON \ |
||||
-DWITH_PROMETHEUS=ON \ |
||||
.. |
||||
|
||||
- name: iwyu_tool |
||||
run: | |
||||
cd build |
||||
make -k 2>&1 | tee -a iwyu.log |
||||
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 |
||||
if: success() || failure() |
||||
with: |
||||
name: Logs (include-what-you-use) |
||||
path: ./build/*.log |
||||
|
||||
- name: count warnings |
||||
run: | |
||||
set +e |
||||
cd build |
||||
readonly WARNING_COUNT=`grep -c "include-what-you-use reported diagnostics:" iwyu.log` |
||||
echo "include-what-you-use reported ${WARNING_COUNT} warning(s)" |
||||
# Acceptable limit, to decrease over time down to 0 |
||||
readonly WARNING_LIMIT=0 |
||||
# FAIL the build if WARNING_COUNT > WARNING_LIMIT |
||||
if [ $WARNING_COUNT -gt $WARNING_LIMIT ] ; then |
||||
exit 1 |
||||
# WARN in annotations if WARNING_COUNT > 0 |
||||
elif [ $WARNING_COUNT -gt 0 ] ; then |
||||
echo "::warning::include-what-you-use reported ${WARNING_COUNT} warning(s)" |
||||
fi |
||||
@ -0,0 +1,52 @@
|
||||
name: OSSF Scorecard |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- main |
||||
schedule: |
||||
- cron: "56 23 * * 6" # once a week |
||||
workflow_dispatch: |
||||
|
||||
permissions: read-all |
||||
|
||||
jobs: |
||||
analysis: |
||||
runs-on: ubuntu-latest |
||||
permissions: |
||||
# Needed for Code scanning upload |
||||
security-events: write |
||||
# Needed for GitHub OIDC token if publish_results is true |
||||
id-token: write |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
||||
with: |
||||
persist-credentials: false |
||||
|
||||
- uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 |
||||
with: |
||||
results_file: results.sarif |
||||
results_format: sarif |
||||
publish_results: true |
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable |
||||
# uploads of run results in SARIF format to the repository Actions tab. |
||||
# https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts |
||||
- name: "Upload artifact" |
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 |
||||
with: |
||||
name: SARIF file |
||||
path: results.sarif |
||||
retention-days: 5 |
||||
|
||||
# Upload the results to GitHub's code scanning dashboard (optional). |
||||
# Commenting out will disable upload of results to your repo's Code Scanning dashboard |
||||
- name: "Upload to code-scanning" |
||||
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 |
||||
with: |
||||
sarif_file: results.sarif |
||||
@ -0,0 +1,28 @@
|
||||
|
||||
name: Add comment |
||||
on: |
||||
issues: |
||||
types: |
||||
- labeled |
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
add-comment: |
||||
if: github.event.label.name == 'help wanted' |
||||
runs-on: ubuntu-latest |
||||
permissions: |
||||
issues: write |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- name: Add comment |
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 |
||||
with: |
||||
issue-number: ${{ github.event.issue.number }} |
||||
body: | |
||||
This issue is available for anyone to work on. **Make sure to reference this issue in your pull request.** |
||||
:sparkles: Thank you for your contribution! :sparkles: |
||||
@ -0,0 +1,29 @@
|
||||
name: OpenTelemetry-cpp project |
||||
on: |
||||
issues: |
||||
types: |
||||
- reopened |
||||
- opened |
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
label_issues: |
||||
runs-on: ubuntu-latest |
||||
permissions: |
||||
issues: write |
||||
steps: |
||||
- name: Harden the runner (Audit all outbound calls) |
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 |
||||
with: |
||||
egress-policy: audit |
||||
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 |
||||
with: |
||||
script: | |
||||
github.rest.issues.addLabels({ |
||||
issue_number: context.issue.number, |
||||
owner: context.repo.owner, |
||||
repo: context.repo.repo, |
||||
labels: ["needs-triage"] |
||||
}) |
||||
@ -0,0 +1,21 @@
|
||||
name: "Mark stale issues" |
||||
on: |
||||
schedule: |
||||
- cron: "30 1 * * *" |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
stale: |
||||
permissions: |
||||
issues: write # for actions/stale to close stale issues |
||||
pull-requests: write # for actions/stale to close stale PRs |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 |
||||
with: |
||||
stale-issue-message: "This issue was marked as stale due to lack of activity." |
||||
days-before-issue-stale: 60 |
||||
days-before-close: -1 |
||||
exempt-issue-labels: "do-not-stale" |
||||
@ -0,0 +1,84 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
# Ref. https://github.com/github/gitignore/blob/master/C%2B%2B.gitignore |
||||
# Prerequisites |
||||
*.d |
||||
|
||||
# Compiled Object files |
||||
*.slo |
||||
*.lo |
||||
*.o |
||||
*.obj |
||||
|
||||
# Precompiled Headers |
||||
*.gch |
||||
*.pch |
||||
|
||||
# Compiled Dynamic libraries |
||||
*.so |
||||
*.dylib |
||||
*.dll |
||||
*.pdb |
||||
|
||||
# Fortran module files |
||||
*.mod |
||||
*.smod |
||||
|
||||
# Compiled Static libraries |
||||
*.lai |
||||
*.la |
||||
*.a |
||||
*.lib |
||||
|
||||
# Executables |
||||
*.exe |
||||
*.out |
||||
*.app |
||||
|
||||
# Bazel files |
||||
MODULE.bazel.lock |
||||
/bazel-* |
||||
|
||||
# Mac |
||||
.DS_Store |
||||
|
||||
# Output directories |
||||
/out |
||||
/out.* |
||||
# Indicator that the tools were deployed |
||||
.buildtools |
||||
|
||||
# Temporary Bazel directories |
||||
/bazel-* |
||||
/plugin |
||||
/build |
||||
|
||||
tags |
||||
.cache/clangd/* |
||||
|
||||
# Temporary dir used when generating semconv |
||||
buildscripts/semantic-convention/tmp-semconv/ |
||||
|
||||
# Generated cert keys in functional tests |
||||
functional/cert/ca.csr |
||||
functional/cert/ca.pem |
||||
functional/cert/ca-key.pem |
||||
functional/cert/client_cert.csr |
||||
functional/cert/client_cert.pem |
||||
functional/cert/client_cert-key.pem |
||||
functional/cert/server_cert.csr |
||||
functional/cert/server_cert.pem |
||||
functional/cert/server_cert-key.pem |
||||
functional/cert/ca_b.csr |
||||
functional/cert/ca_b.pem |
||||
functional/cert/ca_b-key.pem |
||||
functional/cert/client_cert_b.csr |
||||
functional/cert/client_cert_b.pem |
||||
functional/cert/client_cert_b-key.pem |
||||
functional/cert/server_cert_b.csr |
||||
functional/cert/server_cert_b.pem |
||||
functional/cert/server_cert_b-key.pem |
||||
functional/cert/unreadable.pem |
||||
|
||||
localinstall |
||||
@ -0,0 +1,39 @@
|
||||
[submodule "third_party/prometheus-cpp"] |
||||
path = third_party/prometheus-cpp |
||||
url = https://github.com/jupp0r/prometheus-cpp |
||||
branch = master |
||||
|
||||
[submodule "tools/vcpkg"] |
||||
path = tools/vcpkg |
||||
url = https://github.com/Microsoft/vcpkg |
||||
branch = master |
||||
|
||||
[submodule "third_party/ms-gsl"] |
||||
path = third_party/ms-gsl |
||||
url = https://github.com/microsoft/GSL |
||||
branch = main |
||||
|
||||
[submodule "third_party/googletest"] |
||||
path = third_party/googletest |
||||
url = https://github.com/google/googletest |
||||
branch = main |
||||
|
||||
[submodule "third_party/benchmark"] |
||||
path = third_party/benchmark |
||||
url = https://github.com/google/benchmark |
||||
branch = main |
||||
|
||||
[submodule "third_party/opentelemetry-proto"] |
||||
path = third_party/opentelemetry-proto |
||||
url = https://github.com/open-telemetry/opentelemetry-proto |
||||
branch = main |
||||
|
||||
[submodule "third_party/nlohmann-json"] |
||||
path = third_party/nlohmann-json |
||||
url = https://github.com/nlohmann/json |
||||
branch = master |
||||
|
||||
[submodule "third_party/opentracing-cpp"] |
||||
path = third_party/opentracing-cpp |
||||
url = https://github.com/opentracing/opentracing-cpp.git |
||||
branch = master |
||||
@ -0,0 +1,31 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
# include-what-you-use mapping file |
||||
|
||||
[ |
||||
# Work around for C++ STL |
||||
{ "include": ["<bits/chrono.h>", "private", "<chrono>", "public"] }, |
||||
{ "include": ["<bits/std_abs.h>", "private", "<cstdlib>", "public"] }, |
||||
{ "include": ["<ext/alloc_traits.h>", "private", "<memory>", "public"] }, |
||||
{ "include": ["<bits/types/struct_tm.h>", "private", "<time.h>", "public"] }, |
||||
{ "include": ["<bits/types/struct_FILE.h>", "private", "<stdio.h>", "public"] }, |
||||
|
||||
# Local opentelemetry-cpp style |
||||
|
||||
# We prefer to include <gtest/gtest.h> for simplicity |
||||
{ "include": ["<gtest/gtest-message.h>", "private", "<gtest/gtest.h>", "public"] }, |
||||
{ "include": ["<gtest/gtest-test-part.h>", "private", "<gtest/gtest.h>", "public"] }, |
||||
{ "include": ["<gtest/gtest-param-test.h>", "private", "<gtest/gtest.h>", "public"] }, |
||||
{ "include": ["<gtest/gtest_pred_impl.h>", "private", "<gtest/gtest.h>", "public"] }, |
||||
{ "include": ["<gtest/gtest-typed-test.h>", "private", "<gtest/gtest.h>", "public"] }, |
||||
{ "include": ["<gtest/gtest-assertion-result.h>", "private", "<gtest/gtest.h>", "public"] }, |
||||
|
||||
# We prefer to include <gmock/gmock.h> for simplicity |
||||
{ "include": ["<gmock/gmock-function-mocker.h>", "private", "<gmock/gmock.h>", "public"] }, |
||||
{ "include": ["<gmock/gmock-spec-builders.h>", "private", "<gmock/gmock.h>", "public"] }, |
||||
|
||||
# We prefer to include <curl/curl.h> for simplicity |
||||
{ "include": ["<curl/system.h>", "private", "<curl/curl.h>", "public"] }, |
||||
] |
||||
|
||||
@ -0,0 +1,8 @@
|
||||
{ |
||||
"default": true, |
||||
"MD013": |
||||
{ |
||||
"code_blocks": false, |
||||
"tables": false |
||||
} |
||||
} |
||||
@ -0,0 +1,3 @@
|
||||
third_party/** |
||||
tools/** |
||||
examples/otlp/README.md |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,927 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
cmake_minimum_required(VERSION 3.14) |
||||
|
||||
# See https://cmake.org/cmake/help/latest/policy/CMP0074.html required by |
||||
# certain version of zlib which CURL depends on. |
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12") |
||||
cmake_policy(SET CMP0074 NEW) |
||||
endif() |
||||
|
||||
# Allow to use normal variable for option() |
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13") |
||||
cmake_policy(SET CMP0077 NEW) |
||||
endif() |
||||
|
||||
# Prefer CMAKE_MSVC_RUNTIME_LIBRARY if possible |
||||
if(POLICY CMP0091) |
||||
cmake_policy(SET CMP0091 NEW) |
||||
endif() |
||||
|
||||
if(POLICY CMP0092) |
||||
# https://cmake.org/cmake/help/latest/policy/CMP0092.html#policy:CMP0092 Make |
||||
# sure the /W3 is not removed from CMAKE_CXX_FLAGS since CMake 3.15 |
||||
cmake_policy(SET CMP0092 OLD) |
||||
endif() |
||||
|
||||
# MSVC RTTI flag /GR should not be not added to CMAKE_CXX_FLAGS by default. @see |
||||
# https://cmake.org/cmake/help/latest/policy/CMP0117.html |
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.20.0") |
||||
cmake_policy(SET CMP0117 NEW) |
||||
endif() |
||||
|
||||
project(opentelemetry-cpp) |
||||
|
||||
# Mark variables as used so cmake doesn't complain about them |
||||
mark_as_advanced(CMAKE_TOOLCHAIN_FILE) |
||||
|
||||
# Note: CMAKE_FIND_PACKAGE_PREFER_CONFIG requires cmake 3.15. Prefer cmake |
||||
# CONFIG search mode to find dependencies. This is important to properly find |
||||
# protobuf versions 3.22.0 and above due to the abseil-cpp dependency. |
||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) |
||||
|
||||
# Don't use customized cmake modules if vcpkg is used to resolve dependence. |
||||
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) |
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") |
||||
endif() |
||||
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/third_party_release") |
||||
file(STRINGS "${CMAKE_SOURCE_DIR}/third_party_release" third_party_tags) |
||||
foreach(third_party ${third_party_tags}) |
||||
string(REGEX REPLACE "^[ ]+" "" third_party ${third_party}) |
||||
string(REGEX MATCH "^[^=]+" third_party_name ${third_party}) |
||||
string(REPLACE "${third_party_name}=" "" third_party_tag ${third_party}) |
||||
set(${third_party_name} "${third_party_tag}") |
||||
endforeach() |
||||
endif() |
||||
|
||||
if(DEFINED ENV{ARCH}) |
||||
# Architecture may be specified via ARCH environment variable |
||||
set(ARCH $ENV{ARCH}) |
||||
else() |
||||
# Autodetection logic that populates ARCH variable |
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") |
||||
# Windows may report AMD64 even if target is 32-bit |
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8) |
||||
set(ARCH x64) |
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) |
||||
set(ARCH x86) |
||||
endif() |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*") |
||||
# Windows may report x86 even if target is 64-bit |
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8) |
||||
set(ARCH x64) |
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) |
||||
set(ARCH x86) |
||||
endif() |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "powerpc") |
||||
# AIX will report the processor as 'powerpc' even if building in 64-bit mode |
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8) |
||||
set(ARCH ppc64) |
||||
else() |
||||
set(ARCH ppc32) |
||||
endif() |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES |
||||
"^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)") |
||||
set(ARCH arm64) |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)") |
||||
set(ARCH arm) |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") |
||||
set(ARCH ppc64le) |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64") |
||||
set(ARCH ppc64) |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips.*|MIPS.*)") |
||||
set(ARCH mips) |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(riscv.*|RISCV.*)") |
||||
set(ARCH riscv) |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x.*|S390X.*)") |
||||
set(ARCH s390x) |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(sparc.*|SPARC.*)") |
||||
set(ARCH sparc) |
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(loongarch.*|LOONGARCH.*)") |
||||
set(ARCH loongarch) |
||||
else() |
||||
message( |
||||
FATAL_ERROR |
||||
"opentelemetry-cpp: unrecognized target processor ${CMAKE_SYSTEM_PROCESSOR} configuration!" |
||||
) |
||||
endif() |
||||
endif() |
||||
message(STATUS "Building for architecture ARCH=${ARCH}") |
||||
|
||||
# Autodetect vcpkg toolchain |
||||
if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE) |
||||
set(CMAKE_TOOLCHAIN_FILE |
||||
"$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" |
||||
CACHE STRING "") |
||||
endif() |
||||
|
||||
if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE) |
||||
include("${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}") |
||||
endif() |
||||
|
||||
option(WITH_ABI_VERSION_1 "ABI version 1" ON) |
||||
option(WITH_ABI_VERSION_2 "EXPERIMENTAL: ABI version 2 preview" OFF) |
||||
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h" |
||||
OPENTELEMETRY_CPP_HEADER_VERSION_H) |
||||
|
||||
# |
||||
# We do not want to have WITH_ABI_VERSION = "1" or "2", and instead prefer two |
||||
# distinct flags, WITH_ABI_VERSION_1 and WITH_ABI_VERSION_2. |
||||
# |
||||
# This allows: |
||||
# |
||||
# * to have a specific option description for each ABI |
||||
# * to mark experimental/stable/deprecated on flags, for clarity |
||||
# * to search for exact abi usage move easily, discouraging: |
||||
# |
||||
# * cmake -DWITH_ABI_VERSION=${ARG} |
||||
# |
||||
# While not supported, having distinct WITH_ABI_VERSION_1 and WITH_ABI_VERSION_2 |
||||
# flags also opens the possibility to support multiple ABI concurrently, should |
||||
# that become necessary. |
||||
# |
||||
if(WITH_ABI_VERSION_1 AND WITH_ABI_VERSION_2) |
||||
# |
||||
# Only one ABI is supported in a build. |
||||
# |
||||
message( |
||||
FATAL_ERROR "Set either WITH_ABI_VERSION_1 or WITH_ABI_VERSION_2, not both") |
||||
endif() |
||||
|
||||
if(WITH_ABI_VERSION_2) |
||||
set(OPENTELEMETRY_ABI_VERSION_NO "2") |
||||
elseif(WITH_ABI_VERSION_1) |
||||
set(OPENTELEMETRY_ABI_VERSION_NO "1") |
||||
else() |
||||
if(OPENTELEMETRY_CPP_HEADER_VERSION_H MATCHES |
||||
"OPENTELEMETRY_ABI_VERSION_NO[ \t\r\n]+\"?([0-9]+)\"?") |
||||
math(EXPR OPENTELEMETRY_ABI_VERSION_NO ${CMAKE_MATCH_1}) |
||||
else() |
||||
message( |
||||
FATAL_ERROR |
||||
"OPENTELEMETRY_ABI_VERSION_NO not found on ${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h" |
||||
) |
||||
endif() |
||||
endif() |
||||
|
||||
message(STATUS "OPENTELEMETRY_ABI_VERSION_NO=${OPENTELEMETRY_ABI_VERSION_NO}") |
||||
|
||||
if(OPENTELEMETRY_CPP_HEADER_VERSION_H MATCHES |
||||
"OPENTELEMETRY_VERSION[ \t\r\n]+\"?([^\"]+)\"?") |
||||
set(OPENTELEMETRY_VERSION ${CMAKE_MATCH_1}) |
||||
else() |
||||
message( |
||||
FATAL_ERROR |
||||
"OPENTELEMETRY_VERSION not found on ${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h" |
||||
) |
||||
endif() |
||||
|
||||
message(STATUS "OPENTELEMETRY_VERSION=${OPENTELEMETRY_VERSION}") |
||||
|
||||
option(WITH_NO_DEPRECATED_CODE "Do not include deprecated code" OFF) |
||||
|
||||
set(WITH_STL |
||||
"OFF" |
||||
CACHE STRING "Which version of the Standard Library for C++ to use") |
||||
|
||||
option(WITH_GSL |
||||
"Whether to use Guidelines Support Library for C++ latest features" OFF) |
||||
|
||||
set(OPENTELEMETRY_INSTALL_default ON) |
||||
if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) |
||||
set(OPENTELEMETRY_INSTALL_default OFF) |
||||
endif() |
||||
option(OPENTELEMETRY_INSTALL "Whether to install opentelemetry targets" |
||||
${OPENTELEMETRY_INSTALL_default}) |
||||
|
||||
include("${PROJECT_SOURCE_DIR}/cmake/tools.cmake") |
||||
|
||||
if(NOT WITH_STL STREQUAL "OFF") |
||||
# These definitions are needed for test projects that do not link against |
||||
# opentelemetry-api library directly. We ensure that variant implementation |
||||
# (absl::variant or std::variant) in variant unit test code is consistent with |
||||
# the global project build definitions. Optimize for speed to reduce the hops |
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") |
||||
if(CMAKE_BUILD_TYPE MATCHES Debug) |
||||
# Turn off optimizations for DEBUG |
||||
set(MSVC_CXX_OPT_FLAG "/Od") |
||||
else() |
||||
string(REGEX MATCH "\/O" result ${CMAKE_CXX_FLAGS}) |
||||
if(NOT ${result} MATCHES "\/O") |
||||
set(MSVC_CXX_OPT_FLAG "/O2") |
||||
endif() |
||||
endif() |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MSVC_CXX_OPT_FLAG}") |
||||
endif() |
||||
endif() |
||||
|
||||
option(WITH_OTLP_RETRY_PREVIEW |
||||
"Whether to enable experimental retry functionality" OFF) |
||||
|
||||
option(WITH_OTLP_GRPC_SSL_MTLS_PREVIEW |
||||
"Whether to enable mTLS support fro gRPC" OFF) |
||||
|
||||
option(WITH_OTLP_GRPC "Whether to include the OTLP gRPC exporter in the SDK" |
||||
OFF) |
||||
|
||||
option(WITH_OTLP_HTTP "Whether to include the OTLP http exporter in the SDK" |
||||
OFF) |
||||
|
||||
option(WITH_OTLP_FILE "Whether to include the OTLP file exporter in the SDK" |
||||
OFF) |
||||
|
||||
option( |
||||
WITH_OTLP_HTTP_COMPRESSION |
||||
"Whether to include gzip compression for the OTLP http exporter in the SDK" |
||||
OFF) |
||||
|
||||
option(WITH_CURL_LOGGING "Whether to enable select CURL verbosity in OTel logs" |
||||
OFF) |
||||
|
||||
option(WITH_ZIPKIN "Whether to include the Zipkin exporter in the SDK" OFF) |
||||
|
||||
option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK" |
||||
OFF) |
||||
|
||||
option(WITH_ELASTICSEARCH |
||||
"Whether to include the Elasticsearch Client in the SDK" OFF) |
||||
|
||||
option(WITH_NO_GETENV "Whether the platform supports environment variables" OFF) |
||||
|
||||
option(BUILD_TESTING "Whether to enable tests" ON) |
||||
|
||||
option(WITH_BENCHMARK "Whether to build benchmark program" ON) |
||||
|
||||
option(BUILD_W3CTRACECONTEXT_TEST "Whether to build w3c trace context" OFF) |
||||
|
||||
option(OTELCPP_MAINTAINER_MODE "Build in maintainer mode (-Wall -Werror)" OFF) |
||||
|
||||
option(WITH_OPENTRACING "Whether to include the Opentracing shim" OFF) |
||||
|
||||
option(OTELCPP_VERSIONED_LIBS "Whether to generate the versioned shared libs" |
||||
OFF) |
||||
|
||||
# |
||||
# This option is experimental, subject to change in the spec: |
||||
# |
||||
# * https://github.com/open-telemetry/opentelemetry-specification/issues/2232 |
||||
# |
||||
option(WITH_REMOVE_METER_PREVIEW |
||||
"EXPERIMENTAL, ABI BREAKING: Allow to remove a meter" OFF) |
||||
|
||||
if(OTELCPP_VERSIONED_LIBS AND NOT BUILD_SHARED_LIBS) |
||||
message(FATAL_ERROR "OTELCPP_VERSIONED_LIBS=ON requires BUILD_SHARED_LIBS=ON") |
||||
endif() |
||||
|
||||
if(WIN32) |
||||
option(WITH_ETW "Whether to include the ETW Exporter in the SDK" ON) |
||||
else() |
||||
if(DEFINED (WITH_ETW)) |
||||
message(FATAL_ERROR "WITH_ETW is only supported on Windows") |
||||
endif() |
||||
endif(WIN32) |
||||
|
||||
# Do not convert deprecated message to error |
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") |
||||
add_compile_options(-Wno-error=deprecated-declarations) |
||||
endif() |
||||
|
||||
option( |
||||
WITH_API_ONLY |
||||
"Only build the API (use as a header-only library). Overrides WITH_EXAMPLES and all options to enable exporters" |
||||
OFF) |
||||
option(WITH_EXAMPLES "Whether to build examples" ON) |
||||
|
||||
# This requires CURL, OFF by default. |
||||
option( |
||||
WITH_EXAMPLES_HTTP |
||||
"Whether to build http client/server examples. Requires WITH_EXAMPLES and CURL" |
||||
OFF) |
||||
|
||||
option(WITH_FUNC_TESTS "Whether to build functional tests" ON) |
||||
|
||||
option(WITH_ASYNC_EXPORT_PREVIEW "Whether to enable async export" OFF) |
||||
|
||||
# Exemplar specs status is experimental, so behind feature flag by default |
||||
option(WITH_METRICS_EXEMPLAR_PREVIEW |
||||
"Whether to enable exemplar within metrics" OFF) |
||||
|
||||
# Experimental, so behind feature flag by default |
||||
option(WITH_THREAD_INSTRUMENTATION_PREVIEW |
||||
"Whether to enable thread instrumentation" OFF) |
||||
|
||||
option(OPENTELEMETRY_SKIP_DYNAMIC_LOADING_TESTS |
||||
"Whether to build test libraries that are always linked as shared libs" |
||||
OFF) |
||||
|
||||
# |
||||
# Verify options dependencies |
||||
# |
||||
|
||||
if(WITH_EXAMPLES_HTTP AND NOT WITH_EXAMPLES) |
||||
message(FATAL_ERROR "WITH_EXAMPLES_HTTP=ON requires WITH_EXAMPLES=ON") |
||||
endif() |
||||
|
||||
find_package(Threads) |
||||
|
||||
function(install_windows_deps) |
||||
# Bootstrap vcpkg from CMake and auto-install deps in case if we are missing |
||||
# deps on Windows. Respect the target architecture variable. |
||||
set(VCPKG_TARGET_ARCHITECTURE |
||||
${ARCH} |
||||
PARENT_SCOPE) |
||||
message(STATUS "Installing build tools and dependencies...") |
||||
set(ENV{ARCH} ${ARCH}) |
||||
execute_process( |
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/setup-buildtools.cmd) |
||||
set(CMAKE_TOOLCHAIN_FILE |
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/scripts/buildsystems/vcpkg.cmake |
||||
CACHE FILEPATH "") |
||||
message( |
||||
STATUS |
||||
"Make sure that vcpkg.cmake is set as the CMAKE_TOOLCHAIN_FILE at the START of the cmake build process! |
||||
Can be command-line arg (cmake -DCMAKE_TOOLCHAIN_FILE=...) or set in your editor of choice." |
||||
) |
||||
|
||||
endfunction() |
||||
|
||||
function(set_target_version target_name) |
||||
if(OTELCPP_VERSIONED_LIBS) |
||||
set_target_properties( |
||||
${target_name} PROPERTIES VERSION ${OPENTELEMETRY_VERSION} |
||||
SOVERSION ${OPENTELEMETRY_ABI_VERSION_NO}) |
||||
endif() |
||||
endfunction() |
||||
|
||||
if(MSVC) |
||||
# Options for Visual C++ compiler: /Zc:__cplusplus - report an updated value |
||||
# for recent C++ language standards. Without this option MSVC returns the |
||||
# value of __cplusplus="199711L" |
||||
if(MSVC_VERSION GREATER 1900) |
||||
# __cplusplus flag is not supported by Visual Studio 2015 |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus") |
||||
endif() |
||||
endif() |
||||
|
||||
# include GNUInstallDirs before include cmake/opentelemetry-proto.cmake because |
||||
# opentelemetry-proto installs targets to the location variables defined in |
||||
# GNUInstallDirs. |
||||
include(GNUInstallDirs) |
||||
|
||||
if(WITH_PROMETHEUS) |
||||
find_package(prometheus-cpp CONFIG QUIET) |
||||
if(NOT prometheus-cpp_FOUND) |
||||
message(STATUS "Trying to use local prometheus-cpp from submodule") |
||||
if(EXISTS ${PROJECT_SOURCE_DIR}/third_party/prometheus-cpp/.git) |
||||
set(SAVED_ENABLE_TESTING ${ENABLE_TESTING}) |
||||
set(SAVED_CMAKE_CXX_CLANG_TIDY ${CMAKE_CXX_CLANG_TIDY}) |
||||
set(SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE |
||||
${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}) |
||||
set(ENABLE_TESTING OFF) |
||||
set(CMAKE_CXX_CLANG_TIDY "") |
||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "") |
||||
add_subdirectory(third_party/prometheus-cpp) |
||||
set(ENABLE_TESTING ${SAVED_ENABLE_TESTING}) |
||||
set(CMAKE_CXX_CLANG_TIDY ${SAVED_CMAKE_CXX_CLANG_TIDY}) |
||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE |
||||
${SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}) |
||||
|
||||
# Get the version of the prometheus-cpp submodule |
||||
find_package(Git QUIET) |
||||
if(Git_FOUND) |
||||
execute_process( |
||||
COMMAND ${GIT_EXECUTABLE} describe --tags --always |
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/third_party/prometheus-cpp |
||||
OUTPUT_VARIABLE prometheus-cpp_VERSION |
||||
OUTPUT_STRIP_TRAILING_WHITESPACE) |
||||
string(REGEX REPLACE "^v" "" prometheus-cpp_VERSION |
||||
"${prometheus-cpp_VERSION}") |
||||
endif() |
||||
|
||||
message( |
||||
STATUS |
||||
"Using local prometheus-cpp from submodule. Version = ${prometheus-cpp_VERSION}" |
||||
) |
||||
else() |
||||
message( |
||||
FATAL_ERROR |
||||
"\nprometheus-cpp package was not found. Please either provide it manually or clone with submodules. " |
||||
"To initialize, fetch and checkout any nested submodules, you can use the following command:\n" |
||||
"git submodule update --init --recursive") |
||||
endif() |
||||
else() |
||||
message(STATUS "Using external prometheus-cpp") |
||||
endif() |
||||
endif() |
||||
|
||||
if(WITH_OTLP_GRPC |
||||
OR WITH_OTLP_HTTP |
||||
OR WITH_OTLP_FILE) |
||||
|
||||
# Including the CMakeFindDependencyMacro resolves an error from |
||||
# gRPCConfig.cmake on some grpc versions. See |
||||
# https://github.com/grpc/grpc/pull/33361 for more details. |
||||
include(CMakeFindDependencyMacro) |
||||
|
||||
# Protobuf 3.22+ depends on abseil-cpp and must be found using the cmake |
||||
# find_package CONFIG search mode. The following attempts to find Protobuf |
||||
# using the CONFIG mode first, and if not found, falls back to the MODULE |
||||
# mode. See https://gitlab.kitware.com/cmake/cmake/-/issues/24321 for more |
||||
# details. |
||||
find_package(Protobuf CONFIG) |
||||
if(NOT Protobuf_FOUND) |
||||
find_package(Protobuf MODULE) |
||||
if(Protobuf_FOUND AND Protobuf_VERSION VERSION_GREATER_EQUAL "3.22.0") |
||||
message( |
||||
WARNING |
||||
"Found Protobuf version ${Protobuf_VERSION} using MODULE mode. " |
||||
"Linking errors may occur. Protobuf 3.22+ depends on abseil-cpp " |
||||
"and should be found using the CONFIG mode.") |
||||
endif() |
||||
endif() |
||||
|
||||
if(WITH_OTLP_GRPC) |
||||
find_package(gRPC CONFIG) |
||||
endif() |
||||
if((NOT Protobuf_FOUND) OR (WITH_OTLP_GRPC AND NOT gRPC_FOUND)) |
||||
if(WIN32 AND (NOT DEFINED CMAKE_TOOLCHAIN_FILE)) |
||||
install_windows_deps() |
||||
endif() |
||||
|
||||
if(WIN32 AND (NOT DEFINED CMAKE_TOOLCHAIN_FILE)) |
||||
message(FATAL_ERROR "Windows dependency installation failed!") |
||||
endif() |
||||
if(WIN32) |
||||
include(${CMAKE_TOOLCHAIN_FILE}) |
||||
endif() |
||||
|
||||
if(NOT Protobuf_FOUND) |
||||
find_package(Protobuf CONFIG REQUIRED) |
||||
endif() |
||||
if(NOT gRPC_FOUND AND WITH_OTLP_GRPC) |
||||
find_package(gRPC CONFIG) |
||||
endif() |
||||
if(WIN32) |
||||
# Always use x64 protoc.exe |
||||
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") |
||||
set(Protobuf_PROTOC_EXECUTABLE |
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/packages/protobuf_x64-windows/tools/protobuf/protoc.exe |
||||
) |
||||
endif() |
||||
endif() |
||||
endif() |
||||
# Latest Protobuf imported targets and without legacy module support |
||||
if(TARGET protobuf::protoc) |
||||
if(CMAKE_CROSSCOMPILING AND Protobuf_PROTOC_EXECUTABLE) |
||||
set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE}) |
||||
else() |
||||
project_build_tools_get_imported_location(PROTOBUF_PROTOC_EXECUTABLE |
||||
protobuf::protoc) |
||||
# If protobuf::protoc is not a imported target, then we use the target |
||||
# directly for fallback |
||||
if(NOT PROTOBUF_PROTOC_EXECUTABLE) |
||||
set(PROTOBUF_PROTOC_EXECUTABLE protobuf::protoc) |
||||
endif() |
||||
endif() |
||||
elseif(Protobuf_PROTOC_EXECUTABLE) |
||||
# Some versions of FindProtobuf.cmake uses mixed case instead of uppercase |
||||
set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE}) |
||||
endif() |
||||
include(CMakeDependentOption) |
||||
|
||||
message(STATUS "PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}") |
||||
set(SAVED_CMAKE_CXX_CLANG_TIDY ${CMAKE_CXX_CLANG_TIDY}) |
||||
set(CMAKE_CXX_CLANG_TIDY "") |
||||
include(cmake/opentelemetry-proto.cmake) |
||||
set(CMAKE_CXX_CLANG_TIDY ${SAVED_CMAKE_CXX_CLANG_TIDY}) |
||||
endif() |
||||
|
||||
# |
||||
# Do we need HTTP CLIENT CURL ? |
||||
# |
||||
|
||||
if(WITH_OTLP_HTTP |
||||
OR WITH_ELASTICSEARCH |
||||
OR WITH_ZIPKIN |
||||
OR BUILD_W3CTRACECONTEXT_TEST |
||||
OR WITH_EXAMPLES_HTTP) |
||||
set(WITH_HTTP_CLIENT_CURL ON) |
||||
else() |
||||
set(WITH_HTTP_CLIENT_CURL OFF) |
||||
endif() |
||||
|
||||
# |
||||
# Do we need CURL ? |
||||
# |
||||
|
||||
if((NOT WITH_API_ONLY) AND WITH_HTTP_CLIENT_CURL) |
||||
# No specific version required. |
||||
find_package(CURL REQUIRED) |
||||
# Set the CURL_VERSION from the legacy CURL_VERSION_STRING Required for CMake |
||||
# versions below 4.0 |
||||
if(NOT DEFINED CURL_VERSION AND DEFINED CURL_VERSION_STRING) |
||||
set(CURL_VERSION ${CURL_VERSION_STRING}) |
||||
endif() |
||||
endif() |
||||
|
||||
# |
||||
# Do we need ZLIB ? |
||||
# |
||||
|
||||
if((NOT WITH_API_ONLY) |
||||
AND WITH_HTTP_CLIENT_CURL |
||||
AND WITH_OTLP_HTTP_COMPRESSION) |
||||
# No specific version required. |
||||
find_package(ZLIB REQUIRED) |
||||
# Set the ZLIB_VERSION from the legacy ZLIB_VERSION_STRING Required for CMake |
||||
# versions below 3.26 |
||||
if(NOT DEFINED ZLIB_VERSION AND DEFINED ZLIB_VERSION_STRING) |
||||
set(ZLIB_VERSION ${ZLIB_VERSION_STRING}) |
||||
endif() |
||||
endif() |
||||
|
||||
# |
||||
# Do we need NLOHMANN_JSON ? |
||||
# |
||||
|
||||
if(WITH_ELASTICSEARCH |
||||
OR WITH_ZIPKIN |
||||
OR WITH_OTLP_HTTP |
||||
OR WITH_OTLP_FILE |
||||
OR BUILD_W3CTRACECONTEXT_TEST |
||||
OR WITH_ETW) |
||||
set(USE_NLOHMANN_JSON ON) |
||||
else() |
||||
set(USE_NLOHMANN_JSON OFF) |
||||
endif() |
||||
|
||||
if((NOT WITH_API_ONLY) AND USE_NLOHMANN_JSON) |
||||
include(cmake/nlohmann-json.cmake) |
||||
endif() |
||||
|
||||
if(OTELCPP_MAINTAINER_MODE) |
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") |
||||
message(STATUS "Building with gcc in maintainer mode.") |
||||
|
||||
add_compile_options(-Wall) |
||||
add_compile_options(-Werror) |
||||
add_compile_options(-Wextra) |
||||
|
||||
# Tested with GCC 9.4 on github. |
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.4) |
||||
message(STATUS "Building with additional warnings for gcc.") |
||||
|
||||
# Relaxed warnings |
||||
|
||||
# Enforced warnings |
||||
|
||||
# C++ options only |
||||
add_compile_options($<$<STREQUAL:$<COMPILE_LANGUAGE>,CXX>:-Wextra-semi>) |
||||
add_compile_options( |
||||
$<$<STREQUAL:$<COMPILE_LANGUAGE>,CXX>:-Woverloaded-virtual>) |
||||
add_compile_options( |
||||
$<$<STREQUAL:$<COMPILE_LANGUAGE>,CXX>:-Wsuggest-override>) |
||||
add_compile_options( |
||||
$<$<STREQUAL:$<COMPILE_LANGUAGE>,CXX>:-Wold-style-cast>) |
||||
|
||||
# C and C++ |
||||
add_compile_options(-Wcast-qual) |
||||
add_compile_options(-Wformat-security) |
||||
add_compile_options(-Wlogical-op) |
||||
add_compile_options(-Wmissing-include-dirs) |
||||
add_compile_options(-Wstringop-truncation) |
||||
add_compile_options(-Wundef) |
||||
add_compile_options(-Wvla) |
||||
endif() |
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") |
||||
message(STATUS "Building with clang in maintainer mode.") |
||||
|
||||
add_compile_options(-Wall) |
||||
add_compile_options(-Werror) |
||||
add_compile_options(-Wextra) |
||||
|
||||
# Tested with Clang 11.0 on github. |
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) |
||||
message(STATUS "Building with additional warnings for clang.") |
||||
|
||||
# Relaxed warnings |
||||
add_compile_options(-Wno-error=unused-private-field) |
||||
|
||||
# Enforced warnings |
||||
add_compile_options(-Wcast-qual) |
||||
add_compile_options(-Wconditional-uninitialized) |
||||
add_compile_options(-Wextra-semi) |
||||
add_compile_options(-Wformat-security) |
||||
add_compile_options(-Wheader-hygiene) |
||||
add_compile_options(-Winconsistent-missing-destructor-override) |
||||
add_compile_options(-Winconsistent-missing-override) |
||||
add_compile_options(-Wnewline-eof) |
||||
add_compile_options(-Wnon-virtual-dtor) |
||||
add_compile_options(-Woverloaded-virtual) |
||||
add_compile_options(-Wrange-loop-analysis) |
||||
add_compile_options(-Wundef) |
||||
add_compile_options(-Wundefined-reinterpret-cast) |
||||
add_compile_options(-Wvla) |
||||
add_compile_options(-Wold-style-cast) |
||||
endif() |
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") |
||||
message(STATUS "Building with msvc in maintainer mode.") |
||||
|
||||
add_compile_options(/WX) |
||||
add_compile_options(/W4) |
||||
|
||||
# Relaxed warnings |
||||
add_compile_options(/wd4100) |
||||
add_compile_options(/wd4125) |
||||
add_compile_options(/wd4566) |
||||
add_compile_options(/wd4127) |
||||
add_compile_options(/wd4512) |
||||
add_compile_options(/wd4267) |
||||
add_compile_options(/wd4996) |
||||
|
||||
# Enforced warnings |
||||
add_compile_options(/we4265) # 'class': class has virtual functions, but |
||||
# destructor is not virtual |
||||
add_compile_options(/we5204) # A class with virtual functions has |
||||
# non-virtual trivial destructor. |
||||
|
||||
elseif() |
||||
message(FATAL_ERROR "Building with unknown compiler in maintainer mode.") |
||||
endif() |
||||
endif(OTELCPP_MAINTAINER_MODE) |
||||
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") |
||||
|
||||
include(CTest) |
||||
if(BUILD_TESTING) |
||||
if(EXISTS ${CMAKE_BINARY_DIR}/lib/libgtest.a) |
||||
# Prefer GTest from build tree. GTest is not always working with |
||||
# CMAKE_PREFIX_PATH |
||||
set(GTEST_INCLUDE_DIRS |
||||
${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include |
||||
${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include) |
||||
if(TARGET gtest) |
||||
set(GTEST_BOTH_LIBRARIES gtest gtest_main) |
||||
else() |
||||
set(GTEST_BOTH_LIBRARIES ${CMAKE_BINARY_DIR}/lib/libgtest.a |
||||
${CMAKE_BINARY_DIR}/lib/libgtest_main.a) |
||||
endif() |
||||
elseif(WIN32) |
||||
# Make sure we are always bootsrapped with vcpkg on Windows |
||||
find_package(GTest) |
||||
if(NOT (GTEST_FOUND OR GTest_FOUND)) |
||||
if(DEFINED CMAKE_TOOLCHAIN_FILE) |
||||
message( |
||||
FATAL_ERROR |
||||
"Pleaes install GTest with the CMAKE_TOOLCHAIN_FILE at ${CMAKE_TOOLCHAIN_FILE}" |
||||
) |
||||
else() |
||||
install_windows_deps() |
||||
include(${CMAKE_TOOLCHAIN_FILE}) |
||||
find_package(GTest REQUIRED) |
||||
endif() |
||||
endif() |
||||
else() |
||||
# Prefer GTest installed by OS distro, brew or vcpkg package manager |
||||
find_package(GTest REQUIRED) |
||||
endif() |
||||
if(NOT GTEST_BOTH_LIBRARIES) |
||||
# New GTest package names |
||||
if(TARGET GTest::gtest) |
||||
set(GTEST_BOTH_LIBRARIES GTest::gtest GTest::gtest_main) |
||||
elseif(TARGET GTest::GTest) |
||||
set(GTEST_BOTH_LIBRARIES GTest::GTest GTest::Main) |
||||
endif() |
||||
endif() |
||||
if(GTEST_INCLUDE_DIRS) |
||||
include_directories(SYSTEM ${GTEST_INCLUDE_DIRS}) |
||||
endif() |
||||
message(STATUS "GTEST_INCLUDE_DIRS = ${GTEST_INCLUDE_DIRS}") |
||||
message(STATUS "GTEST_BOTH_LIBRARIES = ${GTEST_BOTH_LIBRARIES}") |
||||
|
||||
# Try to find gmock |
||||
if(NOT GMOCK_LIB AND TARGET GTest::gmock) |
||||
set(GMOCK_LIB GTest::gmock) |
||||
elseif(MSVC) |
||||
# Explicitly specify that we consume GTest from shared library. The rest of |
||||
# code logic below determines whether we link Release or Debug flavor of the |
||||
# library. These flavors have different prefix on Windows, gmock and gmockd |
||||
# respectively. |
||||
add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1) |
||||
if(GMOCK_LIB) |
||||
# unset GMOCK_LIB to force find_library to redo the lookup, as the cached |
||||
# entry could cause linking to incorrect flavor of gmock and leading to |
||||
# runtime error. |
||||
unset(GMOCK_LIB CACHE) |
||||
endif() |
||||
endif() |
||||
if(NOT GMOCK_LIB) |
||||
if(MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug") |
||||
find_library(GMOCK_LIB gmockd PATH_SUFFIXES lib) |
||||
else() |
||||
find_library(GMOCK_LIB gmock PATH_SUFFIXES lib) |
||||
endif() |
||||
# Reset GMOCK_LIB if it was not found, or some target may link |
||||
# GMOCK_LIB-NOTFOUND |
||||
if(NOT GMOCK_LIB) |
||||
unset(GMOCK_LIB) |
||||
unset(GMOCK_LIB CACHE) |
||||
endif() |
||||
endif() |
||||
|
||||
enable_testing() |
||||
if(WITH_BENCHMARK) |
||||
# Benchmark respects the CMAKE_PREFIX_PATH |
||||
find_package(benchmark CONFIG REQUIRED) |
||||
endif() |
||||
endif() |
||||
|
||||
# Record build config and versions |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "build settings") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "OpenTelemetry: ${OPENTELEMETRY_VERSION}") |
||||
message(STATUS "OpenTelemetry ABI: ${OPENTELEMETRY_ABI_VERSION_NO}") |
||||
message(STATUS "ARCH: ${ARCH}") |
||||
message(STATUS "CXX: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") |
||||
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") |
||||
message(STATUS "CXXFLAGS: ${CMAKE_CXX_FLAGS}") |
||||
message(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") |
||||
message(STATUS "CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}") |
||||
message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") |
||||
|
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "opentelemetry-cpp build options") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "WITH_API_ONLY: ${WITH_API_ONLY}") |
||||
message(STATUS "WITH_NO_DEPRECATED_CODE: ${WITH_NO_DEPRECATED_CODE}") |
||||
message(STATUS "WITH_ABI_VERSION_1: ${WITH_ABI_VERSION_1}") |
||||
message(STATUS "WITH_ABI_VERSION_2: ${WITH_ABI_VERSION_2}") |
||||
message(STATUS "OTELCPP_VERSIONED_LIBS: ${OTELCPP_VERSIONED_LIBS}") |
||||
message(STATUS "OTELCPP_MAINTAINER_MODE: ${OTELCPP_MAINTAINER_MODE}") |
||||
message(STATUS "WITH_STL: ${WITH_STL}") |
||||
message(STATUS "WITH_GSL: ${WITH_GSL}") |
||||
message(STATUS "WITH_NO_GETENV: ${WITH_NO_GETENV}") |
||||
|
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "opentelemetry-cpp cmake component options") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "WITH_OTLP_GRPC: ${WITH_OTLP_GRPC}") |
||||
message(STATUS "WITH_OTLP_HTTP: ${WITH_OTLP_HTTP}") |
||||
message(STATUS "WITH_OTLP_FILE: ${WITH_OTLP_FILE}") |
||||
message(STATUS "WITH_HTTP_CLIENT_CURL: ${WITH_HTTP_CLIENT_CURL}") |
||||
message(STATUS "WITH_ZIPKIN: ${WITH_ZIPKIN}") |
||||
message(STATUS "WITH_PROMETHEUS: ${WITH_PROMETHEUS}") |
||||
message(STATUS "WITH_ELASTICSEARCH: ${WITH_ELASTICSEARCH}") |
||||
message(STATUS "WITH_OPENTRACING: ${WITH_OPENTRACING}") |
||||
message(STATUS "WITH_ETW: ${WITH_ETW}") |
||||
message(STATUS "OPENTELEMETRY_BUILD_DLL: ${OPENTELEMETRY_BUILD_DLL}") |
||||
|
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "feature preview options") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "WITH_ASYNC_EXPORT_PREVIEW: ${WITH_ASYNC_EXPORT_PREVIEW}") |
||||
message( |
||||
STATUS |
||||
"WITH_THREAD_INSTRUMENTATION_PREVIEW: ${WITH_THREAD_INSTRUMENTATION_PREVIEW}" |
||||
) |
||||
message( |
||||
STATUS "WITH_METRICS_EXEMPLAR_PREVIEW: ${WITH_METRICS_EXEMPLAR_PREVIEW}") |
||||
message(STATUS "WITH_REMOVE_METER_PREVIEW: ${WITH_REMOVE_METER_PREVIEW}") |
||||
message( |
||||
STATUS "WITH_OTLP_GRPC_SSL_MTLS_PREVIEW: ${WITH_OTLP_GRPC_SSL_MTLS_PREVIEW}") |
||||
message(STATUS "WITH_OTLP_RETRY_PREVIEW: ${WITH_OTLP_RETRY_PREVIEW}") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "third-party options") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "WITH_NLOHMANN_JSON: ${USE_NLOHMANN_JSON}") |
||||
message(STATUS "WITH_CURL_LOGGING: ${WITH_CURL_LOGGING}") |
||||
message(STATUS "WITH_OTLP_HTTP_COMPRESSION: ${WITH_OTLP_HTTP_COMPRESSION}") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "examples and test options") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "WITH_BENCHMARK: ${WITH_BENCHMARK}") |
||||
message(STATUS "WITH_EXAMPLES: ${WITH_EXAMPLES}") |
||||
message(STATUS "WITH_EXAMPLES_HTTP: ${WITH_EXAMPLES_HTTP}") |
||||
message(STATUS "WITH_FUNC_TESTS: ${WITH_FUNC_TESTS}") |
||||
message(STATUS "BUILD_W3CTRACECONTEXT_TEST: ${BUILD_W3CTRACECONTEXT_TEST}") |
||||
message(STATUS "BUILD_TESTING: ${BUILD_TESTING}") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "versions") |
||||
message(STATUS "---------------------------------------------") |
||||
message(STATUS "CMake: ${CMAKE_VERSION}") |
||||
message(STATUS "GTest: ${GTest_VERSION}") |
||||
message(STATUS "benchmark: ${benchmark_VERSION}") |
||||
if(WITH_GSL) |
||||
message(STATUS "GSL: ${GSL_VERSION}") |
||||
endif() |
||||
if(absl_FOUND) |
||||
message(STATUS "Abseil: ${absl_VERSION}") |
||||
endif() |
||||
if(Protobuf_FOUND) |
||||
message(STATUS "Protobuf: ${Protobuf_VERSION}") |
||||
endif() |
||||
if(gRPC_FOUND) |
||||
message(STATUS "gRPC: ${gRPC_VERSION}") |
||||
endif() |
||||
if(CURL_FOUND) |
||||
message(STATUS "CURL: ${CURL_VERSION}") |
||||
endif() |
||||
if(ZLIB_FOUND) |
||||
message(STATUS "ZLIB: ${ZLIB_VERSION}") |
||||
endif() |
||||
if(USE_NLOHMANN_JSON) |
||||
message(STATUS "nlohmann-json: ${nlohmann_json_VERSION}") |
||||
endif() |
||||
if(prometheus-cpp_FOUND) |
||||
message(STATUS "prometheus-cpp: ${prometheus-cpp_VERSION}") |
||||
endif() |
||||
message(STATUS "---------------------------------------------") |
||||
|
||||
include("${PROJECT_SOURCE_DIR}/cmake/otel-install-functions.cmake") |
||||
|
||||
include(CMakePackageConfigHelpers) |
||||
|
||||
if(DEFINED OPENTELEMETRY_BUILD_DLL) |
||||
if(NOT WIN32) |
||||
message(FATAL_ERROR "Build DLL is only supported on Windows!") |
||||
endif() |
||||
if(NOT MSVC) |
||||
message(WARNING "Build DLL is supposed to work with MSVC!") |
||||
endif() |
||||
if(WITH_STL) |
||||
message( |
||||
WARNING "Build DLL with C++ STL could cause binary incompatibility!") |
||||
endif() |
||||
add_definitions(-DOPENTELEMETRY_BUILD_EXPORT_DLL) |
||||
endif() |
||||
|
||||
add_subdirectory(api) |
||||
|
||||
if(WITH_OPENTRACING) |
||||
find_package(OpenTracing CONFIG QUIET) |
||||
if(NOT OpenTracing_FOUND) |
||||
set(OPENTRACING_DIR "third_party/opentracing-cpp") |
||||
message(STATUS "Trying to use local ${OPENTRACING_DIR} from submodule") |
||||
if(EXISTS "${PROJECT_SOURCE_DIR}/${OPENTRACING_DIR}/.git") |
||||
set(SAVED_BUILD_TESTING ${BUILD_TESTING}) |
||||
set(BUILD_TESTING OFF) |
||||
set(SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE |
||||
${CMAKE_CXX_INCLUDE_WHAT_YOU_USE}) |
||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "") |
||||
add_subdirectory(${OPENTRACING_DIR}) |
||||
set(BUILD_TESTING ${SAVED_BUILD_TESTING}) |
||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE |
||||
${SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE}) |
||||
else() |
||||
message( |
||||
FATAL_ERROR |
||||
"\nopentracing-cpp package was not found. Please either provide it manually or clone with submodules. " |
||||
"To initialize, fetch and checkout any nested submodules, you can use the following command:\n" |
||||
"git submodule update --init --recursive") |
||||
endif() |
||||
else() |
||||
message(STATUS "Using external opentracing-cpp") |
||||
endif() |
||||
add_subdirectory(opentracing-shim) |
||||
endif() |
||||
|
||||
if(NOT WITH_API_ONLY) |
||||
set(BUILD_TESTING ${BUILD_TESTING}) |
||||
|
||||
add_subdirectory(sdk) |
||||
add_subdirectory(ext) |
||||
add_subdirectory(exporters) |
||||
|
||||
if(BUILD_TESTING) |
||||
add_subdirectory(test_common) |
||||
endif() |
||||
if(WITH_EXAMPLES) |
||||
add_subdirectory(examples) |
||||
endif() |
||||
if(WITH_FUNC_TESTS) |
||||
add_subdirectory(functional) |
||||
endif() |
||||
endif() |
||||
|
||||
include(cmake/opentelemetry-build-external-component.cmake) |
||||
include(cmake/patch-imported-config.cmake) |
||||
|
||||
if(OPENTELEMETRY_INSTALL) |
||||
# Install the cmake config and version files |
||||
otel_install_cmake_config() |
||||
|
||||
# Install the components and associated files |
||||
otel_install_components() |
||||
|
||||
# Install the thirdparty dependency definition file |
||||
otel_install_thirdparty_definitions() |
||||
|
||||
if(BUILD_PACKAGE) |
||||
include(cmake/package.cmake) |
||||
include(CPack) |
||||
endif() |
||||
endif() |
||||
@ -0,0 +1,126 @@
|
||||
{ |
||||
"configurations": [ |
||||
{ |
||||
"name": "nostd-x64-Debug", |
||||
"generator": "Ninja", |
||||
"configurationType": "Debug", |
||||
"inheritEnvironments": [ |
||||
"msvc_x64_x64" |
||||
], |
||||
"buildRoot": "${projectDir}\\out\\vs2019\\${name}", |
||||
"installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", |
||||
"cmakeCommandArgs": "", |
||||
"buildCommandArgs": "", |
||||
"ctestCommandArgs": "", |
||||
"variables": [ |
||||
{ |
||||
"name": "WITH_OTLP_GRPC", |
||||
"value": "True", |
||||
"type": "BOOL" |
||||
}, |
||||
{ |
||||
"name": "WITH_EXAMPLES", |
||||
"value": "true", |
||||
"type": "BOOL" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"name": "nostd-x64-Release", |
||||
"generator": "Ninja", |
||||
"configurationType": "Release", |
||||
"inheritEnvironments": [ |
||||
"msvc_x64_x64" |
||||
], |
||||
"buildRoot": "${projectDir}\\out\\vs2019\\${name}", |
||||
"installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", |
||||
"cmakeCommandArgs": "", |
||||
"buildCommandArgs": "", |
||||
"ctestCommandArgs": "", |
||||
"cmakeToolchain": "", |
||||
"variables": [ |
||||
{ |
||||
"name": "WITH_OTLP_GRPC", |
||||
"value": "True", |
||||
"type": "BOOL" |
||||
}, |
||||
{ |
||||
"name": "WITH_EXAMPLES", |
||||
"value": "true", |
||||
"type": "BOOL" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"name": "stdlib-x64-Debug", |
||||
"generator": "Ninja", |
||||
"configurationType": "Debug", |
||||
"inheritEnvironments": [ |
||||
"msvc_x64_x64" |
||||
], |
||||
"buildRoot": "${projectDir}\\out\\vs2019\\${name}", |
||||
"installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", |
||||
"cmakeCommandArgs": "", |
||||
"buildCommandArgs": "", |
||||
"ctestCommandArgs": "", |
||||
"variables": [ |
||||
{ |
||||
"name": "WITH_STL", |
||||
"value": "True", |
||||
"type": "BOOL" |
||||
}, |
||||
{ |
||||
"name": "WITH_OTLP_GRPC", |
||||
"value": "True", |
||||
"type": "BOOL" |
||||
}, |
||||
{ |
||||
"name": "WITH_EXAMPLES", |
||||
"value": "true", |
||||
"type": "BOOL" |
||||
}, |
||||
{ |
||||
"name": "WITH_PROMETHEUS", |
||||
"value": "True", |
||||
"type": "BOOL" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"name": "stdlib-x64-Release", |
||||
"generator": "Ninja", |
||||
"configurationType": "Release", |
||||
"inheritEnvironments": [ |
||||
"msvc_x64_x64" |
||||
], |
||||
"buildRoot": "${projectDir}\\out\\vs2019\\${name}", |
||||
"installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", |
||||
"cmakeCommandArgs": "", |
||||
"buildCommandArgs": "", |
||||
"ctestCommandArgs": "", |
||||
"cmakeToolchain": "", |
||||
"variables": [ |
||||
{ |
||||
"name": "WITH_STL", |
||||
"value": "True", |
||||
"type": "BOOL" |
||||
}, |
||||
{ |
||||
"name": "WITH_OTLP_GRPC", |
||||
"value": "True", |
||||
"type": "BOOL" |
||||
}, |
||||
{ |
||||
"name": "WITH_EXAMPLES", |
||||
"value": "true", |
||||
"type": "BOOL" |
||||
}, |
||||
{ |
||||
"name": "WITH_PROMETHEUS", |
||||
"value": "True", |
||||
"type": "BOOL" |
||||
} |
||||
] |
||||
} |
||||
] |
||||
} |
||||
@ -0,0 +1,3 @@
|
||||
# OpenTelemetry Community Code of Conduct |
||||
|
||||
OpenTelemetry follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). |
||||
@ -0,0 +1,322 @@
|
||||
# Contributing to opentelemetry-cpp |
||||
|
||||
The OpenTelemetry C/C++ special interest group (SIG) meets regularly. See the |
||||
OpenTelemetry [community](https://github.com/open-telemetry/community#cc-sdk) |
||||
repo for information on this and other language SIGs. |
||||
|
||||
See the [public meeting |
||||
notes](https://docs.google.com/document/d/1i1E4-_y4uJ083lCutKGDhkpi3n4_e774SBLi9hPLocw/edit) |
||||
for a summary description of past meetings. To request edit access, join the |
||||
meeting or get in touch on |
||||
[Slack](https://cloud-native.slack.com/archives/C01N3AT62SJ). |
||||
|
||||
See the [community membership |
||||
document](https://github.com/open-telemetry/community/blob/main/community-membership.md) |
||||
on how to become a |
||||
[**Member**](https://github.com/open-telemetry/community/blob/main/community-membership.md#member), |
||||
[**Approver**](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) |
||||
and |
||||
[**Maintainer**](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer). |
||||
|
||||
## Development |
||||
|
||||
OpenTelemetry C++ uses the [Google naming |
||||
convention](https://google.github.io/styleguide/cppguide.html#Naming). |
||||
|
||||
Code is formatted automatically and enforced by CI. |
||||
|
||||
### Build and Run Code Examples |
||||
|
||||
Note: these instructions apply to examples configured with Bazel, see |
||||
example-specific documentation for other build automation tools. |
||||
|
||||
Install the latest bazel version by following the steps listed |
||||
[here](https://docs.bazel.build/versions/master/install.html). |
||||
|
||||
Select an example of interest from the [examples |
||||
folder](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/examples). |
||||
Inside each example directory is a `BUILD` file containing instructions for |
||||
Bazel. Find the binary name of your example by inspecting the contents of this |
||||
`BUILD` file. |
||||
|
||||
Build the example from the root of the opentelemetry-cpp directory using Bazel. |
||||
Replace `<binary name>` with the identifier found in the previous step: |
||||
|
||||
```sh |
||||
bazel build //examples/<example directory name>:<binary name> |
||||
``` |
||||
|
||||
Run the resulting executable to see telemetry from the application as it calls |
||||
the instrumented library: </li> |
||||
|
||||
```sh |
||||
bazel-bin/examples/<example directory name>/<binary name> |
||||
``` |
||||
|
||||
For instance, building and running the `simple` example can be done as follows: |
||||
|
||||
```sh |
||||
bazel build //examples/simple:example_simple |
||||
bazel-bin/examples/simple/example_simple |
||||
``` |
||||
|
||||
### DevContainer Setup for Project |
||||
|
||||
This guide provides instructions on how to set up and use the development |
||||
container (`devcontainer`) environment to streamline testing and development |
||||
for this project. With the DevContainer, you can work in a consistent environment |
||||
configured with all the necessary dependencies and tools. |
||||
|
||||
#### Prerequisites |
||||
|
||||
Before getting started, ensure you have the following installed: |
||||
|
||||
* **Docker**: DevContainers require Docker for containerization. |
||||
* **Visual Studio Code (VSCode)** with the **Remote - Containers** extension. |
||||
|
||||
#### Getting Started |
||||
|
||||
* **Open the Project in DevContainer**: |
||||
|
||||
Open the project in VSCode. When prompted to "Reopen in Container," select |
||||
this option. If you’re not prompted, you can manually open the container by |
||||
selecting **Remote-Containers: Reopen in Container** from the command palette |
||||
(`F1` or `Ctrl+Shift+P`). |
||||
|
||||
* **Container Setup**: |
||||
|
||||
The DevContainer environment will automatically build based on the configuration |
||||
files provided (e.g., `.devcontainer/devcontainer.json`). This setup will install |
||||
required dependencies, tools, and environment variables needed for the project. |
||||
|
||||
* **Container Customization**: |
||||
See `.devcontainer/README.md` for devcontainer configuration options. |
||||
|
||||
#### Available Commands |
||||
|
||||
Once inside the DevContainer, you can use the following commands to run tests |
||||
and CI workflows. |
||||
|
||||
##### 1. Run Tests with Bazelisk |
||||
|
||||
To run tests with Bazelisk using specific compilation options, use: |
||||
|
||||
```bash |
||||
bazelisk-linux-amd64 test --copt=-DENABLE_LOGS_PREVIEW |
||||
--test_output=errors --cache_test_results=no --copt=-DENABLE_TEST //exporters/otlp/... |
||||
``` |
||||
|
||||
###### Command Breakdown |
||||
|
||||
* `--copt=-DENABLE_LOGS_PREVIEW`: Enables preview logs. |
||||
* `--test_output=errors`: Shows only the errors in the test output. |
||||
* `--cache_test_results=no`: Forces Bazel to re-run tests without caching. |
||||
* `--copt=-DENABLE_TEST`: Enables testing capabilities for the target code. |
||||
* `//exporters/otlp/...`: Specifies the test target path. |
||||
|
||||
##### 2. Run CI Script |
||||
|
||||
You can also run the CI script provided to perform testing with the |
||||
following command as an |
||||
example: |
||||
|
||||
```bash |
||||
bash ci/do_ci.sh cmake.exporter.otprotocol.test |
||||
``` |
||||
|
||||
This command initiates the CI pipeline, executing tests specifically for the |
||||
**cmake.exporter.otprotocol** module. |
||||
|
||||
#### Troubleshooting |
||||
|
||||
If you encounter issues: |
||||
|
||||
* **Rebuild the DevContainer**: From the command palette, run |
||||
**Remote-Containers: Rebuild Container** to reinitialize the environment. |
||||
* **Check Bazelisk and CI Script Logs**: Inspect logs for any configuration or |
||||
dependency issues. |
||||
|
||||
#### Additional Notes |
||||
|
||||
* You can adjust compiler options (`--copt`) as needed to test additional flags |
||||
or enable/disable specific features. |
||||
* The test results will be displayed in the terminal within the DevContainer for |
||||
easy debugging. |
||||
|
||||
#### Resources |
||||
|
||||
* **Bazelisk Documentation**: [https://github.com/bazelbuild/bazelisk](https://github.com/bazelbuild/bazelisk) |
||||
* **VSCode DevContainer Documentation**: [https://code.visualstudio.com/docs/remote/containers](https://code.visualstudio.com/docs/remote/containers) |
||||
|
||||
### Docker Development Image |
||||
|
||||
The `.devcontainer/Dockerfile.dev` |
||||
dockerfile can be built directly with the following command. |
||||
|
||||
```sh |
||||
docker build -t opentelemetry-cpp-dev -f ./.devcontainer/Dockerfile.dev . |
||||
``` |
||||
|
||||
You can customize the image using build arguments |
||||
to match permissions with the host user. |
||||
|
||||
```sh |
||||
docker build -t opentelemetry-cpp-dev \ |
||||
--build-arg USER_UID="$(id -u)" \ |
||||
--build-arg USER_GID="$(id -g)" \ |
||||
-f ./.devcontainer/Dockerfile.dev . |
||||
|
||||
``` |
||||
|
||||
Run an interactive bash session binding your host |
||||
opentelemetry-cpp directory to the container's workspace: |
||||
|
||||
```sh |
||||
docker run -it -v "$PWD:/workspaces/opentelemetry-cpp" opentelemetry-cpp-dev bash |
||||
``` |
||||
|
||||
## Pull Requests |
||||
|
||||
### How to Send Pull Requests |
||||
|
||||
Everyone is welcome to contribute code to `opentelemetry-cpp` via GitHub pull |
||||
requests (PRs). |
||||
|
||||
To create a new PR, fork the project in GitHub and clone the upstream repo: |
||||
|
||||
```sh |
||||
git clone --recursive https://github.com/open-telemetry/opentelemetry-cpp.git |
||||
``` |
||||
|
||||
Add your fork as a remote: |
||||
|
||||
```sh |
||||
git remote add fork https://github.com/YOUR_GITHUB_USERNAME/opentelemetry-cpp.git |
||||
``` |
||||
|
||||
If you haven't, make sure you are loading the submodules required to build |
||||
OpenTelemetry |
||||
|
||||
```sh |
||||
git submodule init |
||||
git submodule update |
||||
``` |
||||
|
||||
The source code is automatically formatted using clang-format. |
||||
|
||||
The output can vary between versions, so make sure to install `clang-format` |
||||
version `10.0`, and have `clang-format-10` in your execution path, |
||||
so that the helper script `tools/format.sh` can find it. |
||||
|
||||
Check out a new branch, make modifications and push the branch to your fork: |
||||
|
||||
```sh |
||||
git checkout -b feature |
||||
# edit files |
||||
tools/format.sh |
||||
git commit |
||||
git push fork feature |
||||
``` |
||||
|
||||
If you made changes to the Markdown documents (`*.md` files), install the latest |
||||
[`markdownlint-cli`](https://github.com/igorshubovych/markdownlint-cli) and run: |
||||
|
||||
```sh |
||||
markdownlint . |
||||
``` |
||||
|
||||
If you modified shell scripts (`*.sh` files), install `shellcheck` and run: |
||||
|
||||
```sh |
||||
shellcheck --severity=error <path to shell script>.sh |
||||
``` |
||||
|
||||
Open a pull request against the main `opentelemetry-cpp` repo. |
||||
|
||||
To run tests locally, please read the [CI instructions](ci/README.md). |
||||
|
||||
### How to Receive Comments |
||||
|
||||
* If the PR is not ready for review, please put `[WIP]` in the title, tag it as |
||||
`work-in-progress`, or mark it as |
||||
[`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/). |
||||
* Make sure [CLA](https://identity.linuxfoundation.org/projects/cncf) is signed |
||||
and CI is clear. |
||||
* For non-trivial changes, please update the [CHANGELOG](./CHANGELOG.md). |
||||
|
||||
### How to Get PRs Merged |
||||
|
||||
A PR is considered to be **ready to merge** when: |
||||
|
||||
* It has received two approvals with at least one approval from |
||||
[Approver](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) |
||||
/ |
||||
[Maintainer](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer) |
||||
(at different company). |
||||
* A pull request opened by an Approver / Maintainer can be merged with only one |
||||
approval from Approver / Maintainer (at different company). |
||||
* Major feedback items/points are resolved. |
||||
* It has been open for review for at least one working day. This gives people |
||||
reasonable time to review. |
||||
* Trivial changes (typo, cosmetic, doc, etc.) don't have to wait for one day. |
||||
* Urgent fixes can take exceptions as long as it has been actively communicated. |
||||
|
||||
Any Maintainer can merge the PR once it is **ready to merge**. Maintainer can |
||||
make conscious judgement to merge pull requests which have not strictly met |
||||
above mentioned requirements. |
||||
|
||||
If a PR has been stuck (e.g. there are lots of debates and people couldn't agree |
||||
on each other), the owner should try to get people aligned by: |
||||
|
||||
* Consolidating the perspectives and putting a summary in the PR. It is |
||||
recommended to add a link into the PR description, which points to a comment |
||||
with a summary in the PR conversation |
||||
* Stepping back to see if it makes sense to narrow down the scope of the PR or |
||||
split it up. |
||||
|
||||
If none of the above worked and the PR has been stuck for more than 2 weeks, the |
||||
owner should bring it to the OpenTelemetry C++ SIG meeting. See |
||||
[README.md](README.md#contributing) for the meeting link. |
||||
|
||||
## Design Choices |
||||
|
||||
As with other OpenTelemetry clients, opentelemetry-cpp follows the |
||||
[opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification). |
||||
|
||||
It's especially valuable to read through the [library |
||||
guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/library-guidelines.md). |
||||
|
||||
## Useful Resources |
||||
|
||||
Hi! If you’re looking at this document, these resources will provide you the |
||||
knowledge to get started as a newcomer to the OpenTelemetry project. They will |
||||
help you understand the OpenTelemetry Project, its components, and specifically |
||||
the C++ repository. |
||||
|
||||
### Reading Resources |
||||
|
||||
* Medium |
||||
[article](https://medium.com/opentelemetry/how-to-start-contributing-to-opentelemetry-b23991ad91f4) |
||||
(October 2019) on how to start contributing to the OpenTelemetry project. |
||||
* Medium |
||||
[article](https://medium.com/opentelemetry/opentelemetry-beyond-getting-started-5ac43cd0fe26) |
||||
(January 2020) describing the overarching goals and use cases for |
||||
OpenTelemetry. |
||||
|
||||
### Relevant Documentation |
||||
|
||||
* [OpenTelemetry |
||||
Specification](https://github.com/open-telemetry/opentelemetry-specification) |
||||
* The OpenTelemetry Specification describes the requirements and expectations |
||||
of for all OpenTelemetry implementations. |
||||
|
||||
* Read through the OpenTelemetry C++ documentation |
||||
* The |
||||
[API](https://opentelemetry-cpp.readthedocs.io/en/latest/api/api.html) |
||||
and |
||||
[SDK](https://opentelemetry-cpp.readthedocs.io/en/latest/sdk/sdk.html) |
||||
documentation provides a lot of information on what the classes and their |
||||
functions are used for. |
||||
|
||||
Please contribute! You’re welcome to add more information if you come across any |
||||
helpful resources. |
||||
@ -0,0 +1,139 @@
|
||||
# Deprecated |
||||
|
||||
This document lists all the items currently deprecated in opentelemetry-cpp. |
||||
|
||||
Deprecated items will be removed in the future. |
||||
|
||||
## Guidelines |
||||
|
||||
### Maintainer guidelines |
||||
|
||||
See the [deprecation-process](./docs/deprecation-process.md) |
||||
|
||||
## [TEMPLATE] |
||||
|
||||
### New Deprecation Title (Template) |
||||
|
||||
#### Announcement (Template) |
||||
|
||||
#### Motivation (Template) |
||||
|
||||
#### Scope (Template) |
||||
|
||||
#### Mitigation (Template) |
||||
|
||||
#### Planned removal (Template) |
||||
|
||||
## [Platforms] |
||||
|
||||
N/A |
||||
|
||||
## [Compilers] |
||||
|
||||
N/A |
||||
|
||||
## [Third party dependencies] |
||||
|
||||
N/A |
||||
|
||||
## [Build tools] |
||||
|
||||
N/A |
||||
|
||||
## [Build scripts] |
||||
|
||||
N/A |
||||
|
||||
## [opentelemetry-cpp API] |
||||
|
||||
N/A |
||||
|
||||
## [opentelemetry-cpp SDK] |
||||
|
||||
N/A |
||||
|
||||
## [opentelemetry-cpp Exporter] |
||||
|
||||
N/A |
||||
|
||||
## [Documentation] |
||||
|
||||
N/A |
||||
|
||||
## Semantic conventions |
||||
|
||||
### Header files "semantic_conventions.h" |
||||
|
||||
#### Announcement (semantic_conventions.h) |
||||
|
||||
Deprecation is announced as part of the migration to weaver: |
||||
|
||||
* `Version:` release following opentelemetry-cpp 1.17.0 |
||||
* `Date:` Nov 9, 2024 |
||||
* `PR:` [PR 3105](https://github.com/open-telemetry/opentelemetry-cpp/pull/3105) |
||||
|
||||
#### Motivation (semantic_conventions.h) |
||||
|
||||
The header files for semantic conventions are generated automatically. |
||||
The tooling to generate these files is changing: |
||||
|
||||
* before, the build-tool repository was used |
||||
* now, the weaver repository is used |
||||
|
||||
Changes in tooling allows to generate code that is better organized, |
||||
with dedicated header files per group of semantic conventions, |
||||
instead of a single header file for everything. |
||||
|
||||
#### Scope (semantic_conventions.h) |
||||
|
||||
The following files: |
||||
|
||||
* `api/include/opentelemetry/trace/semantic_conventions.h` |
||||
* `sdk/include/opentelemetry/sdk/resource/semantic_conventions.h` |
||||
|
||||
are now deprecated. |
||||
|
||||
They correspond to semantic conventions v1.27.0, |
||||
and will no longer be maintained up to date. |
||||
|
||||
These files will be removed in the future. |
||||
|
||||
#### Mitigation (semantic_conventions.h) |
||||
|
||||
Two things have changed: |
||||
|
||||
* the header file to use |
||||
* the symbol name to use. |
||||
|
||||
Before, the semantic convention for `url.full` was: |
||||
|
||||
* declared in file `semantic_conventions.h` |
||||
* declared as symbol `SemanticConventions::kUrlFull` |
||||
|
||||
Now, the `url.full` convention, which is part or the `url` group, is: |
||||
|
||||
* declared in file `semconv/url_attributes.h` |
||||
* declared as symbol `semconv::url::kUrlFull` |
||||
|
||||
Application code that uses semantic conventions must be adjusted |
||||
accordingly. |
||||
|
||||
In addition, semantic conventions that are not marked as stable |
||||
are generated in a different header file, placed under directory |
||||
`incubating`, to better separate stable and non stable code. |
||||
|
||||
For example, file `semconv/incubating/url_attributes.h` |
||||
defines `semconv::url::kUrlDomain`, |
||||
which is not marked as stable in semconv v1.27.0 |
||||
|
||||
#### Planned removal (semantic_conventions.h) |
||||
|
||||
The following files: |
||||
|
||||
* `api/include/opentelemetry/trace/semantic_conventions.h` |
||||
* `sdk/include/opentelemetry/sdk/resource/semantic_conventions.h` |
||||
|
||||
will be removed. |
||||
|
||||
The removal date is planned for July 1, 2025. |
||||
This allows more than six months for applications to adjust. |
||||
@ -0,0 +1,452 @@
|
||||
# Building opentelemetry-cpp |
||||
|
||||
[CMake](https://cmake.org/) and [Bazel](https://bazel.build) are the official |
||||
build systems for opentelemetry-cpp. |
||||
|
||||
## Dependencies |
||||
|
||||
You can link OpenTelemetry C++ SDK with libraries provided in |
||||
[dependencies.md](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/docs/dependencies.md) |
||||
(complete list of libraries with versions used in our CI can be found |
||||
[here](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/third_party_release)). |
||||
|
||||
## Build instructions using CMake |
||||
|
||||
### Prerequisites for CMake build |
||||
|
||||
- A supported platform (e.g. Windows, macOS or Linux). Refer to [Platforms |
||||
Supported](./README.md#supported-development-platforms) for more information. |
||||
- A compatible C++ compiler supporting at least C++14. Major compilers are |
||||
supported. Refer to [Supported Compilers](./README.md#supported-c-versions) |
||||
for more information. |
||||
- [Git](https://git-scm.com/) for fetching opentelemetry-cpp source code from |
||||
repository. To install Git, consult the [Set up |
||||
Git](https://help.github.com/articles/set-up-git/) guide on GitHub. |
||||
- [CMake](https://cmake.org/) for building opentelemetry-cpp API, SDK with their |
||||
unittests. The minimum CMake version is 3.14. |
||||
CMake 3.15+ is recommended on Windows due to known CI test failures with 3.14. |
||||
To install CMake, |
||||
consult the [Installing CMake](https://cmake.org/install/) guide. |
||||
- [GoogleTest](https://github.com/google/googletest) framework to build and run |
||||
the unittests. Refer to |
||||
[third_party_release](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/third_party_release#L5) |
||||
for version of GoogleTest used in CI. To install GoogleTest, consult the |
||||
[GoogleTest Build |
||||
Instructions](https://github.com/google/googletest/blob/master/googletest/README.md#generic-build-instructions). |
||||
- [Google Benchmark](https://github.com/google/benchmark) framework to build and |
||||
run benchmark tests. Refer to |
||||
[third_party_release](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/third_party_release#L4) |
||||
for version of Benchmark used in CI. To install Benchmark, consult the |
||||
[GoogleBenchmark Build |
||||
Instructions](https://github.com/google/benchmark#installation). |
||||
- Apart from above core requirements, the Exporters and Propagators have their |
||||
build dependencies. |
||||
|
||||
### Building dependencies for the OTLP exporters |
||||
|
||||
The opentelemetry-cpp OTLP exporters depend on Protobuf and gRPC |
||||
(in the case of the otlp grpc exporters). |
||||
Protobuf (since version 3.22.0) and gRPC depend on Abseil. |
||||
For cmake builds, it is best practice to build and install Abseil |
||||
, Protobuf, and gPRC as independent packages - |
||||
configuring cmake for Protobuf and gRPC to build against |
||||
the installed packages instead of using their submodule option. |
||||
|
||||
If building and installing Protobuf and gRPC manually with cmake the |
||||
recommended approach is: |
||||
|
||||
1. Choose the desired tag version of grpc. Find the compatible versions of abseil |
||||
and protobuf by inspecting the submodules of grpc at that tag. |
||||
2. Build and install the required version of abseil |
||||
3. Build and install the required version of protobuf |
||||
- Set the cmake option of Protobuf to build against the installed |
||||
package of Abseil (`protobuf_ABSL_PROVIDER=package`) |
||||
4. Build and install the required version of grpc |
||||
- Set the cmake option of grpc to build against the installed packages |
||||
of Abseil and Protobuf (cmake options - `gRPC_ABSL_PROVIDER=package` and `gRPC_PROTOBUF_PROVIDER=package`) |
||||
|
||||
### Building as standalone CMake Project |
||||
|
||||
1. Getting the opentelemetry-cpp source with its submodules: |
||||
|
||||
```console |
||||
# Change to the directory where you want to create the code repository |
||||
$ cd ~ |
||||
$ mkdir source && cd source && git clone --recurse-submodules https://github.com/open-telemetry/opentelemetry-cpp |
||||
Cloning into 'opentelemetry-cpp'... |
||||
... |
||||
Resolving deltas: 100% (3225/3225), done. |
||||
$ |
||||
``` |
||||
|
||||
2. Navigate to the repository cloned above, and create the `CMake` build |
||||
configuration. |
||||
|
||||
```console |
||||
$ cd opentelemetry-cpp |
||||
$ mkdir build && cd build && cmake .. |
||||
-- The C compiler identification is GNU 9.3.0 |
||||
-- The CXX compiler identification is GNU 9.3.0 |
||||
... |
||||
-- Configuring done |
||||
-- Generating done |
||||
-- Build files have been written to: /home/<user>/source/opentelemetry-cpp/build |
||||
$ |
||||
``` |
||||
|
||||
Some of the available cmake build variables we can use during cmake |
||||
configuration: |
||||
|
||||
- `-DCMAKE_POSITION_INDEPENDENT_CODE=ON` : Please note that with default |
||||
configuration, the code is compiled without `-fpic` option, so it is not |
||||
suitable for inclusion in shared libraries. To enable the code for |
||||
inclusion in shared libraries, this variable is used. |
||||
- `-DBUILD_SHARED_LIBS=ON` : To build shared libraries for the targets. |
||||
Please refer to note [below](#building-shared-libs-for-windows) for |
||||
Windows DLL support. |
||||
- `-DWITH_OTLP_GRPC=ON` : To enable building OTLP GRPC exporter. |
||||
- `-DWITH_OTLP_HTTP=ON` : To enable building OTLP HTTP exporter. |
||||
- `-DWITH_PROMETHEUS=ON` : To enable building prometheus exporter. |
||||
- `-DOPENTELEMETRY_INSTALL=ON`: To install `otel-cpp` library needed |
||||
for external code linking. |
||||
|
||||
3. Once the build configuration is created, build the CMake targets - this |
||||
includes building SDKs and unittests for API and SDK. Note that since API is |
||||
header only library, no separate build is triggered for it. |
||||
|
||||
```console |
||||
$ cmake --build . --target all |
||||
Scanning dependencies of target timestamp_test |
||||
[ 0%] Building CXX object api/test/core/CMakeFiles/timestamp_test.dir/timestamp_test.cc.o |
||||
[ 1%] Linking CXX executable timestamp_test |
||||
... |
||||
Scanning dependencies of target w3c_tracecontext_test |
||||
[ 99%] Building CXX object ext/test/w3c_tracecontext_test/CMakeFiles/w3c_tracecontext_test.dir/main.cc.o |
||||
[100%] Linking CXX executable w3c_tracecontext_test |
||||
[100%] Built target w3c_tracecontext_test |
||||
$ |
||||
``` |
||||
|
||||
4. Once CMake tests are built, run them with `ctest` command |
||||
|
||||
```console |
||||
$ ctest |
||||
Test project /tmp/opentelemetry-cpp/build |
||||
Start 1: trace.SystemTimestampTest.Construction |
||||
... |
||||
Start 380: ext.http.urlparser.UrlParserTests.BasicTests |
||||
... |
||||
100% tests passed, 0 tests failed out of 380 |
||||
$ |
||||
``` |
||||
|
||||
5. Optionally install the header files for API, and generated targets and header |
||||
files for SDK at custom/default install location. |
||||
|
||||
```console |
||||
$ cmake --install . --prefix /<install-root>/ |
||||
-- Installing: /<install-root>/lib/cmake/opentelemetry-cpp/opentelemetry-cpp-config.cmake |
||||
-- Installing: /<install-root>/lib/cmake/opentelemetry-cpp/opentelemetry-cpp-config-version.cmake |
||||
... |
||||
$ |
||||
``` |
||||
|
||||
### Incorporating into an external CMake Project |
||||
|
||||
There are two approaches to incoporate `opentelemetry-cpp` into |
||||
an external CMake project: |
||||
|
||||
1. Build and install `opentelemetry-cpp` then use `find_package` |
||||
to import its targets |
||||
|
||||
```cmake |
||||
# Find all installed components and link all imported targets |
||||
find_package(opentelemetry-cpp CONFIG REQUIRED) |
||||
... |
||||
target_include_directories(foo PRIVATE ${OPENTELEMETRY_CPP_INCLUDE_DIRS}) |
||||
target_link_libraries(foo PRIVATE ${OPENTELEMETRY_CPP_LIBRARIES}) |
||||
``` |
||||
|
||||
```cmake |
||||
# Find a specific component and link its imported target(s) |
||||
find_package(opentelemetry-cpp CONFIG REQUIRED COMPONENTS api) |
||||
... |
||||
target_link_libraries(foo PRIVATE opentelemetry-cpp::api) |
||||
``` |
||||
|
||||
2. Use CMake's [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) |
||||
module to fetch and build `opentelemetry-cpp` then make its targets available |
||||
|
||||
```cmake |
||||
# Fetch from an existing clone and build |
||||
include(FetchContent) |
||||
FetchContent_Declare(opentelemetry-cpp SOURCE_DIR "<path/to/opentelemetry-cpp>") |
||||
FetchContent_MakeAvailable(opentelemetry-cpp) |
||||
... |
||||
target_link_libraries(foo PRIVATE opentelemetry-cpp::api) |
||||
``` |
||||
|
||||
```cmake |
||||
# Clone and build opentelemetry-cpp from a git tag |
||||
include(FetchContent) |
||||
FetchContent_Declare( |
||||
opentelemetry-cpp |
||||
GIT_REPOSITORY https://github.com/open-telemetry/opentelemetry-cpp.git |
||||
GIT_TAG v1.20.0) |
||||
FetchContent_MakeAvailable(opentelemetry-cpp) |
||||
... |
||||
target_link_libraries(foo PRIVATE opentelemetry-cpp::api) |
||||
``` |
||||
|
||||
In both cases the project's built or imported CMake targets will be |
||||
available in the `opentelemetry-cpp` namespace (ie: `opentelemetry-cpp::api`) |
||||
|
||||
#### Using opentelemetry-cpp package components |
||||
|
||||
> **Note:** `opentelemetry-cpp` CMake package components were introduced in `v1.21.0` |
||||
|
||||
The `opentelemetry-cpp` package supports using the `COMPONENTS` argument to |
||||
`find_package`. The following example illustrates using this feature to include |
||||
and link the `api` header only target to an instrumented `foo_lib` while only including |
||||
and linking the `sdk` and `otlp_grpc_exporter` targets to the `foo_app`. |
||||
|
||||
```cmake |
||||
# foo_lib/CMakeLists.txt |
||||
find_package(opentelemetry-cpp CONFIG REQUIRED COMPONENTS api) |
||||
add_library(foo_lib foo.cpp) |
||||
target_link_libraries(foo_lib PRIVATE opentelemetry-cpp::api) |
||||
``` |
||||
|
||||
```cmake |
||||
# foo_app/CMakeLists.txt |
||||
find_package(opentelemetry-cpp CONFIG REQUIRED COMPONENTS api sdk exporters_otlp_grpc) |
||||
add_executable(foo_app main.cpp) |
||||
target_link_libraries(foo_app PRIVATE foo_lib opentelemetry-cpp::api opentelemetry-cpp::trace opentelemetry-cpp::otlp_grpc_exporter ) |
||||
``` |
||||
|
||||
The following table provides the mapping between components and targets. Components |
||||
and targets available in the installation depends on the opentelemetry-cpp package |
||||
build configuration. |
||||
|
||||
> **Note:** components `exporters_elasticsearch` and `exporters_etw` |
||||
may be moved out of the core package and to `opentelemetry-cpp-contrib` |
||||
in a future release |
||||
|
||||
| Component | Targets | |
||||
|----------------------------|--------------------------------------------------------------------------------------------------| |
||||
| **api** | opentelemetry-cpp::api | |
||||
| **sdk** | opentelemetry-cpp::sdk | |
||||
| | opentelemetry-cpp::version | |
||||
| | opentelemetry-cpp::common | |
||||
| | opentelemetry-cpp::resources | |
||||
| | opentelemetry-cpp::trace | |
||||
| | opentelemetry-cpp::metrics | |
||||
| | opentelemetry-cpp::logs | |
||||
| **ext_common** | opentelemetry-cpp::ext | |
||||
| **ext_http_curl** | opentelemetry-cpp::http_client_curl | |
||||
| **ext_dll** | opentelemetry-cpp::opentelemetry_cpp | |
||||
| **exporters_in_memory** | opentelemetry-cpp::in_memory_span_exporter | |
||||
| | opentelemetry-cpp::in_memory_metric_exporter | |
||||
| **exporters_ostream** | opentelemetry-cpp::ostream_log_record_exporter | |
||||
| | opentelemetry-cpp::ostream_metrics_exporter | |
||||
| | opentelemetry-cpp::ostream_span_exporter | |
||||
| **exporters_otlp_common** | opentelemetry-cpp::proto | |
||||
| | opentelemetry-cpp::otlp_recordable | |
||||
| **exporters_otlp_file** | opentelemetry-cpp::otlp_file_client | |
||||
| | opentelemetry-cpp::otlp_file_exporter | |
||||
| | opentelemetry-cpp::otlp_file_log_record_exporter | |
||||
| | opentelemetry-cpp::otlp_file_metric_exporter | |
||||
| **exporters_otlp_grpc** | opentelemetry-cpp::proto_grpc | |
||||
| | opentelemetry-cpp::otlp_grpc_client | |
||||
| | opentelemetry-cpp::otlp_grpc_exporter | |
||||
| | opentelemetry-cpp::otlp_grpc_log_record_exporter | |
||||
| | opentelemetry-cpp::otlp_grpc_metrics_exporter | |
||||
| **exporters_otlp_http** | opentelemetry-cpp::otlp_http_client | |
||||
| | opentelemetry-cpp::otlp_http_exporter | |
||||
| | opentelemetry-cpp::otlp_http_log_record_exporter | |
||||
| | opentelemetry-cpp::otlp_http_metric_exporter | |
||||
| **exporters_prometheus** | opentelemetry-cpp::prometheus_exporter | |
||||
| **exporters_elasticsearch**| opentelemetry-cpp::elasticsearch_log_record_exporter | |
||||
| **exporters_etw** | opentelemetry-cpp::etw_exporter | |
||||
| **exporters_zipkin** | opentelemetry-cpp::zipkin_trace_exporter | |
||||
| **shims_opentracing** | opentelemetry-cpp::opentracing_shim | |
||||
|
||||
## Build instructions using Bazel |
||||
|
||||
NOTE: Experimental, and not supported for all the components. Make sure the |
||||
[GoogleTest](https://github.com/google/googletest) installation may fail if |
||||
there is a different version of googletest already installed in system-defined |
||||
path. |
||||
|
||||
### Prerequisites for Bazel build |
||||
|
||||
- A supported platform (e.g. Windows, macOS or Linux). Refer to [Platforms |
||||
Supported](./README.md#supported-development-platforms) for more information. |
||||
- A compatible C++ compiler supporting at least C++14. Major compilers are |
||||
supported. Refer to [Supported Compilers](./README.md#supported-c-versions) for |
||||
more information. |
||||
- [Git](https://git-scm.com/) for fetching opentelemetry-cpp source code from |
||||
repository. To install Git, consult the [Set up |
||||
Git](https://help.github.com/articles/set-up-git/) guide on GitHub. |
||||
- [Bazel](https://www.bazel.build/) for building opentelemetry-cpp API, SDK with |
||||
their unittests. We use 3.7.2 in our build system. |
||||
|
||||
To install Bazel, consult the [Installing |
||||
Bazel](https://docs.bazel.build/versions/3.7.0/install.html) guide. |
||||
|
||||
### Building as standalone Bazel Project |
||||
|
||||
1. Getting the opentelemetry-cpp source: |
||||
|
||||
```console |
||||
# Change to the directory where you want to create the code repository |
||||
$ cd ~ |
||||
$ mkdir source && cd source |
||||
$ git clone https://github.com/open-telemetry/opentelemetry-cpp |
||||
Cloning into 'opentelemetry-cpp'... |
||||
... |
||||
Resolving deltas: 100% (3225/3225), done. |
||||
$ |
||||
``` |
||||
|
||||
2. Navigate to the repository cloned above, download the dependencies and build |
||||
the source code: |
||||
|
||||
```console |
||||
$ cd opentelemetry-cpp |
||||
$ bazel build //... |
||||
bazel build -- //... -//exporters/otlp/... -//exporters/prometheus/... |
||||
Extracting Bazel installation... |
||||
Starting local Bazel server and connecting to it... |
||||
INFO: Analyzed 121 targets (98 packages loaded, 3815 targets configured). |
||||
INFO: Found 121 targets... |
||||
INFO: From Compiling sdk/src/trace/tracer_context.cc: |
||||
... |
||||
|
||||
``` |
||||
|
||||
3. Once Bazel tests are built, run them with `bazel test //...` command |
||||
|
||||
```console |
||||
$ bazel test //... |
||||
.. |
||||
$ |
||||
``` |
||||
|
||||
4. The build artifacts will be located under `bazel-bin` |
||||
|
||||
### Incorporating into an existing Bazel Project |
||||
|
||||
- WORKSPACE file: |
||||
|
||||
```console |
||||
http_archive( |
||||
name = "io_opentelemetry_cpp", |
||||
sha256 = "<sha256>", |
||||
strip_prefix = "opentelemetry-cpp-1.0.1", |
||||
urls = [ |
||||
"https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v1.0.1.tar.gz" |
||||
], |
||||
) |
||||
|
||||
# Load OpenTelemetry dependencies after load. |
||||
load("@io_opentelemetry_cpp//bazel:repository.bzl", "opentelemetry_cpp_deps") |
||||
|
||||
opentelemetry_cpp_deps() |
||||
|
||||
# (required after v1.8.0) Load extra dependencies required for OpenTelemetry |
||||
load("@io_opentelemetry_cpp//bazel:extra_deps.bzl", "opentelemetry_extra_deps") |
||||
|
||||
opentelemetry_extra_deps() |
||||
|
||||
# Load gRPC dependencies after load. |
||||
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps") |
||||
|
||||
grpc_deps() |
||||
|
||||
# Load extra gRPC dependencies due to https://github.com/grpc/grpc/issues/20511 |
||||
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps") |
||||
|
||||
grpc_extra_deps() |
||||
|
||||
``` |
||||
|
||||
- Component level BUILD file: |
||||
|
||||
```console |
||||
cc_library( |
||||
name = "<name>" |
||||
... |
||||
deps = [ |
||||
"@io_opentelemetry_cpp//api", |
||||
"@io_opentelemetry_cpp//exporters/otlp:otlp_exporter", |
||||
"@io_opentelemetry_cpp//sdk/src/trace", |
||||
... |
||||
], |
||||
... |
||||
) |
||||
``` |
||||
|
||||
## Building shared libs for Windows |
||||
|
||||
Windows DLL build is supported under **preview**. Please check the |
||||
[doc](./docs/build-as-dll.md) for more details. |
||||
|
||||
## Generating binary packages |
||||
|
||||
OpenTelemetry C++ supports generating platform specific binary packages from CMake |
||||
configuration. The packages generated through this mayn't be production ready, |
||||
and user may have to customize it further before using it as distribution. |
||||
|
||||
- Linux : deb, rpm, tgz |
||||
- MacOS : tgz |
||||
- Windows : NuGet, zip |
||||
|
||||
This requires platform specific package generators already installed. The package |
||||
generation can subsequently be enabled by using BUILD_PACKAGE option during cmake |
||||
configuration |
||||
|
||||
```console |
||||
$ cd opentelemetry-cpp |
||||
$ mkdir build && cd build && cmake -DBUILD_PACKAGE=ON .. |
||||
|
||||
-- Package name: opentelemetry-cpp-1.8.1-ubuntu-20.04-x86_64.deb |
||||
-- Configuring done |
||||
-- Generating done |
||||
... |
||||
$ |
||||
``` |
||||
|
||||
Once build is complete as specified in [standalone build section](#building-as-standalone-cmake-project), |
||||
the package can be generated as below. |
||||
|
||||
```console |
||||
$ cpack -C debug |
||||
CPack: Create package using DEB |
||||
... |
||||
CPack: - package: /home/<user>/opentelemetry-cpp/build/opentelemetry-cpp-1.8.1-ubuntu-20.04-x86_64.deb generated. |
||||
$ |
||||
``` |
||||
|
||||
## Using Package Managers |
||||
|
||||
If you are using [Conan](https://www.conan.io/) to manage your dependencies, add |
||||
[`opentelemetry-cpp/x.y.z`](https://conan.io/center/opentelemetry-cpp) to your |
||||
`conanfile`'s requires, where `x.y.z` is the release version you want to use. |
||||
Please file issues [here](https://github.com/conan-io/conan-center-index/issues) |
||||
if you experience problems with the packages. |
||||
|
||||
If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project |
||||
for external dependencies, then you can install the [opentelemetry-cpp |
||||
package](https://github.com/microsoft/vcpkg/tree/master/ports/opentelemetry-cpp) |
||||
with `vcpkg install opentelemetry-cpp` and follow the then displayed |
||||
descriptions. Please see the vcpkg project for any issues regarding the |
||||
packaging. |
||||
|
||||
If you are using [alpine linux](https://www.alpinelinux.org/) you can install |
||||
the [opentelemetry-cpp packages](https://pkgs.alpinelinux.org/packages?name=opentelemetry-cpp-*) |
||||
with `apk add -X http://dl-cdn.alpinelinux.org/alpine/edge/testing opentelemetry-cpp-dev`. |
||||
|
||||
Please note, these packages are not officially provided and maintained by |
||||
OpenTelemetry C++ project, and are just listed here to consolidate all such |
||||
efforts for ease of developers. |
||||
@ -0,0 +1,201 @@
|
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
http://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
APPENDIX: How to apply the Apache License to your work. |
||||
|
||||
To apply the Apache License to your work, attach the following |
||||
boilerplate notice, with the fields enclosed by brackets "[]" |
||||
replaced with your own identifying information. (Don't include |
||||
the brackets!) The text should be enclosed in the appropriate |
||||
comment syntax for the file format. We also recommend that a |
||||
file or class name and description of purpose be included on the |
||||
same "printed page" as the copyright notice for easier |
||||
identification within third-party archives. |
||||
|
||||
Copyright [yyyy] [name of copyright owner] |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
@ -0,0 +1,25 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
module( |
||||
name = "opentelemetry-cpp", |
||||
version = "1.21.0", |
||||
compatibility_level = 0, |
||||
repo_name = "io_opentelemetry_cpp", |
||||
) |
||||
|
||||
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "com_google_absl") |
||||
bazel_dep(name = "bazel_skylib", version = "1.5.0") |
||||
bazel_dep(name = "curl", version = "8.8.0") |
||||
bazel_dep(name = "grpc", version = "1.63.1.bcr.1", repo_name = "com_github_grpc_grpc") |
||||
bazel_dep(name = "nlohmann_json", version = "3.12.0", repo_name = "github_nlohmann_json") |
||||
bazel_dep(name = "opentelemetry-proto", version = "1.6.0", repo_name = "com_github_opentelemetry_proto") |
||||
bazel_dep(name = "opentracing-cpp", version = "1.6.0", repo_name = "com_github_opentracing") |
||||
bazel_dep(name = "platforms", version = "0.0.8") |
||||
bazel_dep(name = "prometheus-cpp", version = "1.3.0", repo_name = "com_github_jupp0r_prometheus_cpp") |
||||
bazel_dep(name = "protobuf", version = "26.0", repo_name = "com_google_protobuf") |
||||
bazel_dep(name = "rules_proto", version = "5.3.0-21.7") |
||||
bazel_dep(name = "zlib", version = "1.3.1.bcr.1") |
||||
|
||||
bazel_dep(name = "google_benchmark", version = "1.8.3", dev_dependency = True, repo_name = "com_github_google_benchmark") |
||||
bazel_dep(name = "googletest", version = "1.14.0.bcr.1", dev_dependency = True, repo_name = "com_google_googletest") |
||||
@ -0,0 +1,127 @@
|
||||
# OpenTelemetry C++ |
||||
|
||||
[](https://cloud-native.slack.com/archives/C01N3AT62SJ) |
||||
[](https://codecov.io/gh/open-telemetry/opentelemetry-cpp/) |
||||
[](https://github.com/open-telemetry/opentelemetry-cpp/actions) |
||||
[](https://github.com/open-telemetry/opentelemetry-cpp/releases/) |
||||
[](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-cpp?ref=badge_shield&issueType=license) |
||||
[](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-cpp?ref=badge_shield&issueType=security) |
||||
|
||||
The C++ [OpenTelemetry](https://opentelemetry.io/) client. |
||||
|
||||
## Project Status |
||||
|
||||
**Stable** across all 3 signals i.e. `Logs`, `Metrics`, and `Traces`. |
||||
|
||||
See [Spec Compliance |
||||
Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md) |
||||
to understand which portions of the specification has been implemented in this |
||||
repo. |
||||
|
||||
## Supported C++ Versions |
||||
|
||||
Code shipped from this repository generally supports the following versions of |
||||
C++ standards: |
||||
|
||||
* ISO/IEC 14882:2014 (C++14) |
||||
* ISO/IEC 14882:2017 (C++17) |
||||
* ISO/IEC 14882:2020 (C++20) |
||||
|
||||
Any exceptions to this are noted in the individual `README.md` files. |
||||
|
||||
Please note that supporting the [C Programming |
||||
Language](https://en.wikipedia.org/wiki/C_(programming_language)) is not a goal |
||||
of the current project. |
||||
|
||||
## Supported Development Platforms |
||||
|
||||
Our CI pipeline builds and tests on following `x86-64` platforms: |
||||
|
||||
| Platform | Build type | |
||||
|---------------------------------------------------------------------|---------------| |
||||
| ubuntu-22.04 (GCC 10, GCC 12, Clang 14) | CMake, Bazel | |
||||
| ubuntu-20.04 (GCC 9.4.0 - default compiler) | CMake, Bazel | |
||||
| ubuntu-20.04 (GCC 9.4.0 with -std=c++14/17/20 flags) | CMake, Bazel | |
||||
| macOS 12.7 (Xcode 14.2) | Bazel | |
||||
| Windows Server 2019 (Visual Studio Enterprise 2019) | CMake, Bazel | |
||||
| Windows Server 2022 (Visual Studio Enterprise 2022) | CMake | |
||||
|
||||
In general, the code shipped from this repository should build on all platforms |
||||
having C++ compiler with [supported C++ standards](#supported-c-versions). |
||||
|
||||
## Dependencies |
||||
|
||||
Please refer to [Dependencies.md](docs/dependencies.md) for OSS Dependencies and |
||||
license requirements. |
||||
|
||||
## Installation |
||||
|
||||
Please refer to [INSTALL.md](./INSTALL.md). |
||||
|
||||
## Getting Started |
||||
|
||||
As an application owner or the library author, you can find the getting started |
||||
guide and reference documentation on |
||||
[opentelemetry-cpp.readthedocs.io](https://opentelemetry-cpp.readthedocs.io/en/latest/) |
||||
|
||||
The `examples/simple` directory contains a minimal program demonstrating how to |
||||
instrument a small library using a simple `processor` and console `exporter`, |
||||
along with build files for CMake and Bazel. |
||||
|
||||
## Contributing |
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md) |
||||
|
||||
We meet weekly, and the time of the meeting alternates between Monday at 13:00 |
||||
PT and Wednesday at 9:00 PT. The meeting is subject to change depending on |
||||
contributors' availability. Check the [OpenTelemetry community |
||||
calendar](https://github.com/open-telemetry/community#calendar) |
||||
for specific dates and Zoom meeting links. |
||||
|
||||
Meeting notes are available as a public [Google |
||||
doc](https://docs.google.com/document/d/1i1E4-_y4uJ083lCutKGDhkpi3n4_e774SBLi9hPLocw/edit?usp=sharing). |
||||
For edit access, get in touch on |
||||
[Slack](https://cloud-native.slack.com/archives/C01N3AT62SJ). |
||||
|
||||
[Maintainers](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer) |
||||
([@open-telemetry/cpp-maintainers](https://github.com/orgs/open-telemetry/teams/cpp-maintainers)): |
||||
|
||||
* [Ehsan Saei](https://github.com/esigo) |
||||
* [Lalit Kumar Bhasin](https://github.com/lalitb), Microsoft |
||||
* [Marc Alff](https://github.com/marcalff), Oracle |
||||
* [Tom Tan](https://github.com/ThomsonTan), Microsoft |
||||
|
||||
[Approvers](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) |
||||
([@open-telemetry/cpp-approvers](https://github.com/orgs/open-telemetry/teams/cpp-approvers)): |
||||
|
||||
* [Doug Barker](https://github.com/dbarker) |
||||
* [Josh Suereth](https://github.com/jsuereth), Google |
||||
* [Pranav Sharma](https://github.com/psx95), Google |
||||
* [WenTao Ou](https://github.com/owent), Tencent |
||||
|
||||
[Emeritus |
||||
Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): |
||||
|
||||
* [Alolita Sharma](https://github.com/alolita) |
||||
* [Emil Mikulic](https://github.com/g-easy) |
||||
* [Jodee Varney](https://github.com/jodeev) |
||||
* [Johannes Tax](https://github.com/pyohannes) |
||||
* [Max Golovanov](https://github.com/maxgolov) |
||||
* [Reiley Yang](https://github.com/reyang) |
||||
* [Ryan Burn](https://github.com/rnburn) |
||||
|
||||
### Thanks to all the people who have contributed |
||||
|
||||
[](https://github.com/open-telemetry/opentelemetry-cpp/graphs/contributors) |
||||
|
||||
## Release Schedule |
||||
|
||||
See the [release |
||||
notes](https://github.com/open-telemetry/opentelemetry-cpp/releases) for |
||||
existing releases. |
||||
|
||||
See the [project |
||||
milestones](https://github.com/open-telemetry/opentelemetry-cpp/milestones) for |
||||
details on upcoming releases. The dates and features described in issues and |
||||
milestones are estimates, and subject to change. |
||||
@ -0,0 +1,96 @@
|
||||
# Release Process |
||||
|
||||
## Pre Release |
||||
|
||||
1: Upgrade to latest [dependencies](docs/maintaining-dependencies.md) |
||||
if required. |
||||
|
||||
2: Make sure all relevant changes for this release are included under |
||||
`Unreleased` section in `CHANGELOG.md` and are in language that non-contributors |
||||
to the project can understand. |
||||
|
||||
3: Run the pre-release script. It creates a branch `pre_release_<new-tag>` and |
||||
updates `CHANGELOG.md` with the `<new-tag>`: |
||||
|
||||
```sh |
||||
./buildscripts/pre_release.sh -t <new-tag> |
||||
``` |
||||
|
||||
4: Verify that CHANGELOG.md is updated properly: |
||||
|
||||
```sh |
||||
git diff main |
||||
``` |
||||
|
||||
5: Push the changes to upstream and create a Pull Request on GitHub. Be sure to |
||||
include the curated changes from the [Changelog](./CHANGELOG.md) in the |
||||
description. |
||||
|
||||
## Tag |
||||
|
||||
Once the above Pull Request has been approved and merged it is time to tag the |
||||
merged commit. |
||||
|
||||
***IMPORTANT***: It is critical you use the same tag that you used in the |
||||
Pre-Release step! Failure to do so will leave things in a broken state. |
||||
|
||||
1: Note down the commit hash of the master branch after above PR request is |
||||
merged: `<commit-hash>` |
||||
|
||||
```sh |
||||
git show -s --format=%H |
||||
``` |
||||
|
||||
2: Create a github tag on this commit hash: |
||||
|
||||
```sh |
||||
git tag -a "<new-tag>" -s -m "Version <new-tag>" "<commit-hash>" |
||||
``` |
||||
|
||||
3: Push tag to upstream remote |
||||
|
||||
```sh |
||||
git push upstream |
||||
``` |
||||
|
||||
## Versioning |
||||
|
||||
Once tag is created, it's time to use that tag for Runtime Versioning |
||||
|
||||
1: Create a new brach for updating version information in |
||||
`./sdk/src/version.cc`. |
||||
|
||||
```sh |
||||
git checkout -b update_version_${tag} master |
||||
``` |
||||
|
||||
2: Run the pre-commit script to update the version: |
||||
|
||||
```sh |
||||
./buildscripts/pre-commit |
||||
``` |
||||
|
||||
3: Check if any changes made since last release broke ABI compatibility. If yes, |
||||
update `OPENTELEMETRY_ABI_VERSION_NO` in |
||||
[version.h](api/include/opentelemetry/version.h). |
||||
|
||||
4: Push the changes to upstream and create a Pull Request on GitHub. |
||||
|
||||
5: Once changes are merged, move the tag created earlier to the new commit hash |
||||
from step 4. |
||||
|
||||
```sh |
||||
git tag -f <previous-tag> <new-commit-hash> |
||||
git push --tags --force |
||||
``` |
||||
|
||||
## Release |
||||
|
||||
Finally create a Release for the new `<new-tag>` on GitHub. The release body |
||||
should include all the release notes from the Changelog for this release. |
||||
|
||||
## Post Release |
||||
|
||||
Update the OpenTelemetry.io document |
||||
[here](https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/instrumentation/cpp) |
||||
by sending a Pull Request. |
||||
@ -0,0 +1,107 @@
|
||||
# Versioning |
||||
|
||||
This document describes the versioning policy for this repository. |
||||
|
||||
## Goals |
||||
|
||||
### API and SDK Compatibility |
||||
|
||||
Once the API for a given signal (spans, logs, metrics, baggage) has been |
||||
officially released, that API module will function with any SDK that has the |
||||
same MAJOR version and equal or greater MINOR or PATCH version. For example, |
||||
application compiled with API v1.1 is compatible with SDK v1.1.2, v1.2.0, etc. |
||||
|
||||
For example, libraries that are instrumented with `opentelemetry 1.0.1` will |
||||
function in applications using `opentelemetry 1.11.33` or `opentelemetry 1.3.4`, |
||||
buy may not work in applications using `opentelemetry 2.0.0`. |
||||
|
||||
### ABI Stability |
||||
|
||||
Refer to the [ABI Policy](./docs/abi-policy.md) for more details. To summarise: |
||||
|
||||
* The API is header only, and uses ABI compliant interfaces. However, ABI |
||||
stability is not guaranteed for SDK. |
||||
* In case of ABI breaking changes, a new `inline namespace` version will be |
||||
introduced, and the existing linked applications can continue using the older |
||||
version unless they relink with newer version. |
||||
|
||||
## Release Policy |
||||
|
||||
* Release versions will follow [SemVer 2.0](https://semver.org/). |
||||
* Only a single source package containing the API, SDK, and exporters which are |
||||
required by the specification would be released. All these components are |
||||
always versioned and released together. For example, any changes in one of the |
||||
exporter would result in version update of the entire source package even |
||||
though there is no changes in API, SDK and other exporters. |
||||
* Experimental releases: New (unstable) telemetry signals and features will be |
||||
introduced behind feature flag protected by a preprocessor macro. |
||||
|
||||
```cpp |
||||
#ifdef FEATURE_FLAG |
||||
<metrics api/sdk definitions> |
||||
#endif |
||||
``` |
||||
|
||||
As we deliver the package in source form, and the user is responsible to build |
||||
it for their platform, the user must be aware of these feature flags |
||||
(documented in the [CHANGELOG.md](CHANGELOG.md) file). The user must enable |
||||
them explicitly through their build system (CMake, Bazel or others) to use any |
||||
preview features. |
||||
|
||||
The guidelines in creating feature flag would be: |
||||
|
||||
* Naming: |
||||
* `ENABLE_<SIGNAL>_PREVIEW` : For experimental release of signal api/sdks |
||||
eg, `METRICS_PREVIEW`, `LOGS_PREVIEW`, |
||||
* `ENABLE_<SIGNAL>_<FEATURE_NAME>_PREVIEW` : For experimental release for |
||||
any feature within stable signal. For example, `TRACING_JAEGER_PREVIEW` to |
||||
release the experimental Jaeger exporter for tracing. |
||||
* Cleanup: It is good practice to keep feature-flags as shortlived as |
||||
possible. And, also important to keep the number of them low. They should be |
||||
used such that it is easy to remove/cleanup them once the experimental |
||||
feature is stable. |
||||
|
||||
* New signals will be stabilized via a **minor version bump**, and are not |
||||
allowed to break existing stable interfaces. Feature flags will be removed |
||||
once we have a stable implementation for the signal. |
||||
|
||||
* As an exception, small experimental features in otherwise stable |
||||
signals/components mayn't necessarily be released under feature flag. These |
||||
would be flagged as experimental by adding a `NOTE` in it's header file - |
||||
either at the beginning of file, or as the comment for the experimental API |
||||
methods. Also, if the complete header is experimental, it would be prefixed as |
||||
`experimental_`. As an example, the semantic conventions for trace signal is |
||||
experimental at the time of the writing and is within |
||||
`experimental_semantic_conventions.h` |
||||
|
||||
* Code under the "*::detail" namespace implements internal details, and is NOT |
||||
part of public interface. Also, any API not documented in the [public |
||||
documentation](https://opentelemetry-cpp.readthedocs.io/en/latest/) is NOT |
||||
part of the public interface. |
||||
|
||||
* GitHub releases will be made for all released versions. |
||||
|
||||
## Example Versioning Lifecycle |
||||
|
||||
Purely for illustration purposes, not intended to represent actual releases: |
||||
|
||||
* v0.0.1 release: |
||||
* Contains experimental API and SDK of trace (without feature flag) |
||||
* No API and SDK of logging and metrics available |
||||
* v1.0.0-rc1 release: |
||||
* Pre-release, no API/ABI guarantees, but more stable than alpha/beta. |
||||
* Contains pre-release API and SDK of trace, baggage and resource |
||||
* experimental metrics and logging API/SDK behind feature flag |
||||
* v1.0.0: ( with traces ) |
||||
* Contains stable API and SDK of trace, baggage and resource |
||||
* experimental metrics and logging API/SDK behind feature flag |
||||
* v1.5.0 release (with metrics) |
||||
* Contains stable API and SDK of metrics, trace, baggage, resource. |
||||
* experimental logging API/SDK behind feature flag |
||||
* v1.10.0 release (with logging) |
||||
* Contains stable API and SDK of logging, metrics, trace, baggage, resource. |
||||
|
||||
### Before moving to version 1.0.0 |
||||
|
||||
* Major version zero (0.y.z) is for initial development. Anything MAY change at |
||||
any time. The public API SHOULD NOT be considered stable. |
||||
@ -0,0 +1,23 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
workspace(name = "io_opentelemetry_cpp") |
||||
|
||||
# Load our direct dependencies. |
||||
load("//bazel:repository.bzl", "opentelemetry_cpp_deps") |
||||
|
||||
opentelemetry_cpp_deps() |
||||
|
||||
load("//bazel:extra_deps.bzl", "opentelemetry_extra_deps") |
||||
|
||||
opentelemetry_extra_deps() |
||||
|
||||
# Load gRPC dependencies after load. |
||||
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps") |
||||
|
||||
grpc_deps() |
||||
|
||||
# Load extra gRPC dependencies due to https://github.com/grpc/grpc/issues/20511 |
||||
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps") |
||||
|
||||
grpc_extra_deps() |
||||
@ -0,0 +1,4 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
# Disables the default WORKSPACE when using bzlmod |
||||
@ -0,0 +1,81 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "int_flag", "string_flag") |
||||
|
||||
package(default_visibility = ["//visibility:public"]) |
||||
|
||||
CPP_STDLIBS = [ |
||||
"none", |
||||
"best", |
||||
"2014", |
||||
"2017", |
||||
"2020", |
||||
"2023", |
||||
] |
||||
|
||||
string_flag( |
||||
name = "with_cxx_stdlib", |
||||
build_setting_default = "best", |
||||
values = CPP_STDLIBS, |
||||
) |
||||
|
||||
cc_library( |
||||
name = "api", |
||||
hdrs = glob(["include/**/*.h"]), |
||||
defines = select({ |
||||
":set_cxx_stdlib_none": [], |
||||
### automatic selection |
||||
":set_cxx_stdlib_best": ["OPENTELEMETRY_STL_VERSION=(__cplusplus/100)"], |
||||
# See https://learn.microsoft.com/en-us/cpp/build/reference/zc-cplusplus |
||||
":set_cxx_stdlib_best_and_msvc": ["OPENTELEMETRY_STL_VERSION=(_MSVC_LANG/100)"], |
||||
### manual selection |
||||
":set_cxx_stdlib_2014": ["OPENTELEMETRY_STL_VERSION=2014"], |
||||
":set_cxx_stdlib_2017": ["OPENTELEMETRY_STL_VERSION=2017"], |
||||
":set_cxx_stdlib_2020": ["OPENTELEMETRY_STL_VERSION=2020"], |
||||
":set_cxx_stdlib_2023": ["OPENTELEMETRY_STL_VERSION=2023"], |
||||
"//conditions:default": [], |
||||
}) + select({ |
||||
":abi_version_no_1": ["OPENTELEMETRY_ABI_VERSION_NO=1"], |
||||
":abi_version_no_2": ["OPENTELEMETRY_ABI_VERSION_NO=2"], |
||||
}), |
||||
strip_include_prefix = "include", |
||||
tags = ["api"], |
||||
deps = [ |
||||
"@com_google_absl//absl/base", |
||||
"@com_google_absl//absl/strings", |
||||
"@com_google_absl//absl/types:variant", |
||||
], |
||||
) |
||||
|
||||
[config_setting( |
||||
name = "set_cxx_stdlib_%s" % v, |
||||
flag_values = {":with_cxx_stdlib": v}, |
||||
) for v in CPP_STDLIBS] |
||||
|
||||
config_setting( |
||||
name = "set_cxx_stdlib_best_and_msvc", |
||||
constraint_values = ["@bazel_tools//tools/cpp:msvc"], |
||||
flag_values = {":with_cxx_stdlib": "best"}, |
||||
) |
||||
|
||||
bool_flag( |
||||
name = "with_abseil", |
||||
build_setting_default = False, |
||||
deprecation = "The value of this flag is ignored. Bazel builds always depend on Abseil for its pre-adopted `std::` types. You should remove this flag from your build command.", |
||||
) |
||||
|
||||
int_flag( |
||||
name = "abi_version_no", |
||||
build_setting_default = 1, |
||||
) |
||||
|
||||
config_setting( |
||||
name = "abi_version_no_1", |
||||
flag_values = {":abi_version_no": "1"}, |
||||
) |
||||
|
||||
config_setting( |
||||
name = "abi_version_no_2", |
||||
flag_values = {":abi_version_no": "2"}, |
||||
) |
||||
@ -0,0 +1,140 @@
|
||||
# Copyright The OpenTelemetry Authors |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
add_library(opentelemetry_api INTERFACE) |
||||
target_include_directories( |
||||
opentelemetry_api |
||||
INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>" |
||||
"$<INSTALL_INTERFACE:include>") |
||||
|
||||
set_target_properties(opentelemetry_api PROPERTIES EXPORT_NAME api) |
||||
|
||||
otel_add_component( |
||||
COMPONENT |
||||
api |
||||
TARGETS |
||||
opentelemetry_api |
||||
FILES_DIRECTORY |
||||
"include/opentelemetry" |
||||
FILES_DESTINATION |
||||
"include" |
||||
FILES_MATCHING |
||||
PATTERN |
||||
"*.h") |
||||
|
||||
if(OPENTELEMETRY_INSTALL) |
||||
unset(TARGET_DEPS) |
||||
endif() |
||||
|
||||
if(BUILD_TESTING) |
||||
add_subdirectory(test) |
||||
endif() |
||||
|
||||
if(WITH_NO_DEPRECATED_CODE) |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE OPENTELEMETRY_NO_DEPRECATED_CODE) |
||||
endif() |
||||
|
||||
if(WITH_STL STREQUAL "OFF") |
||||
message(STATUS "Building WITH_STL=OFF") |
||||
elseif(WITH_STL STREQUAL "CXX11") |
||||
message(STATUS "Building WITH_STL=CXX11") |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE OPENTELEMETRY_STL_VERSION=2011) |
||||
elseif(WITH_STL STREQUAL "CXX14") |
||||
message(STATUS "Building WITH_STL=CXX14") |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE OPENTELEMETRY_STL_VERSION=2014) |
||||
elseif(WITH_STL STREQUAL "CXX17") |
||||
message(STATUS "Building WITH_STL=CXX17") |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE OPENTELEMETRY_STL_VERSION=2017) |
||||
elseif(WITH_STL STREQUAL "CXX20") |
||||
message(STATUS "Building WITH_STL=CXX20") |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE OPENTELEMETRY_STL_VERSION=2020) |
||||
elseif(WITH_STL STREQUAL "CXX23") |
||||
message(STATUS "Building WITH_STL=CXX23") |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE OPENTELEMETRY_STL_VERSION=2023) |
||||
elseif(WITH_STL STREQUAL "ON") |
||||
message(STATUS "Building WITH_STL=ON") |
||||
# "ON" corresponds to "CXX23" at this time. |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE OPENTELEMETRY_STL_VERSION=2023) |
||||
else() |
||||
message( |
||||
FATAL_ERROR "WITH_STL must be ON, OFF, CXX11, CXX14, CXX17, CXX20 or CXX23") |
||||
endif() |
||||
|
||||
if(WITH_GSL) |
||||
target_compile_definitions(opentelemetry_api INTERFACE HAVE_GSL) |
||||
|
||||
# Guidelines Support Library path. Used if we are not on not get C++20. |
||||
# |
||||
find_package(Microsoft.GSL QUIET) |
||||
if(TARGET Microsoft.GSL::GSL) |
||||
target_link_libraries(opentelemetry_api INTERFACE Microsoft.GSL::GSL) |
||||
list(APPEND TARGET_DEPS "gsl") |
||||
else() |
||||
set(GSL_DIR third_party/ms-gsl) |
||||
target_include_directories( |
||||
opentelemetry_api INTERFACE "$<BUILD_INTERFACE:${GSL_DIR}/include>") |
||||
endif() |
||||
endif() |
||||
|
||||
if(WITH_NO_GETENV) |
||||
target_compile_definitions(opentelemetry_api INTERFACE NO_GETENV) |
||||
endif() |
||||
|
||||
if(WIN32) |
||||
if(WITH_ETW) |
||||
target_compile_definitions(opentelemetry_api INTERFACE HAVE_MSGPACK) |
||||
endif() |
||||
endif() |
||||
|
||||
if(WITH_ASYNC_EXPORT_PREVIEW) |
||||
target_compile_definitions(opentelemetry_api INTERFACE ENABLE_ASYNC_EXPORT) |
||||
endif() |
||||
|
||||
target_compile_definitions( |
||||
opentelemetry_api |
||||
INTERFACE OPENTELEMETRY_ABI_VERSION_NO=${OPENTELEMETRY_ABI_VERSION_NO}) |
||||
|
||||
if(WITH_OTLP_RETRY_PREVIEW) |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE ENABLE_OTLP_RETRY_PREVIEW) |
||||
endif() |
||||
|
||||
if(WITH_OTLP_GRPC_SSL_MTLS_PREVIEW) |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE ENABLE_OTLP_GRPC_SSL_MTLS_PREVIEW) |
||||
endif() |
||||
|
||||
if(WITH_METRICS_EXEMPLAR_PREVIEW) |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE ENABLE_METRICS_EXEMPLAR_PREVIEW) |
||||
endif() |
||||
|
||||
if(WITH_THREAD_INSTRUMENTATION_PREVIEW) |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE ENABLE_THREAD_INSTRUMENTATION_PREVIEW) |
||||
endif() |
||||
|
||||
if(WITH_OTLP_HTTP_COMPRESSION) |
||||
target_compile_definitions(opentelemetry_api |
||||
INTERFACE ENABLE_OTLP_COMPRESSION_PREVIEW) |
||||
endif() |
||||
|
||||
if(APPLE) |
||||
target_link_libraries(opentelemetry_api INTERFACE "-framework CoreFoundation") |
||||
endif() |
||||
|
||||
include(${PROJECT_SOURCE_DIR}/cmake/pkgconfig.cmake) |
||||
|
||||
if(OPENTELEMETRY_INSTALL) |
||||
opentelemetry_add_pkgconfig( |
||||
api "OpenTelemetry API" |
||||
"A header-only library to support instrumentation with OpenTelemetry." |
||||
"${TARGET_DEPS}") |
||||
endif() |
||||
@ -0,0 +1,299 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <cctype> |
||||
|
||||
#include "opentelemetry/common/kv_properties.h" |
||||
#include "opentelemetry/common/macros.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
|
||||
namespace baggage |
||||
{ |
||||
|
||||
class OPENTELEMETRY_EXPORT Baggage |
||||
{ |
||||
public: |
||||
static constexpr size_t kMaxKeyValuePairs = 180; |
||||
static constexpr size_t kMaxKeyValueSize = 4096; |
||||
static constexpr size_t kMaxSize = 8192; |
||||
static constexpr char kKeyValueSeparator = '='; |
||||
static constexpr char kMembersSeparator = ','; |
||||
static constexpr char kMetadataSeparator = ';'; |
||||
|
||||
Baggage() noexcept : kv_properties_(new common::KeyValueProperties()) {} |
||||
Baggage(size_t size) noexcept : kv_properties_(new common::KeyValueProperties(size)) {} |
||||
|
||||
template <class T> |
||||
Baggage(const T &keys_and_values) noexcept |
||||
: kv_properties_(new common::KeyValueProperties(keys_and_values)) |
||||
{} |
||||
|
||||
OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr<Baggage> GetDefault() |
||||
{ |
||||
static nostd::shared_ptr<Baggage> baggage{new Baggage()}; |
||||
return baggage; |
||||
} |
||||
|
||||
/* Get value for key in the baggage
|
||||
@returns true if key is found, false otherwise |
||||
*/ |
||||
bool GetValue(nostd::string_view key, std::string &value) const noexcept |
||||
{ |
||||
return kv_properties_->GetValue(key, value); |
||||
} |
||||
|
||||
/* Returns shared_ptr of new baggage object which contains new key-value pair. If key or value is
|
||||
invalid, copy of current baggage is returned |
||||
*/ |
||||
nostd::shared_ptr<Baggage> Set(const nostd::string_view &key, |
||||
const nostd::string_view &value) noexcept |
||||
{ |
||||
|
||||
nostd::shared_ptr<Baggage> baggage(new Baggage(kv_properties_->Size() + 1)); |
||||
const bool valid_kv = IsValidKey(key) && IsValidValue(value); |
||||
|
||||
if (valid_kv) |
||||
{ |
||||
baggage->kv_properties_->AddEntry(key, value); |
||||
} |
||||
|
||||
// add rest of the fields.
|
||||
kv_properties_->GetAllEntries( |
||||
[&baggage, &key, &valid_kv](nostd::string_view e_key, nostd::string_view e_value) { |
||||
// if key or value was not valid, add all the entries. Add only remaining entries
|
||||
// otherwise.
|
||||
if (!valid_kv || key != e_key) |
||||
{ |
||||
baggage->kv_properties_->AddEntry(e_key, e_value); |
||||
} |
||||
|
||||
return true; |
||||
}); |
||||
|
||||
return baggage; |
||||
} |
||||
|
||||
// @return all key-values entries by repeatedly invoking the function reference passed as argument
|
||||
// for each entry
|
||||
bool GetAllEntries( |
||||
nostd::function_ref<bool(nostd::string_view, nostd::string_view)> callback) const noexcept |
||||
{ |
||||
return kv_properties_->GetAllEntries(callback); |
||||
} |
||||
|
||||
// delete key from the baggage if it exists. Returns shared_ptr of new baggage object.
|
||||
// if key does not exist, copy of current baggage is returned.
|
||||
// Validity of key is not checked as invalid keys should never be populated in baggage in the
|
||||
// first place.
|
||||
nostd::shared_ptr<Baggage> Delete(nostd::string_view key) noexcept |
||||
{ |
||||
// keeping size of baggage same as key might not be found in it
|
||||
nostd::shared_ptr<Baggage> baggage(new Baggage(kv_properties_->Size())); |
||||
kv_properties_->GetAllEntries( |
||||
[&baggage, &key](nostd::string_view e_key, nostd::string_view e_value) { |
||||
if (key != e_key) |
||||
baggage->kv_properties_->AddEntry(e_key, e_value); |
||||
return true; |
||||
}); |
||||
return baggage; |
||||
} |
||||
|
||||
// Returns shared_ptr of baggage after extracting key-value pairs from header
|
||||
static nostd::shared_ptr<Baggage> FromHeader(nostd::string_view header) noexcept |
||||
{ |
||||
if (header.size() > kMaxSize) |
||||
{ |
||||
// header size exceeds maximum threshold, return empty baggage
|
||||
return GetDefault(); |
||||
} |
||||
|
||||
common::KeyValueStringTokenizer kv_str_tokenizer(header); |
||||
size_t cnt = kv_str_tokenizer.NumTokens(); // upper bound on number of kv pairs
|
||||
if (cnt > kMaxKeyValuePairs) |
||||
{ |
||||
cnt = kMaxKeyValuePairs; |
||||
} |
||||
|
||||
nostd::shared_ptr<Baggage> baggage(new Baggage(cnt)); |
||||
bool kv_valid; |
||||
nostd::string_view key, value; |
||||
|
||||
while (kv_str_tokenizer.next(kv_valid, key, value) && baggage->kv_properties_->Size() < cnt) |
||||
{ |
||||
if (!kv_valid || (key.size() + value.size() > kMaxKeyValueSize)) |
||||
{ |
||||
// if kv pair is not valid, skip it
|
||||
continue; |
||||
} |
||||
|
||||
// NOTE : metadata is kept as part of value only as it does not have any semantic meaning.
|
||||
// but, we need to extract it (else Decode on value will return error)
|
||||
nostd::string_view metadata; |
||||
auto metadata_separator = value.find(kMetadataSeparator); |
||||
if (metadata_separator != std::string::npos) |
||||
{ |
||||
metadata = value.substr(metadata_separator); |
||||
value = value.substr(0, metadata_separator); |
||||
} |
||||
|
||||
bool err = 0; |
||||
auto key_str = UrlDecode(common::StringUtil::Trim(key), err); |
||||
auto value_str = UrlDecode(common::StringUtil::Trim(value), err); |
||||
|
||||
if (err == false && IsValidKey(key_str) && IsValidValue(value_str)) |
||||
{ |
||||
if (!metadata.empty()) |
||||
{ |
||||
value_str.append(metadata.data(), metadata.size()); |
||||
} |
||||
baggage->kv_properties_->AddEntry(key_str, value_str); |
||||
} |
||||
} |
||||
|
||||
return baggage; |
||||
} |
||||
|
||||
// Creates string from baggage object.
|
||||
std::string ToHeader() const noexcept |
||||
{ |
||||
std::string header_s; |
||||
bool first = true; |
||||
kv_properties_->GetAllEntries([&](nostd::string_view key, nostd::string_view value) { |
||||
if (!first) |
||||
{ |
||||
header_s.push_back(kMembersSeparator); |
||||
} |
||||
else |
||||
{ |
||||
first = false; |
||||
} |
||||
header_s.append(UrlEncode(key)); |
||||
header_s.push_back(kKeyValueSeparator); |
||||
|
||||
// extracting metadata from value. We do not encode metadata
|
||||
auto metadata_separator = value.find(kMetadataSeparator); |
||||
if (metadata_separator != std::string::npos) |
||||
{ |
||||
header_s.append(UrlEncode(value.substr(0, metadata_separator))); |
||||
auto metadata = value.substr(metadata_separator); |
||||
header_s.append(std::string(metadata.data(), metadata.size())); |
||||
} |
||||
else |
||||
{ |
||||
header_s.append(UrlEncode(value)); |
||||
} |
||||
return true; |
||||
}); |
||||
return header_s; |
||||
} |
||||
|
||||
private: |
||||
static bool IsPrintableString(nostd::string_view str) |
||||
{ |
||||
for (const auto ch : str) |
||||
{ |
||||
if (ch < ' ' || ch > '~') |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
static bool IsValidKey(nostd::string_view key) { return key.size() && IsPrintableString(key); } |
||||
|
||||
static bool IsValidValue(nostd::string_view value) { return IsPrintableString(value); } |
||||
|
||||
// Uri encode key value pairs before injecting into header
|
||||
// Implementation inspired from : https://golang.org/src/net/url/url.go?s=7851:7884#L264
|
||||
static std::string UrlEncode(nostd::string_view str) |
||||
{ |
||||
auto to_hex = [](char c) -> char { |
||||
static const char *hex = "0123456789ABCDEF"; |
||||
return hex[c & 15]; |
||||
}; |
||||
|
||||
std::string ret; |
||||
|
||||
for (auto c : str) |
||||
{ |
||||
if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') |
||||
{ |
||||
ret.push_back(c); |
||||
} |
||||
else if (c == ' ') |
||||
{ |
||||
ret.push_back('+'); |
||||
} |
||||
else |
||||
{ |
||||
ret.push_back('%'); |
||||
ret.push_back(to_hex(c >> 4)); |
||||
ret.push_back(to_hex(c & 15)); |
||||
} |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
// Uri decode key value pairs after extracting from header
|
||||
static std::string UrlDecode(nostd::string_view str, bool &err) |
||||
{ |
||||
auto IsHex = [](char c) { |
||||
return std::isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); |
||||
}; |
||||
|
||||
auto from_hex = [](char c) -> char { |
||||
// c - '0' produces integer type which could trigger error/warning when casting to char,
|
||||
// but the cast is safe here.
|
||||
return static_cast<char>(std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10); |
||||
}; |
||||
|
||||
std::string ret; |
||||
|
||||
for (size_t i = 0; i < str.size(); i++) |
||||
{ |
||||
if (str[i] == '%') |
||||
{ |
||||
if (i + 2 >= str.size() || !IsHex(str[i + 1]) || !IsHex(str[i + 2])) |
||||
{ |
||||
err = 1; |
||||
return ""; |
||||
} |
||||
ret.push_back(from_hex(str[i + 1]) << 4 | from_hex(str[i + 2])); |
||||
i += 2; |
||||
} |
||||
else if (str[i] == '+') |
||||
{ |
||||
ret.push_back(' '); |
||||
} |
||||
else if (std::isalnum(str[i]) || str[i] == '-' || str[i] == '_' || str[i] == '.' || |
||||
str[i] == '~') |
||||
{ |
||||
ret.push_back(str[i]); |
||||
} |
||||
else |
||||
{ |
||||
err = 1; |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
private: |
||||
// Store entries in a C-style array to avoid using std::array or std::vector.
|
||||
nostd::unique_ptr<common::KeyValueProperties> kv_properties_; |
||||
}; |
||||
|
||||
} // namespace baggage
|
||||
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,36 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/baggage/baggage.h" |
||||
#include "opentelemetry/context/context.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
|
||||
namespace baggage |
||||
{ |
||||
|
||||
static const std::string kBaggageHeader = "baggage"; |
||||
|
||||
inline nostd::shared_ptr<Baggage> GetBaggage(const context::Context &context) noexcept |
||||
{ |
||||
context::ContextValue context_value = context.GetValue(kBaggageHeader); |
||||
if (nostd::holds_alternative<nostd::shared_ptr<Baggage>>(context_value)) |
||||
{ |
||||
return nostd::get<nostd::shared_ptr<Baggage>>(context_value); |
||||
} |
||||
static nostd::shared_ptr<Baggage> empty_baggage{new Baggage()}; |
||||
return empty_baggage; |
||||
} |
||||
|
||||
inline context::Context SetBaggage(context::Context &context, |
||||
const nostd::shared_ptr<Baggage> &baggage) noexcept |
||||
{ |
||||
return context.SetValue(kBaggageHeader, baggage); |
||||
} |
||||
|
||||
} // namespace baggage
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,60 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <memory> |
||||
#include <string> |
||||
|
||||
#include "opentelemetry/baggage/baggage.h" |
||||
#include "opentelemetry/baggage/baggage_context.h" |
||||
#include "opentelemetry/context/context.h" |
||||
#include "opentelemetry/context/propagation/text_map_propagator.h" |
||||
#include "opentelemetry/nostd/function_ref.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace baggage |
||||
{ |
||||
namespace propagation |
||||
{ |
||||
|
||||
class BaggagePropagator : public context::propagation::TextMapPropagator |
||||
{ |
||||
public: |
||||
void Inject(context::propagation::TextMapCarrier &carrier, |
||||
const context::Context &context) noexcept override |
||||
{ |
||||
auto baggage = baggage::GetBaggage(context); |
||||
auto header = baggage->ToHeader(); |
||||
if (header.size()) |
||||
{ |
||||
carrier.Set(kBaggageHeader, header); |
||||
} |
||||
} |
||||
|
||||
context::Context Extract(const context::propagation::TextMapCarrier &carrier, |
||||
context::Context &context) noexcept override |
||||
{ |
||||
nostd::string_view baggage_str = carrier.Get(baggage::kBaggageHeader); |
||||
auto baggage = baggage::Baggage::FromHeader(baggage_str); |
||||
|
||||
if (baggage->ToHeader().size()) |
||||
{ |
||||
return baggage::SetBaggage(context, baggage); |
||||
} |
||||
else |
||||
{ |
||||
return context; |
||||
} |
||||
} |
||||
|
||||
bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override |
||||
{ |
||||
return callback(kBaggageHeader); |
||||
} |
||||
}; |
||||
} // namespace propagation
|
||||
} // namespace baggage
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,82 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <cstdint> |
||||
|
||||
#include "opentelemetry/nostd/span.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/variant.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
/// OpenTelemetry signals can be enriched by adding attributes. The
|
||||
/// \c AttributeValue type is defined as a variant of all attribute value
|
||||
/// types the OpenTelemetry C++ API supports.
|
||||
///
|
||||
/// The following attribute value types are supported by the OpenTelemetry
|
||||
/// specification:
|
||||
/// - Primitive types: string, boolean, double precision floating point
|
||||
/// (IEEE 754-1985) or signed 64 bit integer.
|
||||
/// - Homogenous arrays of primitive type values.
|
||||
///
|
||||
/// \warning
|
||||
/// \parblock The OpenTelemetry C++ API currently supports several attribute
|
||||
/// value types that are not covered by the OpenTelemetry specification:
|
||||
/// - \c uint64_t
|
||||
/// - \c nostd::span<const uint64_t>
|
||||
/// - \c nostd::span<uint8_t>
|
||||
///
|
||||
/// Those types are reserved for future use and currently should not be
|
||||
/// used. There are no guarantees around how those values are handled by
|
||||
/// exporters.
|
||||
/// \endparblock
|
||||
using AttributeValue = |
||||
nostd::variant<bool, |
||||
int32_t, |
||||
int64_t, |
||||
uint32_t, |
||||
double, |
||||
const char *, |
||||
nostd::string_view, |
||||
nostd::span<const bool>, |
||||
nostd::span<const int32_t>, |
||||
nostd::span<const int64_t>, |
||||
nostd::span<const uint32_t>, |
||||
nostd::span<const double>, |
||||
nostd::span<const nostd::string_view>, |
||||
// Not currently supported by the specification, but reserved for future use.
|
||||
// Added to provide support for all primitive C++ types.
|
||||
uint64_t, |
||||
// Not currently supported by the specification, but reserved for future use.
|
||||
// Added to provide support for all primitive C++ types.
|
||||
nostd::span<const uint64_t>, |
||||
// Not currently supported by the specification, but reserved for future use.
|
||||
// See https://github.com/open-telemetry/opentelemetry-specification/issues/780
|
||||
nostd::span<const uint8_t>>; |
||||
|
||||
enum AttributeType |
||||
{ |
||||
kTypeBool, |
||||
kTypeInt, |
||||
kTypeInt64, |
||||
kTypeUInt, |
||||
kTypeDouble, |
||||
kTypeCString, |
||||
kTypeString, |
||||
kTypeSpanBool, |
||||
kTypeSpanInt, |
||||
kTypeSpanInt64, |
||||
kTypeSpanUInt, |
||||
kTypeSpanDouble, |
||||
kTypeSpanString, |
||||
kTypeUInt64, |
||||
kTypeSpanUInt64, |
||||
kTypeSpanByte |
||||
}; |
||||
|
||||
} // namespace common
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,64 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/common/attribute_value.h" |
||||
#include "opentelemetry/nostd/function_ref.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
/**
|
||||
* Supports internal iteration over a collection of key-value pairs. |
||||
*/ |
||||
class KeyValueIterable |
||||
{ |
||||
public: |
||||
virtual ~KeyValueIterable() = default; |
||||
|
||||
/**
|
||||
* Iterate over key-value pairs |
||||
* @param callback a callback to invoke for each key-value. If the callback returns false, |
||||
* the iteration is aborted. |
||||
* @return true if every key-value pair was iterated over |
||||
*/ |
||||
virtual bool ForEachKeyValue(nostd::function_ref<bool(nostd::string_view, common::AttributeValue)> |
||||
callback) const noexcept = 0; |
||||
|
||||
/**
|
||||
* @return the number of key-value pairs |
||||
*/ |
||||
virtual size_t size() const noexcept = 0; |
||||
}; |
||||
|
||||
/**
|
||||
* Supports internal iteration over a collection of key-value pairs. |
||||
*/ |
||||
class NoopKeyValueIterable : public KeyValueIterable |
||||
{ |
||||
public: |
||||
~NoopKeyValueIterable() override = default; |
||||
|
||||
/**
|
||||
* Iterate over key-value pairs |
||||
* @param callback a callback to invoke for each key-value. If the callback returns false, |
||||
* the iteration is aborted. |
||||
* @return true if every key-value pair was iterated over |
||||
*/ |
||||
bool ForEachKeyValue( |
||||
nostd::function_ref<bool(nostd::string_view, common::AttributeValue)>) const noexcept override |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
/**
|
||||
* @return the number of key-value pairs |
||||
*/ |
||||
size_t size() const noexcept override { return 0; } |
||||
}; |
||||
|
||||
} // namespace common
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,146 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <stddef.h> |
||||
#include <initializer_list> |
||||
#include <iterator> |
||||
#include <type_traits> |
||||
#include <utility> |
||||
#include <vector> |
||||
|
||||
#include "opentelemetry/common/attribute_value.h" |
||||
#include "opentelemetry/common/key_value_iterable.h" |
||||
#include "opentelemetry/nostd/function_ref.h" |
||||
#include "opentelemetry/nostd/span.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/type_traits.h" |
||||
#include "opentelemetry/nostd/utility.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
// NOTE - code within `detail` namespace implements internal details, and not part
|
||||
// of the public interface.
|
||||
namespace detail |
||||
{ |
||||
inline void take_key_value(nostd::string_view, common::AttributeValue) {} |
||||
|
||||
template <class T> |
||||
auto is_key_value_iterable_impl(T iterable) |
||||
-> decltype(take_key_value(std::begin(iterable)->first, std::begin(iterable)->second), |
||||
nostd::size(iterable), |
||||
std::true_type{}); |
||||
|
||||
std::false_type is_key_value_iterable_impl(...); |
||||
|
||||
template <class T> |
||||
struct is_key_value_iterable |
||||
{ |
||||
static const bool value = decltype(detail::is_key_value_iterable_impl(std::declval<T>()))::value; |
||||
}; |
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief Container for key-value pairs that can transform every value in it to one of types |
||||
* listed in common::AttributeValue. It may contain value types that are not directly map'able |
||||
* to primitive value types. In that case the `ForEachKeyValue` method acts as a transform to |
||||
* convert the value type to one listed under AtributeValue (bool, int32_t, int64_t, uint32_t, |
||||
* uint64_t, double, nostd::string_view, or arrays of primite types). For example, if UUID, |
||||
* GUID, or UTF-16 string type is passed as one of values stored inside this container, the |
||||
* container itself may provide a custom implementation of `ForEachKeyValue` to transform the |
||||
* 'non-standard' type to one of the standard types. |
||||
*/ |
||||
template <class T> |
||||
class KeyValueIterableView final : public KeyValueIterable |
||||
{ |
||||
|
||||
public: |
||||
explicit KeyValueIterableView(const T &container) noexcept : container_{&container} {} |
||||
|
||||
// KeyValueIterable
|
||||
bool ForEachKeyValue(nostd::function_ref<bool(nostd::string_view, common::AttributeValue)> |
||||
callback) const noexcept override |
||||
{ |
||||
auto iter = std::begin(*container_); |
||||
auto last = std::end(*container_); |
||||
for (; iter != last; ++iter) |
||||
{ |
||||
if (!callback(iter->first, iter->second)) |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
size_t size() const noexcept override { return nostd::size(*container_); } |
||||
|
||||
private: |
||||
const T *container_; |
||||
}; |
||||
|
||||
template <class T, nostd::enable_if_t<detail::is_key_value_iterable<T>::value> * = nullptr> |
||||
KeyValueIterableView<T> MakeKeyValueIterableView(const T &container) noexcept |
||||
{ |
||||
return KeyValueIterableView<T>(container); |
||||
} |
||||
|
||||
/**
|
||||
* Utility function to help to make a attribute view from initializer_list |
||||
* |
||||
* @param attributes |
||||
* @return nostd::span<const std::pair<nostd::string_view, common::AttributeValue>> |
||||
*/ |
||||
inline static nostd::span<const std::pair<nostd::string_view, common::AttributeValue>> |
||||
MakeAttributes(std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> |
||||
attributes) noexcept |
||||
{ |
||||
return nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}; |
||||
} |
||||
|
||||
/**
|
||||
* Utility function to help to make a attribute view from a span |
||||
* |
||||
* @param attributes |
||||
* @return nostd::span<const std::pair<nostd::string_view, common::AttributeValue>> |
||||
*/ |
||||
inline static nostd::span<const std::pair<nostd::string_view, common::AttributeValue>> |
||||
MakeAttributes( |
||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>> attributes) noexcept |
||||
{ |
||||
return attributes; |
||||
} |
||||
|
||||
/**
|
||||
* Utility function to help to make a attribute view from a KeyValueIterable |
||||
* |
||||
* @param attributes |
||||
* @return common::KeyValueIterable |
||||
*/ |
||||
inline static const common::KeyValueIterable &MakeAttributes( |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
return attributes; |
||||
} |
||||
|
||||
/**
|
||||
* Utility function to help to make a attribute view from a key-value iterable object |
||||
* |
||||
* @param attributes |
||||
* @return nostd::span<const std::pair<nostd::string_view, common::AttributeValue>> |
||||
*/ |
||||
template < |
||||
class ArgumentType, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<ArgumentType>::value> * = nullptr> |
||||
inline static common::KeyValueIterableView<ArgumentType> MakeAttributes( |
||||
const ArgumentType &arg) noexcept |
||||
{ |
||||
return common::KeyValueIterableView<ArgumentType>(arg); |
||||
} |
||||
|
||||
} // namespace common
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,272 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/common/key_value_iterable_view.h" |
||||
#include "opentelemetry/common/string_util.h" |
||||
#include "opentelemetry/nostd/function_ref.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/unique_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
#include <cstring> |
||||
#include <string> |
||||
#include <type_traits> |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
|
||||
// Constructor parameter for KeyValueStringTokenizer
|
||||
struct KeyValueStringTokenizerOptions |
||||
{ |
||||
char member_separator = ','; |
||||
char key_value_separator = '='; |
||||
bool ignore_empty_members = true; |
||||
}; |
||||
|
||||
// Tokenizer for key-value headers
|
||||
class KeyValueStringTokenizer |
||||
{ |
||||
public: |
||||
KeyValueStringTokenizer( |
||||
nostd::string_view str, |
||||
const KeyValueStringTokenizerOptions &opts = KeyValueStringTokenizerOptions()) noexcept |
||||
: str_(str), opts_(opts), index_(0) |
||||
{} |
||||
|
||||
static nostd::string_view GetDefaultKeyOrValue() |
||||
{ |
||||
static std::string default_str = ""; |
||||
return default_str; |
||||
} |
||||
|
||||
// Returns next key value in the string header
|
||||
// @param valid_kv : if the found kv pair is valid or not
|
||||
// @param key : key in kv pair
|
||||
// @param key : value in kv pair
|
||||
// @returns true if next kv pair was found, false otherwise.
|
||||
bool next(bool &valid_kv, nostd::string_view &key, nostd::string_view &value) noexcept |
||||
{ |
||||
valid_kv = true; |
||||
while (index_ < str_.size()) |
||||
{ |
||||
bool is_empty_pair = false; |
||||
size_t end = str_.find(opts_.member_separator, index_); |
||||
if (end == std::string::npos) |
||||
{ |
||||
end = str_.size() - 1; |
||||
} |
||||
else if (end == index_) // empty pair. do not update end
|
||||
{ |
||||
is_empty_pair = true; |
||||
} |
||||
else |
||||
{ |
||||
end--; |
||||
} |
||||
|
||||
auto list_member = StringUtil::Trim(str_, index_, end); |
||||
if (list_member.size() == 0 || is_empty_pair) |
||||
{ |
||||
// empty list member
|
||||
index_ = end + 2 - is_empty_pair; |
||||
if (opts_.ignore_empty_members) |
||||
{ |
||||
continue; |
||||
} |
||||
|
||||
valid_kv = true; |
||||
key = GetDefaultKeyOrValue(); |
||||
value = GetDefaultKeyOrValue(); |
||||
return true; |
||||
} |
||||
|
||||
auto key_end_pos = list_member.find(opts_.key_value_separator); |
||||
if (key_end_pos == std::string::npos) |
||||
{ |
||||
// invalid member
|
||||
valid_kv = false; |
||||
} |
||||
else |
||||
{ |
||||
key = list_member.substr(0, key_end_pos); |
||||
value = list_member.substr(key_end_pos + 1); |
||||
} |
||||
|
||||
index_ = end + 2; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
// no more entries remaining
|
||||
return false; |
||||
} |
||||
|
||||
// Returns total number of tokens in header string
|
||||
size_t NumTokens() const noexcept |
||||
{ |
||||
size_t cnt = 0, begin = 0; |
||||
while (begin < str_.size()) |
||||
{ |
||||
++cnt; |
||||
size_t end = str_.find(opts_.member_separator, begin); |
||||
if (end == std::string::npos) |
||||
{ |
||||
break; |
||||
} |
||||
|
||||
begin = end + 1; |
||||
} |
||||
|
||||
return cnt; |
||||
} |
||||
|
||||
// Resets the iterator
|
||||
void reset() noexcept { index_ = 0; } |
||||
|
||||
private: |
||||
nostd::string_view str_; |
||||
KeyValueStringTokenizerOptions opts_; |
||||
size_t index_; |
||||
}; |
||||
|
||||
// Class to store fixed size array of key-value pairs of string type
|
||||
class KeyValueProperties |
||||
{ |
||||
// Class to store key-value pairs of string types
|
||||
public: |
||||
class Entry |
||||
{ |
||||
public: |
||||
Entry() : key_(nullptr), value_(nullptr) {} |
||||
|
||||
// Copy constructor
|
||||
Entry(const Entry ©) |
||||
{ |
||||
key_ = CopyStringToPointer(copy.key_.get()); |
||||
value_ = CopyStringToPointer(copy.value_.get()); |
||||
} |
||||
|
||||
// Copy assignment operator
|
||||
Entry &operator=(Entry &other) |
||||
{ |
||||
key_ = CopyStringToPointer(other.key_.get()); |
||||
value_ = CopyStringToPointer(other.value_.get()); |
||||
return *this; |
||||
} |
||||
|
||||
// Move contructor and assignment operator
|
||||
Entry(Entry &&other) = default; |
||||
Entry &operator=(Entry &&other) = default; |
||||
|
||||
// Creates an Entry for a given key-value pair.
|
||||
Entry(nostd::string_view key, nostd::string_view value) |
||||
{ |
||||
key_ = CopyStringToPointer(key); |
||||
value_ = CopyStringToPointer(value); |
||||
} |
||||
|
||||
// Gets the key associated with this entry.
|
||||
nostd::string_view GetKey() const noexcept { return key_.get(); } |
||||
|
||||
// Gets the value associated with this entry.
|
||||
nostd::string_view GetValue() const noexcept { return value_.get(); } |
||||
|
||||
// Sets the value for this entry. This overrides the previous value.
|
||||
void SetValue(nostd::string_view value) noexcept { value_ = CopyStringToPointer(value); } |
||||
|
||||
private: |
||||
// Store key and value as raw char pointers to avoid using std::string.
|
||||
nostd::unique_ptr<const char[]> key_; |
||||
nostd::unique_ptr<const char[]> value_; |
||||
|
||||
// Copies string into a buffer and returns a unique_ptr to the buffer.
|
||||
// This is a workaround for the fact that memcpy doesn't accept a const destination.
|
||||
nostd::unique_ptr<const char[]> CopyStringToPointer(nostd::string_view str) |
||||
{ |
||||
char *temp = new char[str.size() + 1]; |
||||
memcpy(temp, str.data(), str.size()); |
||||
temp[str.size()] = '\0'; |
||||
return nostd::unique_ptr<const char[]>(temp); |
||||
} |
||||
}; |
||||
|
||||
// Maintain the number of entries in entries_.
|
||||
size_t num_entries_; |
||||
|
||||
// Max size of allocated array
|
||||
size_t max_num_entries_; |
||||
|
||||
// Store entries in a C-style array to avoid using std::array or std::vector.
|
||||
nostd::unique_ptr<Entry[]> entries_; |
||||
|
||||
public: |
||||
// Create Key-value list of given size
|
||||
// @param size : Size of list.
|
||||
KeyValueProperties(size_t size) noexcept |
||||
: num_entries_(0), max_num_entries_(size), entries_(new Entry[size]) |
||||
{} |
||||
|
||||
// Create Empty Key-Value list
|
||||
KeyValueProperties() noexcept : num_entries_(0), max_num_entries_(0), entries_(nullptr) {} |
||||
|
||||
template <class T, class = typename std::enable_if<detail::is_key_value_iterable<T>::value>::type> |
||||
KeyValueProperties(const T &keys_and_values) noexcept |
||||
: num_entries_(0), |
||||
max_num_entries_(keys_and_values.size()), |
||||
entries_(new Entry[max_num_entries_]) |
||||
{ |
||||
for (auto &e : keys_and_values) |
||||
{ |
||||
Entry entry(e.first, e.second); |
||||
(entries_.get())[num_entries_++] = std::move(entry); |
||||
} |
||||
} |
||||
|
||||
// Adds new kv pair into kv properties
|
||||
void AddEntry(nostd::string_view key, nostd::string_view value) noexcept |
||||
{ |
||||
if (num_entries_ < max_num_entries_) |
||||
{ |
||||
Entry entry(key, value); |
||||
(entries_.get())[num_entries_++] = std::move(entry); |
||||
} |
||||
} |
||||
|
||||
// Returns all kv pair entries
|
||||
bool GetAllEntries( |
||||
nostd::function_ref<bool(nostd::string_view, nostd::string_view)> callback) const noexcept |
||||
{ |
||||
for (size_t i = 0; i < num_entries_; i++) |
||||
{ |
||||
auto &entry = (entries_.get())[i]; |
||||
if (!callback(entry.GetKey(), entry.GetValue())) |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
// Return value for key if exists, return false otherwise
|
||||
bool GetValue(nostd::string_view key, std::string &value) const noexcept |
||||
{ |
||||
for (size_t i = 0; i < num_entries_; i++) |
||||
{ |
||||
auto &entry = (entries_.get())[i]; |
||||
if (entry.GetKey() == key) |
||||
{ |
||||
const auto &entry_value = entry.GetValue(); |
||||
value = std::string(entry_value.data(), entry_value.size()); |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
size_t Size() const noexcept { return num_entries_; } |
||||
}; |
||||
} // namespace common
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,523 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
/*
|
||||
OPENTELEMETRY_HAVE_BUILTIN&OPENTELEMETRY_HAVE_FEATURE |
||||
|
||||
Checks whether the compiler supports a Clang Feature Checking Macro, and if |
||||
so, checks whether it supports the provided builtin function "x" where x |
||||
is one of the functions noted in |
||||
https://clang.llvm.org/docs/LanguageExtensions.html
|
||||
|
||||
Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. |
||||
http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html
|
||||
*/ |
||||
#if !defined(OPENTELEMETRY_HAVE_BUILTIN) |
||||
# ifdef __has_builtin |
||||
# define OPENTELEMETRY_HAVE_BUILTIN(x) __has_builtin(x) |
||||
# else |
||||
# define OPENTELEMETRY_HAVE_BUILTIN(x) 0 |
||||
# endif |
||||
#endif |
||||
|
||||
#if !defined(OPENTELEMETRY_HAVE_FEATURE) |
||||
# ifdef __has_feature |
||||
# define OPENTELEMETRY_HAVE_FEATURE(f) __has_feature(f) |
||||
# else |
||||
# define OPENTELEMETRY_HAVE_FEATURE(f) 0 |
||||
# endif |
||||
#endif |
||||
|
||||
/*
|
||||
has feature |
||||
|
||||
OPENTELEMETRY_HAVE_ATTRIBUTE |
||||
|
||||
A function-like feature checking macro that is a wrapper around |
||||
`__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a |
||||
nonzero constant integer if the attribute is supported or 0 if not. |
||||
|
||||
It evaluates to zero if `__has_attribute` is not defined by the compiler. |
||||
|
||||
GCC: https://gcc.gnu.org/gcc-5/changes.html
|
||||
Clang: https://clang.llvm.org/docs/LanguageExtensions.html
|
||||
*/ |
||||
#if !defined(OPENTELEMETRY_HAVE_ATTRIBUTE) |
||||
# ifdef __has_attribute |
||||
# define OPENTELEMETRY_HAVE_ATTRIBUTE(x) __has_attribute(x) |
||||
# else |
||||
# define OPENTELEMETRY_HAVE_ATTRIBUTE(x) 0 |
||||
# endif |
||||
#endif |
||||
|
||||
/*
|
||||
OPENTELEMETRY_HAVE_CPP_ATTRIBUTE |
||||
|
||||
A function-like feature checking macro that accepts C++11 style attributes. |
||||
It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 |
||||
(https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
|
||||
find `__has_cpp_attribute`, will evaluate to 0. |
||||
*/ |
||||
#if !defined(OPENTELEMETRY_HAVE_CPP_ATTRIBUTE) |
||||
# if defined(__cplusplus) && defined(__has_cpp_attribute) |
||||
// NOTE: requiring __cplusplus above should not be necessary, but
|
||||
// works around https://bugs.llvm.org/show_bug.cgi?id=23435.
|
||||
# define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) |
||||
# else |
||||
# define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) 0 |
||||
# endif |
||||
#endif |
||||
|
||||
/*
|
||||
Expected usage pattern: |
||||
|
||||
if OPENTELEMETRY_LIKELY_CONDITION (ptr != nullptr) |
||||
{ |
||||
do_something_likely(); |
||||
} else { |
||||
do_something_unlikely(); |
||||
} |
||||
|
||||
This pattern works with gcc/clang and __builtin_expect(), |
||||
as well as with C++20. |
||||
It is unclear if __builtin_expect() will be deprecated |
||||
in favor of C++20 [[likely]] or not. |
||||
|
||||
OPENTELEMETRY_LIKELY_CONDITION is preferred over OPENTELEMETRY_LIKELY, |
||||
to be revisited when C++20 is required. |
||||
*/ |
||||
|
||||
#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && defined(__cplusplus) |
||||
// Only use likely with C++20
|
||||
# if __cplusplus >= 202002L |
||||
// GCC 9 has likely attribute but do not support declare it at the beginning of statement
|
||||
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) |
||||
# if __has_cpp_attribute(likely) |
||||
# define OPENTELEMETRY_LIKELY_CONDITION(C) (C) [[likely]] |
||||
# endif |
||||
# endif |
||||
# endif |
||||
#endif |
||||
#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__)) |
||||
// Only use if supported by the compiler
|
||||
# define OPENTELEMETRY_LIKELY_CONDITION(C) (__builtin_expect(!!(C), true)) |
||||
#endif |
||||
#ifndef OPENTELEMETRY_LIKELY_CONDITION |
||||
// Do not use likely annotations
|
||||
# define OPENTELEMETRY_LIKELY_CONDITION(C) (C) |
||||
#endif |
||||
|
||||
#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && defined(__cplusplus) |
||||
// Only use unlikely with C++20
|
||||
# if __cplusplus >= 202002L |
||||
// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement
|
||||
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) |
||||
# if __has_cpp_attribute(unlikely) |
||||
# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) [[unlikely]] |
||||
# endif |
||||
# endif |
||||
# endif |
||||
#endif |
||||
#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__)) |
||||
// Only use if supported by the compiler
|
||||
# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (__builtin_expect(!!(C), false)) |
||||
#endif |
||||
#ifndef OPENTELEMETRY_UNLIKELY_CONDITION |
||||
// Do not use unlikely annotations
|
||||
# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) |
||||
#endif |
||||
|
||||
/*
|
||||
Expected usage pattern: |
||||
|
||||
if (ptr != nullptr) |
||||
OPENTELEMETRY_LIKELY |
||||
{ |
||||
do_something_likely(); |
||||
} else { |
||||
do_something_unlikely(); |
||||
} |
||||
|
||||
This pattern works starting with C++20. |
||||
See https://en.cppreference.com/w/cpp/language/attributes/likely
|
||||
|
||||
Please use OPENTELEMETRY_LIKELY_CONDITION instead for now. |
||||
*/ |
||||
|
||||
#if !defined(OPENTELEMETRY_LIKELY) && defined(__cplusplus) |
||||
// Only use likely with C++20
|
||||
# if __cplusplus >= 202002L |
||||
// GCC 9 has likely attribute but do not support declare it at the beginning of statement
|
||||
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) |
||||
# if __has_cpp_attribute(likely) |
||||
# define OPENTELEMETRY_LIKELY [[likely]] |
||||
# endif |
||||
# endif |
||||
# endif |
||||
#endif |
||||
|
||||
#ifndef OPENTELEMETRY_LIKELY |
||||
# define OPENTELEMETRY_LIKELY |
||||
#endif |
||||
|
||||
#if !defined(OPENTELEMETRY_UNLIKELY) && defined(__cplusplus) |
||||
// Only use unlikely with C++20
|
||||
# if __cplusplus >= 202002L |
||||
// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement
|
||||
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) |
||||
# if __has_cpp_attribute(unlikely) |
||||
# define OPENTELEMETRY_UNLIKELY [[unlikely]] |
||||
# endif |
||||
# endif |
||||
# endif |
||||
#endif |
||||
|
||||
#ifndef OPENTELEMETRY_UNLIKELY |
||||
# define OPENTELEMETRY_UNLIKELY |
||||
#endif |
||||
|
||||
/// \brief Declare variable as maybe unused
|
||||
/// usage:
|
||||
/// OPENTELEMETRY_MAYBE_UNUSED int a;
|
||||
/// class OPENTELEMETRY_MAYBE_UNUSED a;
|
||||
/// OPENTELEMETRY_MAYBE_UNUSED int a();
|
||||
///
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L |
||||
# define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]] |
||||
#elif defined(__clang__) |
||||
# define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused)) |
||||
#elif defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) |
||||
# define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused)) |
||||
#elif (defined(_MSC_VER) && _MSC_VER >= 1910) && (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) |
||||
# define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]] |
||||
#else |
||||
# define OPENTELEMETRY_MAYBE_UNUSED |
||||
#endif |
||||
|
||||
#ifndef OPENTELEMETRY_RTTI_ENABLED |
||||
# if defined(__clang__) |
||||
# if __has_feature(cxx_rtti) |
||||
# define OPENTELEMETRY_RTTI_ENABLED |
||||
# endif |
||||
# elif defined(__GNUG__) |
||||
# if defined(__GXX_RTTI) |
||||
# define OPENTELEMETRY_RTTI_ENABLED |
||||
# endif |
||||
# elif defined(_MSC_VER) |
||||
# if defined(_CPPRTTI) |
||||
# define OPENTELEMETRY_RTTI_ENABLED |
||||
# endif |
||||
# endif |
||||
#endif |
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201402L |
||||
# define OPENTELEMETRY_DEPRECATED [[deprecated]] |
||||
#elif defined(__clang__) |
||||
# define OPENTELEMETRY_DEPRECATED __attribute__((deprecated)) |
||||
#elif defined(__GNUC__) |
||||
# define OPENTELEMETRY_DEPRECATED __attribute__((deprecated)) |
||||
#elif defined(_MSC_VER) |
||||
# if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L |
||||
# define OPENTELEMETRY_DEPRECATED [[deprecated]] |
||||
# else |
||||
# define OPENTELEMETRY_DEPRECATED __declspec(deprecated) |
||||
# endif |
||||
#else |
||||
# define OPENTELEMETRY_DEPRECATED |
||||
#endif |
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201402L |
||||
# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]] |
||||
#elif defined(__clang__) |
||||
# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg))) |
||||
#elif defined(__GNUC__) |
||||
# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg))) |
||||
#elif defined(_MSC_VER) |
||||
# if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L |
||||
# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]] |
||||
# else |
||||
# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __declspec(deprecated(msg)) |
||||
# endif |
||||
#else |
||||
# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) |
||||
#endif |
||||
|
||||
// Regex support
|
||||
#if (__GNUC__ == 4 && (__GNUC_MINOR__ == 8 || __GNUC_MINOR__ == 9)) |
||||
# define OPENTELEMETRY_HAVE_WORKING_REGEX 0 |
||||
#else |
||||
# define OPENTELEMETRY_HAVE_WORKING_REGEX 1 |
||||
#endif |
||||
|
||||
/* clang-format off */ |
||||
|
||||
/**
|
||||
@page HEADER_ONLY_SINGLETON Header only singleton. |
||||
|
||||
@section ELF_SINGLETON |
||||
|
||||
For clang and gcc, the desired coding pattern is as follows. |
||||
|
||||
@verbatim |
||||
class Foo |
||||
{ |
||||
// (a)
|
||||
__attribute__((visibility("default"))) |
||||
// (b)
|
||||
T& get_singleton() |
||||
{ |
||||
// (c)
|
||||
static T singleton; |
||||
return singleton; |
||||
} |
||||
}; |
||||
@endverbatim |
||||
|
||||
(a) is needed when the code is build with |
||||
@code -fvisibility="hidden" @endcode |
||||
to ensure that all instances of (b) are visible to the linker. |
||||
|
||||
What is duplicated in the binary is @em code, in (b). |
||||
|
||||
The linker will make sure only one instance |
||||
of all the (b) methods is used. |
||||
|
||||
(c) is a singleton implemented inside a method. |
||||
|
||||
This is very desirable, because: |
||||
|
||||
- the C++ compiler guarantees that construction |
||||
of the variable (c) is thread safe. |
||||
|
||||
- constructors for (c) singletons are executed in code path order, |
||||
or not at all if the singleton is never used. |
||||
|
||||
@section OTHER_SINGLETON |
||||
|
||||
For other platforms, header only singletons are not supported at this |
||||
point. |
||||
|
||||
@section CODING_PATTERN |
||||
|
||||
The coding pattern to use in the source code is as follows |
||||
|
||||
@verbatim |
||||
class Foo |
||||
{ |
||||
OPENTELEMETRY_API_SINGLETON |
||||
T& get_singleton() |
||||
{ |
||||
static T singleton; |
||||
return singleton; |
||||
} |
||||
}; |
||||
@endverbatim |
||||
*/ |
||||
|
||||
/* clang-format on */ |
||||
|
||||
#if defined(__clang__) |
||||
|
||||
# define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default"))) |
||||
# define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden"))) |
||||
|
||||
#elif defined(__GNUC__) |
||||
|
||||
# define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default"))) |
||||
# define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden"))) |
||||
|
||||
#else |
||||
|
||||
/* Add support for other compilers here. */ |
||||
|
||||
# define OPENTELEMETRY_API_SINGLETON |
||||
# define OPENTELEMETRY_LOCAL_SYMBOL |
||||
|
||||
#endif |
||||
|
||||
//
|
||||
// Atomic wrappers based on compiler intrinsics for memory read/write.
|
||||
// The tailing number is read/write length in bits.
|
||||
//
|
||||
// N.B. Compiler intrinsic is used because the usage of C++ standard library is restricted in the
|
||||
// OpenTelemetry C++ API.
|
||||
//
|
||||
#if defined(__GNUC__) |
||||
|
||||
# define OPENTELEMETRY_ATOMIC_READ_8(ptr) __atomic_load_n(ptr, __ATOMIC_SEQ_CST) |
||||
# define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST) |
||||
|
||||
#elif defined(_MSC_VER) |
||||
|
||||
# include <intrin.h> |
||||
|
||||
# define OPENTELEMETRY_ATOMIC_READ_8(ptr) \ |
||||
static_cast<uint8_t>(_InterlockedCompareExchange8(reinterpret_cast<char *>(ptr), 0, 0)) |
||||
# define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) \ |
||||
_InterlockedExchange8(reinterpret_cast<char *>(ptr), static_cast<char>(value)) |
||||
|
||||
#else |
||||
# error port atomics read/write for the current platform |
||||
#endif |
||||
|
||||
/* clang-format on */ |
||||
//
|
||||
// The if/elif order matters here. If both OPENTELEMETRY_BUILD_IMPORT_DLL and
|
||||
// OPENTELEMETRY_BUILD_EXPORT_DLL are defined, the former takes precedence.
|
||||
//
|
||||
// TODO: consider define OPENTELEMETRY_EXPORT for cygwin/gcc, see below link.
|
||||
// https://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support
|
||||
//
|
||||
#if defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_IMPORT_DLL) |
||||
|
||||
# define OPENTELEMETRY_EXPORT __declspec(dllimport) |
||||
|
||||
#elif defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_EXPORT_DLL) |
||||
|
||||
# define OPENTELEMETRY_EXPORT __declspec(dllexport) |
||||
|
||||
#else |
||||
|
||||
//
|
||||
// build OpenTelemetry as static library or not on Windows.
|
||||
//
|
||||
# define OPENTELEMETRY_EXPORT |
||||
|
||||
#endif |
||||
|
||||
// OPENTELEMETRY_HAVE_EXCEPTIONS
|
||||
//
|
||||
// Checks whether the compiler both supports and enables exceptions. Many
|
||||
// compilers support a "no exceptions" mode that disables exceptions.
|
||||
//
|
||||
// Generally, when OPENTELEMETRY_HAVE_EXCEPTIONS is not defined:
|
||||
//
|
||||
// * Code using `throw` and `try` may not compile.
|
||||
// * The `noexcept` specifier will still compile and behave as normal.
|
||||
// * The `noexcept` operator may still return `false`.
|
||||
//
|
||||
// For further details, consult the compiler's documentation.
|
||||
#ifndef OPENTELEMETRY_HAVE_EXCEPTIONS |
||||
# if defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__) < 306 |
||||
// Clang < 3.6
|
||||
// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro
|
||||
# if defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions) |
||||
# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 |
||||
# endif // defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions)
|
||||
# elif OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions) |
||||
# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 |
||||
// Handle remaining special cases and default to exceptions being supported.
|
||||
# elif !(defined(__GNUC__) && !defined(__EXCEPTIONS) && !defined(__cpp_exceptions)) && \ |
||||
!(defined(_MSC_VER) && !defined(_CPPUNWIND)) |
||||
# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 |
||||
# endif |
||||
#endif |
||||
#ifndef OPENTELEMETRY_HAVE_EXCEPTIONS |
||||
# define OPENTELEMETRY_HAVE_EXCEPTIONS 0 |
||||
#endif |
||||
|
||||
/*
|
||||
OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function |
||||
parameter or implicit object parameter is retained by the return value of the |
||||
annotated function (or, for a parameter of a constructor, in the value of the |
||||
constructed object). This attribute causes warnings to be produced if a |
||||
temporary object does not live long enough. |
||||
|
||||
When applied to a reference parameter, the referenced object is assumed to be |
||||
retained by the return value of the function. When applied to a non-reference |
||||
parameter (for example, a pointer or a class type), all temporaries |
||||
referenced by the parameter are assumed to be retained by the return value of |
||||
the function. |
||||
|
||||
See also the upstream documentation: |
||||
https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
|
||||
*/ |
||||
#ifndef OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND |
||||
# if OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) |
||||
# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] |
||||
# elif OPENTELEMETRY_HAVE_ATTRIBUTE(lifetimebound) |
||||
# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) |
||||
# else |
||||
# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND |
||||
# endif |
||||
#endif |
||||
|
||||
// OPENTELEMETRY_HAVE_MEMORY_SANITIZER
|
||||
//
|
||||
// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of
|
||||
// a compiler instrumentation module and a run-time library.
|
||||
#ifndef OPENTELEMETRY_HAVE_MEMORY_SANITIZER |
||||
# if !defined(__native_client__) && OPENTELEMETRY_HAVE_FEATURE(memory_sanitizer) |
||||
# define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 1 |
||||
# else |
||||
# define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 0 |
||||
# endif |
||||
#endif |
||||
|
||||
#if OPENTELEMETRY_HAVE_MEMORY_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_memory) |
||||
# define OPENTELEMETRY_SANITIZER_NO_MEMORY \ |
||||
__attribute__((no_sanitize_memory)) // __attribute__((no_sanitize("memory")))
|
||||
#else |
||||
# define OPENTELEMETRY_SANITIZER_NO_MEMORY |
||||
#endif |
||||
|
||||
// OPENTELEMETRY_HAVE_THREAD_SANITIZER
|
||||
//
|
||||
// ThreadSanitizer (TSan) is a fast data race detector.
|
||||
#ifndef OPENTELEMETRY_HAVE_THREAD_SANITIZER |
||||
# if defined(__SANITIZE_THREAD__) |
||||
# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1 |
||||
# elif OPENTELEMETRY_HAVE_FEATURE(thread_sanitizer) |
||||
# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1 |
||||
# else |
||||
# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 0 |
||||
# endif |
||||
#endif |
||||
|
||||
#if OPENTELEMETRY_HAVE_THREAD_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_thread) |
||||
# define OPENTELEMETRY_SANITIZER_NO_THREAD \ |
||||
__attribute__((no_sanitize_thread)) // __attribute__((no_sanitize("thread")))
|
||||
#else |
||||
# define OPENTELEMETRY_SANITIZER_NO_THREAD |
||||
#endif |
||||
|
||||
// OPENTELEMETRY_HAVE_ADDRESS_SANITIZER
|
||||
//
|
||||
// AddressSanitizer (ASan) is a fast memory error detector.
|
||||
#ifndef OPENTELEMETRY_HAVE_ADDRESS_SANITIZER |
||||
# if defined(__SANITIZE_ADDRESS__) |
||||
# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1 |
||||
# elif OPENTELEMETRY_HAVE_FEATURE(address_sanitizer) |
||||
# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1 |
||||
# else |
||||
# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 0 |
||||
# endif |
||||
#endif |
||||
|
||||
// OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER
|
||||
//
|
||||
// Hardware-Assisted AddressSanitizer (or HWASAN) is even faster than asan
|
||||
// memory error detector which can use CPU features like ARM TBI, Intel LAM or
|
||||
// AMD UAI.
|
||||
#ifndef OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER |
||||
# if defined(__SANITIZE_HWADDRESS__) |
||||
# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1 |
||||
# elif OPENTELEMETRY_HAVE_FEATURE(hwaddress_sanitizer) |
||||
# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1 |
||||
# else |
||||
# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 0 |
||||
# endif |
||||
#endif |
||||
|
||||
#if OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_address) |
||||
# define OPENTELEMETRY_SANITIZER_NO_ADDRESS \ |
||||
__attribute__((no_sanitize_address)) // __attribute__((no_sanitize("address")))
|
||||
#elif OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && defined(_MSC_VER) && _MSC_VER >= 1928 |
||||
# define OPENTELEMETRY_SANITIZER_NO_ADDRESS __declspec(no_sanitize_address) |
||||
#elif OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize) |
||||
# define OPENTELEMETRY_SANITIZER_NO_ADDRESS __attribute__((no_sanitize("hwaddress"))) |
||||
#else |
||||
# define OPENTELEMETRY_SANITIZER_NO_ADDRESS |
||||
#endif |
||||
@ -0,0 +1,133 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <atomic> |
||||
#include <chrono> |
||||
#include <thread> |
||||
|
||||
#include "opentelemetry/version.h" |
||||
|
||||
#if defined(_MSC_VER) |
||||
# define _WINSOCKAPI_ // stops including winsock.h
|
||||
# include <windows.h> |
||||
#elif defined(__i386__) || defined(__x86_64__) |
||||
# if defined(__clang__) |
||||
# include <emmintrin.h> |
||||
# elif defined(__INTEL_COMPILER) |
||||
# include <immintrin.h> |
||||
# endif |
||||
#endif |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
|
||||
constexpr int SPINLOCK_FAST_ITERATIONS = 100; |
||||
constexpr int SPINLOCK_SLEEP_MS = 1; |
||||
|
||||
/**
|
||||
* A Mutex which uses atomic flags and spin-locks instead of halting threads. |
||||
* |
||||
* This mutex uses an incremental back-off strategy with the following phases: |
||||
* 1. A tight spin-lock loop (pending: using hardware PAUSE/YIELD instructions) |
||||
* 2. A loop where the current thread yields control after checking the lock. |
||||
* 3. Issuing a thread-sleep call before starting back in phase 1. |
||||
* |
||||
* This is meant to give a good balance of perofrmance and CPU consumption in |
||||
* practice. |
||||
* |
||||
* This mutex uses an incremental back-off strategy with the following phases: |
||||
* 1. A tight spin-lock loop (pending: using hardware PAUSE/YIELD instructions) |
||||
* 2. A loop where the current thread yields control after checking the lock. |
||||
* 3. Issuing a thread-sleep call before starting back in phase 1. |
||||
* |
||||
* This is meant to give a good balance of perofrmance and CPU consumption in |
||||
* practice. |
||||
* |
||||
* This class implements the `BasicLockable` specification: |
||||
* https://en.cppreference.com/w/cpp/named_req/BasicLockable
|
||||
*/ |
||||
class SpinLockMutex |
||||
{ |
||||
public: |
||||
SpinLockMutex() noexcept {} |
||||
~SpinLockMutex() noexcept = default; |
||||
SpinLockMutex(const SpinLockMutex &) = delete; |
||||
SpinLockMutex &operator=(const SpinLockMutex &) = delete; |
||||
|
||||
static inline void fast_yield() noexcept |
||||
{ |
||||
// Issue a Pause/Yield instruction while spinning.
|
||||
#if defined(_MSC_VER) |
||||
YieldProcessor(); |
||||
#elif defined(__i386__) || defined(__x86_64__) |
||||
# if defined(__clang__) || defined(__INTEL_COMPILER) |
||||
_mm_pause(); |
||||
# else |
||||
__builtin_ia32_pause(); |
||||
# endif |
||||
#elif defined(__armel__) || defined(__ARMEL__) |
||||
asm volatile("nop" ::: "memory"); |
||||
#elif defined(__arm__) || defined(__aarch64__) // arm big endian / arm64
|
||||
__asm__ __volatile__("yield" ::: "memory"); |
||||
#else |
||||
// TODO: Issue PAGE/YIELD on other architectures.
|
||||
#endif |
||||
} |
||||
|
||||
/**
|
||||
* Attempts to lock the mutex. Return immediately with `true` (success) or `false` (failure). |
||||
*/ |
||||
bool try_lock() noexcept |
||||
{ |
||||
return !flag_.load(std::memory_order_relaxed) && |
||||
!flag_.exchange(true, std::memory_order_acquire); |
||||
} |
||||
|
||||
/**
|
||||
* Blocks until a lock can be obtained for the current thread. |
||||
* |
||||
* This mutex will spin the current CPU waiting for the lock to be available. This can have |
||||
* decent performance in scenarios where there is low lock contention and lock-holders achieve |
||||
* their work quickly. It degrades in scenarios where locked tasks take a long time. |
||||
*/ |
||||
void lock() noexcept |
||||
{ |
||||
for (;;) |
||||
{ |
||||
// Try once
|
||||
if (!flag_.exchange(true, std::memory_order_acquire)) |
||||
{ |
||||
return; |
||||
} |
||||
// Spin-Fast (goal ~10ns)
|
||||
for (std::size_t i = 0; i < SPINLOCK_FAST_ITERATIONS; ++i) |
||||
{ |
||||
if (try_lock()) |
||||
{ |
||||
return; |
||||
} |
||||
fast_yield(); |
||||
} |
||||
// Yield then try again (goal ~100ns)
|
||||
std::this_thread::yield(); |
||||
if (try_lock()) |
||||
{ |
||||
return; |
||||
} |
||||
// Sleep and then start the whole process again. (goal ~1000ns)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(SPINLOCK_SLEEP_MS)); |
||||
} |
||||
return; |
||||
} |
||||
/** Releases the lock held by the execution agent. Throws no exceptions. */ |
||||
void unlock() noexcept { flag_.store(false, std::memory_order_release); } |
||||
|
||||
private: |
||||
std::atomic<bool> flag_{false}; |
||||
}; |
||||
|
||||
} // namespace common
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,42 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
|
||||
class StringUtil |
||||
{ |
||||
public: |
||||
static nostd::string_view Trim(nostd::string_view str, size_t left, size_t right) noexcept |
||||
{ |
||||
while (left <= right && isspace(str[left])) |
||||
{ |
||||
left++; |
||||
} |
||||
while (left <= right && isspace(str[right])) |
||||
{ |
||||
right--; |
||||
} |
||||
return str.substr(left, 1 + right - left); |
||||
} |
||||
|
||||
static nostd::string_view Trim(nostd::string_view str) noexcept |
||||
{ |
||||
if (str.empty()) |
||||
{ |
||||
return str; |
||||
} |
||||
|
||||
return Trim(str, 0, str.size() - 1); |
||||
} |
||||
}; |
||||
|
||||
} // namespace common
|
||||
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,206 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <chrono> |
||||
#include <cstdint> |
||||
|
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
/**
|
||||
* @brief A timepoint relative to the system clock epoch. |
||||
* |
||||
* This is used for marking the beginning and end of an operation. |
||||
*/ |
||||
class SystemTimestamp |
||||
{ |
||||
public: |
||||
/**
|
||||
* @brief Initializes a system timestamp pointing to the start of the epoch. |
||||
*/ |
||||
SystemTimestamp() noexcept : nanos_since_epoch_{0} {} |
||||
|
||||
/**
|
||||
* @brief Initializes a system timestamp from a duration. |
||||
* |
||||
* @param time_since_epoch Time elapsed since the beginning of the epoch. |
||||
*/ |
||||
template <class Rep, class Period> |
||||
explicit SystemTimestamp(const std::chrono::duration<Rep, Period> &time_since_epoch) noexcept |
||||
: nanos_since_epoch_{static_cast<int64_t>( |
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(time_since_epoch).count())} |
||||
{} |
||||
|
||||
/**
|
||||
* @brief Initializes a system timestamp based on a point in time. |
||||
* |
||||
* @param time_point A point in time. |
||||
*/ |
||||
/*implicit*/ SystemTimestamp(const std::chrono::system_clock::time_point &time_point) noexcept |
||||
: SystemTimestamp{time_point.time_since_epoch()} |
||||
{} |
||||
|
||||
/**
|
||||
* @brief Returns a time point for the time stamp. |
||||
* |
||||
* @return A time point corresponding to the time stamp. |
||||
*/ |
||||
operator std::chrono::system_clock::time_point() const noexcept |
||||
{ |
||||
return std::chrono::system_clock::time_point{ |
||||
std::chrono::duration_cast<std::chrono::system_clock::duration>( |
||||
std::chrono::nanoseconds{nanos_since_epoch_})}; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Returns the nanoseconds since the beginning of the epoch. |
||||
* |
||||
* @return Elapsed nanoseconds since the beginning of the epoch for this timestamp. |
||||
*/ |
||||
std::chrono::nanoseconds time_since_epoch() const noexcept |
||||
{ |
||||
return std::chrono::nanoseconds{nanos_since_epoch_}; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Compare two steady time stamps. |
||||
* |
||||
* @return true if the two time stamps are equal. |
||||
*/ |
||||
bool operator==(const SystemTimestamp &other) const noexcept |
||||
{ |
||||
return nanos_since_epoch_ == other.nanos_since_epoch_; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Compare two steady time stamps for inequality. |
||||
* |
||||
* @return true if the two time stamps are not equal. |
||||
*/ |
||||
bool operator!=(const SystemTimestamp &other) const noexcept |
||||
{ |
||||
return nanos_since_epoch_ != other.nanos_since_epoch_; |
||||
} |
||||
|
||||
private: |
||||
int64_t nanos_since_epoch_; |
||||
}; |
||||
|
||||
/**
|
||||
* @brief A timepoint relative to the monotonic clock epoch |
||||
* |
||||
* This is used for calculating the duration of an operation. |
||||
*/ |
||||
class SteadyTimestamp |
||||
{ |
||||
public: |
||||
/**
|
||||
* @brief Initializes a monotonic timestamp pointing to the start of the epoch. |
||||
*/ |
||||
SteadyTimestamp() noexcept : nanos_since_epoch_{0} {} |
||||
|
||||
/**
|
||||
* @brief Initializes a monotonic timestamp from a duration. |
||||
* |
||||
* @param time_since_epoch Time elapsed since the beginning of the epoch. |
||||
*/ |
||||
template <class Rep, class Period> |
||||
explicit SteadyTimestamp(const std::chrono::duration<Rep, Period> &time_since_epoch) noexcept |
||||
: nanos_since_epoch_{static_cast<int64_t>( |
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(time_since_epoch).count())} |
||||
{} |
||||
|
||||
/**
|
||||
* @brief Initializes a monotonic timestamp based on a point in time. |
||||
* |
||||
* @param time_point A point in time. |
||||
*/ |
||||
/*implicit*/ SteadyTimestamp(const std::chrono::steady_clock::time_point &time_point) noexcept |
||||
: SteadyTimestamp{time_point.time_since_epoch()} |
||||
{} |
||||
|
||||
/**
|
||||
* @brief Returns a time point for the time stamp. |
||||
* |
||||
* @return A time point corresponding to the time stamp. |
||||
*/ |
||||
operator std::chrono::steady_clock::time_point() const noexcept |
||||
{ |
||||
return std::chrono::steady_clock::time_point{ |
||||
std::chrono::duration_cast<std::chrono::steady_clock::duration>( |
||||
std::chrono::nanoseconds{nanos_since_epoch_})}; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Returns the nanoseconds since the beginning of the epoch. |
||||
* |
||||
* @return Elapsed nanoseconds since the beginning of the epoch for this timestamp. |
||||
*/ |
||||
std::chrono::nanoseconds time_since_epoch() const noexcept |
||||
{ |
||||
return std::chrono::nanoseconds{nanos_since_epoch_}; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Compare two steady time stamps. |
||||
* |
||||
* @return true if the two time stamps are equal. |
||||
*/ |
||||
bool operator==(const SteadyTimestamp &other) const noexcept |
||||
{ |
||||
return nanos_since_epoch_ == other.nanos_since_epoch_; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Compare two steady time stamps for inequality. |
||||
* |
||||
* @return true if the two time stamps are not equal. |
||||
*/ |
||||
bool operator!=(const SteadyTimestamp &other) const noexcept |
||||
{ |
||||
return nanos_since_epoch_ != other.nanos_since_epoch_; |
||||
} |
||||
|
||||
private: |
||||
int64_t nanos_since_epoch_; |
||||
}; |
||||
|
||||
class DurationUtil |
||||
{ |
||||
public: |
||||
template <class Rep, class Period> |
||||
static std::chrono::duration<Rep, Period> AdjustWaitForTimeout( |
||||
std::chrono::duration<Rep, Period> timeout, |
||||
std::chrono::duration<Rep, Period> indefinite_value) noexcept |
||||
{ |
||||
// Do not call now() when this duration is max value, now() may have a expensive cost.
|
||||
if (timeout == (std::chrono::duration<Rep, Period>::max)()) |
||||
{ |
||||
return indefinite_value; |
||||
} |
||||
|
||||
// std::future<T>::wait_for, std::this_thread::sleep_for, and std::condition_variable::wait_for
|
||||
// may use steady_clock or system_clock.We need make sure now() + timeout do not overflow.
|
||||
auto max_timeout = std::chrono::duration_cast<std::chrono::duration<Rep, Period>>( |
||||
(std::chrono::steady_clock::time_point::max)() - std::chrono::steady_clock::now()); |
||||
if (timeout >= max_timeout) |
||||
{ |
||||
return indefinite_value; |
||||
} |
||||
max_timeout = std::chrono::duration_cast<std::chrono::duration<Rep, Period>>( |
||||
(std::chrono::system_clock::time_point::max)() - std::chrono::system_clock::now()); |
||||
if (timeout >= max_timeout) |
||||
{ |
||||
return indefinite_value; |
||||
} |
||||
|
||||
return timeout; |
||||
} |
||||
}; |
||||
|
||||
} // namespace common
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,19 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <type_traits> // IWYU pragma: keep |
||||
|
||||
#if defined(OPENTELEMETRY_ABI_VERSION_NO) && OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
# error \ |
||||
"opentelemetry/config.h is removed in ABI version 2 and later. Please use opentelemetry/version.h instead." |
||||
#else |
||||
# if defined(__clang__) || defined(__GNUC__) |
||||
# pragma GCC warning \ |
||||
"opentelemetry/config.h is deprecated. Please use opentelemetry/version.h instead." |
||||
# elif defined(_MSC_VER) |
||||
# pragma message( \ |
||||
"[WARNING]: opentelemetry/config.h is deprecated. Please use opentelemetry/version.h instead.") |
||||
# endif |
||||
#endif |
||||
@ -0,0 +1,171 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <cstring> |
||||
#include <utility> |
||||
|
||||
#include "opentelemetry/context/context_value.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/variant.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace context |
||||
{ |
||||
|
||||
// The context class provides a context identifier. Is built as a linked list
|
||||
// of DataList nodes and each context holds a shared_ptr to a place within
|
||||
// the list that determines which keys and values it has access to. All that
|
||||
// come before and none that come after.
|
||||
class Context |
||||
{ |
||||
|
||||
public: |
||||
Context() = default; |
||||
// Creates a context object from a map of keys and identifiers, this will
|
||||
// hold a shared_ptr to the head of the DataList linked list
|
||||
template <class T> |
||||
Context(const T &keys_and_values) noexcept |
||||
: head_{nostd::shared_ptr<DataList>{new DataList(keys_and_values)}} |
||||
{} |
||||
|
||||
// Creates a context object from a key and value, this will
|
||||
// hold a shared_ptr to the head of the DataList linked list
|
||||
Context(nostd::string_view key, ContextValue value) noexcept |
||||
: head_{nostd::shared_ptr<DataList>{new DataList(key, value)}} |
||||
{} |
||||
|
||||
// Accepts a new iterable and then returns a new context that
|
||||
// contains the new key and value data. It attaches the
|
||||
// exisiting list to the end of the new list.
|
||||
template <class T> |
||||
Context SetValues(T &values) noexcept |
||||
{ |
||||
Context context = Context(values); |
||||
nostd::shared_ptr<DataList> last = context.head_; |
||||
while (last->next_ != nullptr) |
||||
{ |
||||
last = last->next_; |
||||
} |
||||
last->next_ = head_; |
||||
return context; |
||||
} |
||||
|
||||
// Accepts a new iterable and then returns a new context that
|
||||
// contains the new key and value data. It attaches the
|
||||
// exisiting list to the end of the new list.
|
||||
Context SetValue(nostd::string_view key, ContextValue value) noexcept |
||||
{ |
||||
Context context = Context(key, value); |
||||
context.head_->next_ = head_; |
||||
return context; |
||||
} |
||||
|
||||
// Returns the value associated with the passed in key.
|
||||
context::ContextValue GetValue(const nostd::string_view key) const noexcept |
||||
{ |
||||
for (DataList *data = head_.get(); data != nullptr; data = data->next_.get()) |
||||
{ |
||||
if (key.size() == data->key_length_) |
||||
{ |
||||
if (std::memcmp(key.data(), data->key_, data->key_length_) == 0) |
||||
{ |
||||
return data->value_; |
||||
} |
||||
} |
||||
} |
||||
return ContextValue{}; |
||||
} |
||||
|
||||
// Checks for key and returns true if found
|
||||
bool HasKey(const nostd::string_view key) const noexcept |
||||
{ |
||||
return !nostd::holds_alternative<nostd::monostate>(GetValue(key)); |
||||
} |
||||
|
||||
bool operator==(const Context &other) const noexcept { return (head_ == other.head_); } |
||||
|
||||
private: |
||||
// A linked list to contain the keys and values of this context node
|
||||
struct DataList |
||||
{ |
||||
char *key_ = nullptr; |
||||
|
||||
nostd::shared_ptr<DataList> next_{nullptr}; |
||||
|
||||
size_t key_length_ = 0UL; |
||||
|
||||
ContextValue value_; |
||||
|
||||
DataList() = default; |
||||
|
||||
// Builds a data list off of a key and value iterable and returns the head
|
||||
template <class T> |
||||
DataList(const T &keys_and_vals) |
||||
{ |
||||
bool first = true; |
||||
auto *node = this; |
||||
for (auto &iter : keys_and_vals) |
||||
{ |
||||
if (first) |
||||
{ |
||||
*node = DataList(iter.first, iter.second); |
||||
first = false; |
||||
} |
||||
else |
||||
{ |
||||
node->next_ = nostd::shared_ptr<DataList>(new DataList(iter.first, iter.second)); |
||||
node = node->next_.get(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Builds a data list with just a key and value, so it will just be the head
|
||||
// and returns that head.
|
||||
DataList(nostd::string_view key, const ContextValue &value) |
||||
{ |
||||
key_ = new char[key.size()]; |
||||
key_length_ = key.size(); |
||||
std::memcpy(key_, key.data(), key.size() * sizeof(char)); |
||||
next_ = nostd::shared_ptr<DataList>{nullptr}; |
||||
value_ = value; |
||||
} |
||||
|
||||
DataList(const DataList &other) |
||||
: key_(new char[other.key_length_]), |
||||
next_(other.next_), |
||||
key_length_(other.key_length_), |
||||
value_(other.value_) |
||||
{ |
||||
std::memcpy(key_, other.key_, other.key_length_ * sizeof(char)); |
||||
} |
||||
|
||||
DataList &operator=(DataList &&other) noexcept |
||||
{ |
||||
key_length_ = other.key_length_; |
||||
value_ = std::move(other.value_); |
||||
next_ = std::move(other.next_); |
||||
|
||||
key_ = other.key_; |
||||
other.key_ = nullptr; |
||||
|
||||
return *this; |
||||
} |
||||
|
||||
~DataList() |
||||
{ |
||||
if (key_ != nullptr) |
||||
{ |
||||
delete[] key_; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
// Head of the list which holds the keys and values of this context
|
||||
nostd::shared_ptr<DataList> head_; |
||||
}; |
||||
} // namespace context
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,35 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <cstdint> |
||||
|
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/variant.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace baggage |
||||
{ |
||||
class Baggage; |
||||
} // namespace baggage
|
||||
|
||||
namespace trace |
||||
{ |
||||
class Span; |
||||
class SpanContext; |
||||
} // namespace trace
|
||||
|
||||
namespace context |
||||
{ |
||||
using ContextValue = nostd::variant<nostd::monostate, |
||||
bool, |
||||
int64_t, |
||||
uint64_t, |
||||
double, |
||||
nostd::shared_ptr<trace::Span>, |
||||
nostd::shared_ptr<trace::SpanContext>, |
||||
nostd::shared_ptr<baggage::Baggage>>; |
||||
} // namespace context
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,93 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <memory> |
||||
#include <vector> |
||||
|
||||
#include "opentelemetry/context/propagation/text_map_propagator.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace context |
||||
{ |
||||
namespace propagation |
||||
{ |
||||
|
||||
class CompositePropagator : public TextMapPropagator |
||||
{ |
||||
public: |
||||
CompositePropagator(std::vector<std::unique_ptr<TextMapPropagator>> propagators) |
||||
: propagators_(std::move(propagators)) |
||||
{} |
||||
|
||||
/**
|
||||
* Run each of the configured propagators with the given context and carrier. |
||||
* Propagators are run in the order they are configured, so if multiple |
||||
* propagators write the same carrier key, the propagator later in the list |
||||
* will "win". |
||||
* |
||||
* @param carrier Carrier into which context will be injected |
||||
* @param context Context to inject |
||||
* |
||||
*/ |
||||
|
||||
void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept override |
||||
{ |
||||
for (auto &p : propagators_) |
||||
{ |
||||
p->Inject(carrier, context); |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
* Run each of the configured propagators with the given context and carrier. |
||||
* Propagators are run in the order they are configured, so if multiple |
||||
* propagators write the same context key, the propagator later in the list |
||||
* will "win". |
||||
* |
||||
* @param carrier Carrier from which to extract context |
||||
* @param context Context to add values to |
||||
*/ |
||||
context::Context Extract(const TextMapCarrier &carrier, |
||||
context::Context &context) noexcept override |
||||
{ |
||||
auto first = true; |
||||
context::Context tmp_context; |
||||
for (auto &p : propagators_) |
||||
{ |
||||
if (first) |
||||
{ |
||||
tmp_context = p->Extract(carrier, context); |
||||
first = false; |
||||
} |
||||
else |
||||
{ |
||||
tmp_context = p->Extract(carrier, tmp_context); |
||||
} |
||||
} |
||||
return propagators_.size() ? tmp_context : context; |
||||
} |
||||
|
||||
/**
|
||||
* Invoke callback with fields set to carrier by `inject` method for all the |
||||
* configured propagators |
||||
* Returns true if all invocation return true |
||||
*/ |
||||
bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override |
||||
{ |
||||
bool status = true; |
||||
for (auto &p : propagators_) |
||||
{ |
||||
status = status && p->Fields(callback); |
||||
} |
||||
return status; |
||||
} |
||||
|
||||
private: |
||||
std::vector<std::unique_ptr<TextMapPropagator>> propagators_; |
||||
}; |
||||
} // namespace propagation
|
||||
} // namespace context
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,57 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <mutex> |
||||
|
||||
#include "opentelemetry/context/propagation/noop_propagator.h" |
||||
|
||||
#include "opentelemetry/common/macros.h" |
||||
#include "opentelemetry/common/spin_lock_mutex.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
|
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace context |
||||
{ |
||||
namespace propagation |
||||
{ |
||||
|
||||
class TextMapPropagator; |
||||
|
||||
/* Stores the singleton TextMapPropagator */ |
||||
|
||||
class OPENTELEMETRY_EXPORT GlobalTextMapPropagator |
||||
{ |
||||
public: |
||||
static nostd::shared_ptr<TextMapPropagator> GetGlobalPropagator() noexcept |
||||
{ |
||||
std::lock_guard<common::SpinLockMutex> guard(GetLock()); |
||||
return nostd::shared_ptr<TextMapPropagator>(GetPropagator()); |
||||
} |
||||
|
||||
static void SetGlobalPropagator(const nostd::shared_ptr<TextMapPropagator> &prop) noexcept |
||||
{ |
||||
std::lock_guard<common::SpinLockMutex> guard(GetLock()); |
||||
GetPropagator() = prop; |
||||
} |
||||
|
||||
private: |
||||
OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr<TextMapPropagator> &GetPropagator() noexcept |
||||
{ |
||||
static nostd::shared_ptr<TextMapPropagator> propagator(new NoOpPropagator()); |
||||
return propagator; |
||||
} |
||||
|
||||
OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept |
||||
{ |
||||
static common::SpinLockMutex lock; |
||||
return lock; |
||||
} |
||||
}; |
||||
|
||||
} // namespace propagation
|
||||
} // namespace context
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,40 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/context/propagation/text_map_propagator.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace context |
||||
{ |
||||
namespace propagation |
||||
{ |
||||
|
||||
/**
|
||||
* No-op implementation TextMapPropagator |
||||
*/ |
||||
class NoOpPropagator : public TextMapPropagator |
||||
{ |
||||
public: |
||||
/** Noop extract function does nothing and returns the input context */ |
||||
context::Context Extract(const TextMapCarrier & /*carrier*/, |
||||
context::Context &context) noexcept override |
||||
{ |
||||
return context; |
||||
} |
||||
|
||||
/** Noop inject function does nothing */ |
||||
void Inject(TextMapCarrier & /*carrier*/, |
||||
const context::Context & /* context */) noexcept override |
||||
{} |
||||
|
||||
bool Fields(nostd::function_ref<bool(nostd::string_view)> /* callback */) const noexcept override |
||||
{ |
||||
return true; |
||||
} |
||||
}; |
||||
} // namespace propagation
|
||||
} // namespace context
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,59 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/context/context.h" |
||||
#include "opentelemetry/nostd/function_ref.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace context |
||||
{ |
||||
namespace propagation |
||||
{ |
||||
|
||||
// TextMapCarrier is the storage medium used by TextMapPropagator.
|
||||
class TextMapCarrier |
||||
{ |
||||
public: |
||||
// returns the value associated with the passed key.
|
||||
virtual nostd::string_view Get(nostd::string_view key) const noexcept = 0; |
||||
|
||||
// stores the key-value pair.
|
||||
virtual void Set(nostd::string_view key, nostd::string_view value) noexcept = 0; |
||||
|
||||
/* list of all the keys in the carrier.
|
||||
By default, it returns true without invoking callback */ |
||||
virtual bool Keys(nostd::function_ref<bool(nostd::string_view)> /* callback */) const noexcept |
||||
{ |
||||
return true; |
||||
} |
||||
virtual ~TextMapCarrier() = default; |
||||
}; |
||||
|
||||
// The TextMapPropagator class provides an interface that enables extracting and injecting
|
||||
// context into carriers that travel in-band across process boundaries. HTTP frameworks and clients
|
||||
// can integrate with TextMapPropagator by providing the object containing the
|
||||
// headers, and a getter and setter function for the extraction and
|
||||
// injection of values, respectively.
|
||||
|
||||
class TextMapPropagator |
||||
{ |
||||
public: |
||||
// Returns the context that is stored in the carrier with the TextMapCarrier as extractor.
|
||||
virtual context::Context Extract(const TextMapCarrier &carrier, |
||||
context::Context &context) noexcept = 0; |
||||
|
||||
// Sets the context for carrier with self defined rules.
|
||||
virtual void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept = 0; |
||||
|
||||
// Gets the fields set in the carrier by the `inject` method
|
||||
virtual bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept = 0; |
||||
|
||||
virtual ~TextMapPropagator() = default; |
||||
}; |
||||
} // namespace propagation
|
||||
} // namespace context
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,340 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <stddef.h> |
||||
#include <algorithm> |
||||
|
||||
#include "opentelemetry/common/macros.h" |
||||
#include "opentelemetry/context/context.h" |
||||
#include "opentelemetry/context/context_value.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/unique_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace context |
||||
{ |
||||
// The Token object provides is returned when attaching objects to the
|
||||
// RuntimeContext object and is associated with a context object, and
|
||||
// can be provided to the RuntimeContext Detach method to remove the
|
||||
// associated context from the RuntimeContext.
|
||||
class Token |
||||
{ |
||||
public: |
||||
bool operator==(const Context &other) const noexcept { return context_ == other; } |
||||
|
||||
~Token() noexcept; |
||||
|
||||
private: |
||||
friend class RuntimeContextStorage; |
||||
|
||||
// A constructor that sets the token's Context object to the
|
||||
// one that was passed in.
|
||||
Token(const Context &context) : context_(context) {} |
||||
|
||||
const Context context_; |
||||
}; |
||||
|
||||
/**
|
||||
* RuntimeContextStorage is used by RuntimeContext to store Context frames. |
||||
* |
||||
* Custom context management strategies can be implemented by deriving from |
||||
* this class and passing an initialized RuntimeContextStorage object to |
||||
* RuntimeContext::SetRuntimeContextStorage. |
||||
*/ |
||||
class OPENTELEMETRY_EXPORT RuntimeContextStorage |
||||
{ |
||||
public: |
||||
/**
|
||||
* Return the current context. |
||||
* @return the current context |
||||
*/ |
||||
virtual Context GetCurrent() noexcept = 0; |
||||
|
||||
/**
|
||||
* Set the current context. |
||||
* @param the new current context |
||||
* @return a token for the new current context. This never returns a nullptr. |
||||
*/ |
||||
virtual nostd::unique_ptr<Token> Attach(const Context &context) noexcept = 0; |
||||
|
||||
/**
|
||||
* Detach the context related to the given token. |
||||
* @param token a token related to a context |
||||
* @return true if the context could be detached |
||||
*/ |
||||
virtual bool Detach(Token &token) noexcept = 0; |
||||
|
||||
virtual ~RuntimeContextStorage() {} |
||||
|
||||
protected: |
||||
nostd::unique_ptr<Token> CreateToken(const Context &context) noexcept |
||||
{ |
||||
return nostd::unique_ptr<Token>(new Token(context)); |
||||
} |
||||
}; |
||||
|
||||
/**
|
||||
* Construct and return the default RuntimeContextStorage |
||||
* @return a ThreadLocalContextStorage |
||||
*/ |
||||
static RuntimeContextStorage *GetDefaultStorage() noexcept; |
||||
|
||||
// Provides a wrapper for propagating the context object globally.
|
||||
//
|
||||
// By default, a thread-local runtime context storage is used.
|
||||
class OPENTELEMETRY_EXPORT RuntimeContext |
||||
{ |
||||
public: |
||||
// Return the current context.
|
||||
static Context GetCurrent() noexcept { return GetRuntimeContextStorage()->GetCurrent(); } |
||||
|
||||
// Sets the current 'Context' object. Returns a token
|
||||
// that can be used to reset to the previous Context.
|
||||
static nostd::unique_ptr<Token> Attach(const Context &context) noexcept |
||||
{ |
||||
return GetRuntimeContextStorage()->Attach(context); |
||||
} |
||||
|
||||
// Resets the context to a previous value stored in the
|
||||
// passed in token. Returns true if successful, false otherwise
|
||||
static bool Detach(Token &token) noexcept { return GetRuntimeContextStorage()->Detach(token); } |
||||
|
||||
// Sets the Key and Value into the passed in context or if a context is not
|
||||
// passed in, the RuntimeContext.
|
||||
// Should be used to SetValues to the current RuntimeContext, is essentially
|
||||
// equivalent to RuntimeContext::GetCurrent().SetValue(key,value). Keep in
|
||||
// mind that the current RuntimeContext will not be changed, and the new
|
||||
// context will be returned.
|
||||
static Context SetValue(nostd::string_view key, |
||||
const ContextValue &value, |
||||
Context *context = nullptr) noexcept |
||||
{ |
||||
Context temp_context; |
||||
if (context == nullptr) |
||||
{ |
||||
temp_context = GetCurrent(); |
||||
} |
||||
else |
||||
{ |
||||
temp_context = *context; |
||||
} |
||||
return temp_context.SetValue(key, value); |
||||
} |
||||
|
||||
// Returns the value associated with the passed in key and either the
|
||||
// passed in context* or the runtime context if a context is not passed in.
|
||||
// Should be used to get values from the current RuntimeContext, is
|
||||
// essentially equivalent to RuntimeContext::GetCurrent().GetValue(key).
|
||||
static ContextValue GetValue(nostd::string_view key, Context *context = nullptr) noexcept |
||||
{ |
||||
Context temp_context; |
||||
if (context == nullptr) |
||||
{ |
||||
temp_context = GetCurrent(); |
||||
} |
||||
else |
||||
{ |
||||
temp_context = *context; |
||||
} |
||||
return temp_context.GetValue(key); |
||||
} |
||||
|
||||
/**
|
||||
* Provide a custom runtime context storage. |
||||
* |
||||
* This provides a possibility to override the default thread-local runtime |
||||
* context storage. This has to be set before any spans are created by the |
||||
* application, otherwise the behavior is undefined. |
||||
* |
||||
* @param storage a custom runtime context storage |
||||
*/ |
||||
static void SetRuntimeContextStorage( |
||||
const nostd::shared_ptr<RuntimeContextStorage> &storage) noexcept |
||||
{ |
||||
GetStorage() = storage; |
||||
} |
||||
|
||||
/**
|
||||
* Provide a pointer to const runtime context storage. |
||||
* |
||||
* The returned pointer can only be used for extending the lifetime of the runtime context |
||||
* storage. |
||||
* |
||||
*/ |
||||
static nostd::shared_ptr<const RuntimeContextStorage> GetConstRuntimeContextStorage() noexcept |
||||
{ |
||||
return GetRuntimeContextStorage(); |
||||
} |
||||
|
||||
private: |
||||
static nostd::shared_ptr<RuntimeContextStorage> GetRuntimeContextStorage() noexcept |
||||
{ |
||||
return GetStorage(); |
||||
} |
||||
|
||||
OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr<RuntimeContextStorage> &GetStorage() noexcept |
||||
{ |
||||
static nostd::shared_ptr<RuntimeContextStorage> context(GetDefaultStorage()); |
||||
return context; |
||||
} |
||||
}; |
||||
|
||||
inline Token::~Token() noexcept |
||||
{ |
||||
context::RuntimeContext::Detach(*this); |
||||
} |
||||
|
||||
// The ThreadLocalContextStorage class is a derived class from
|
||||
// RuntimeContextStorage and provides a wrapper for propagating context through
|
||||
// cpp thread locally. This file must be included to use the RuntimeContext
|
||||
// class if another implementation has not been registered.
|
||||
class ThreadLocalContextStorage : public RuntimeContextStorage |
||||
{ |
||||
public: |
||||
ThreadLocalContextStorage() noexcept = default; |
||||
|
||||
// Return the current context.
|
||||
Context GetCurrent() noexcept override { return GetStack().Top(); } |
||||
|
||||
// Resets the context to the value previous to the passed in token. This will
|
||||
// also detach all child contexts of the passed in token.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool Detach(Token &token) noexcept override |
||||
{ |
||||
// In most cases, the context to be detached is on the top of the stack.
|
||||
if (token == GetStack().Top()) |
||||
{ |
||||
GetStack().Pop(); |
||||
return true; |
||||
} |
||||
|
||||
if (!GetStack().Contains(token)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
while (!(token == GetStack().Top())) |
||||
{ |
||||
GetStack().Pop(); |
||||
} |
||||
|
||||
GetStack().Pop(); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
// Sets the current 'Context' object. Returns a token
|
||||
// that can be used to reset to the previous Context.
|
||||
nostd::unique_ptr<Token> Attach(const Context &context) noexcept override |
||||
{ |
||||
GetStack().Push(context); |
||||
return CreateToken(context); |
||||
} |
||||
|
||||
private: |
||||
// A nested class to store the attached contexts in a stack.
|
||||
class Stack |
||||
{ |
||||
friend class ThreadLocalContextStorage; |
||||
|
||||
Stack() noexcept : size_(0), capacity_(0), base_(nullptr) {} |
||||
|
||||
// Pops the top Context off the stack.
|
||||
void Pop() noexcept |
||||
{ |
||||
if (size_ == 0) |
||||
{ |
||||
return; |
||||
} |
||||
// Store empty Context before decrementing `size`, to ensure
|
||||
// the shared_ptr object (if stored in prev context object ) are released.
|
||||
// The stack is not resized, and the unused memory would be reutilised
|
||||
// for subsequent context storage.
|
||||
base_[size_ - 1] = Context(); |
||||
size_ -= 1; |
||||
} |
||||
|
||||
bool Contains(const Token &token) const noexcept |
||||
{ |
||||
for (size_t pos = size_; pos > 0; --pos) |
||||
{ |
||||
if (token == base_[pos - 1]) |
||||
{ |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
// Returns the Context at the top of the stack.
|
||||
Context Top() const noexcept |
||||
{ |
||||
if (size_ == 0) |
||||
{ |
||||
return Context(); |
||||
} |
||||
return base_[size_ - 1]; |
||||
} |
||||
|
||||
// Pushes the passed in context pointer to the top of the stack
|
||||
// and resizes if necessary.
|
||||
void Push(const Context &context) noexcept |
||||
{ |
||||
size_++; |
||||
if (size_ > capacity_) |
||||
{ |
||||
Resize(size_ * 2); |
||||
} |
||||
base_[size_ - 1] = context; |
||||
} |
||||
|
||||
// Reallocates the storage array to the pass in new capacity size.
|
||||
void Resize(size_t new_capacity) noexcept |
||||
{ |
||||
size_t old_size = size_ - 1; |
||||
if (new_capacity == 0) |
||||
{ |
||||
new_capacity = 2; |
||||
} |
||||
Context *temp = new Context[new_capacity]; |
||||
if (base_ != nullptr) |
||||
{ |
||||
// vs2015 does not like this construct considering it unsafe:
|
||||
// - std::copy(base_, base_ + old_size, temp);
|
||||
// Ref.
|
||||
// https://stackoverflow.com/questions/12270224/xutility2227-warning-c4996-std-copy-impl
|
||||
for (size_t i = 0; i < (std::min)(old_size, new_capacity); i++) |
||||
{ |
||||
temp[i] = base_[i]; |
||||
} |
||||
delete[] base_; |
||||
} |
||||
base_ = temp; |
||||
capacity_ = new_capacity; |
||||
} |
||||
|
||||
~Stack() noexcept { delete[] base_; } |
||||
|
||||
size_t size_; |
||||
size_t capacity_; |
||||
Context *base_; |
||||
}; |
||||
|
||||
OPENTELEMETRY_API_SINGLETON Stack &GetStack() |
||||
{ |
||||
static thread_local Stack stack_ = Stack(); |
||||
return stack_; |
||||
} |
||||
}; |
||||
|
||||
static RuntimeContextStorage *GetDefaultStorage() noexcept |
||||
{ |
||||
return new ThreadLocalContextStorage(); |
||||
} |
||||
} // namespace context
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,25 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// NOTE - code within detail namespace implements internal details, and not part
|
||||
// of the public interface.
|
||||
|
||||
#pragma once |
||||
|
||||
#define OPENTELEMETRY_STRINGIFY(S) OPENTELEMETRY_STRINGIFY_(S) |
||||
#define OPENTELEMETRY_STRINGIFY_(S) #S |
||||
|
||||
#define OPENTELEMETRY_CONCAT(A, B) OPENTELEMETRY_CONCAT_(A, B) |
||||
#define OPENTELEMETRY_CONCAT_(A, B) A##B |
||||
|
||||
// Import the C++20 feature-test macros
|
||||
#ifdef __has_include |
||||
# if __has_include(<version>) |
||||
# include <version> |
||||
# endif |
||||
#elif defined(_MSC_VER) && ((defined(__cplusplus) && __cplusplus >= 202002L) || \ |
||||
(defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)) |
||||
# if _MSC_VER >= 1922 |
||||
# include <version> |
||||
# endif |
||||
#endif |
||||
@ -0,0 +1,37 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <algorithm> |
||||
|
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/unique_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace logs |
||||
{ |
||||
|
||||
/**
|
||||
* EventId class which acts the Id of the event with an optional name. |
||||
*/ |
||||
class EventId |
||||
{ |
||||
public: |
||||
EventId(int64_t id, nostd::string_view name) noexcept |
||||
: id_{id}, name_{nostd::unique_ptr<char[]>{new char[name.length() + 1]}} |
||||
{ |
||||
std::copy(name.begin(), name.end(), name_.get()); |
||||
name_.get()[name.length()] = 0; |
||||
} |
||||
|
||||
EventId(int64_t id) noexcept : id_{id}, name_{nullptr} {} |
||||
|
||||
public: |
||||
int64_t id_; |
||||
nostd::unique_ptr<char[]> name_; |
||||
}; |
||||
|
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,82 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/logs/log_record.h" |
||||
#include "opentelemetry/logs/logger.h" |
||||
#include "opentelemetry/logs/logger_type_traits.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/unique_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace logs |
||||
{ |
||||
#if OPENTELEMETRY_ABI_VERSION_NO < 2 |
||||
/**
|
||||
* Handles event log record creation. |
||||
**/ |
||||
class OPENTELEMETRY_DEPRECATED EventLogger |
||||
{ |
||||
public: |
||||
virtual ~EventLogger() = default; |
||||
|
||||
/* Returns the name of the logger */ |
||||
virtual const nostd::string_view GetName() noexcept = 0; |
||||
|
||||
/* Returns the delegate logger of this event logger */ |
||||
virtual nostd::shared_ptr<Logger> GetDelegateLogger() noexcept = 0; |
||||
|
||||
/**
|
||||
* Emit a event Log Record object |
||||
* |
||||
* @param event_name Event name |
||||
* @param log_record Log record |
||||
*/ |
||||
virtual void EmitEvent(nostd::string_view event_name, |
||||
nostd::unique_ptr<LogRecord> &&log_record) noexcept = 0; |
||||
|
||||
/**
|
||||
* Emit a event Log Record object with arguments |
||||
* |
||||
* @param event_name Event name |
||||
* @tparam args Arguments which can be used to set data of log record by type. |
||||
* Severity -> severity, severity_text |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,tace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> tace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void EmitEvent(nostd::string_view event_name, ArgumentType &&...args) |
||||
{ |
||||
nostd::shared_ptr<Logger> delegate_logger = GetDelegateLogger(); |
||||
if (!delegate_logger) |
||||
{ |
||||
return; |
||||
} |
||||
nostd::unique_ptr<LogRecord> log_record = delegate_logger->CreateLogRecord(); |
||||
|
||||
IgnoreTraitResult(detail::LogRecordSetterTrait<typename std::decay<ArgumentType>::type>::Set( |
||||
log_record.get(), std::forward<ArgumentType>(args))...); |
||||
|
||||
EmitEvent(event_name, std::move(log_record)); |
||||
} |
||||
|
||||
private: |
||||
template <class... ValueType> |
||||
void IgnoreTraitResult(ValueType &&...) |
||||
{} |
||||
}; |
||||
#endif |
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,37 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace logs |
||||
{ |
||||
|
||||
class EventLogger; |
||||
class Logger; |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO < 2 |
||||
/**
|
||||
* Creates new EventLogger instances. |
||||
*/ |
||||
class OPENTELEMETRY_DEPRECATED EventLoggerProvider |
||||
{ |
||||
public: |
||||
virtual ~EventLoggerProvider() = default; |
||||
|
||||
/**
|
||||
* Creates a named EventLogger instance. |
||||
* |
||||
*/ |
||||
|
||||
virtual nostd::shared_ptr<EventLogger> CreateEventLogger( |
||||
nostd::shared_ptr<Logger> delegate_logger, |
||||
nostd::string_view event_domain) noexcept = 0; |
||||
}; |
||||
#endif |
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,92 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/common/attribute_value.h" |
||||
#include "opentelemetry/common/timestamp.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace trace |
||||
{ |
||||
class SpanId; |
||||
class TraceId; |
||||
class TraceFlags; |
||||
} // namespace trace
|
||||
|
||||
namespace logs |
||||
{ |
||||
|
||||
enum class Severity : uint8_t; |
||||
|
||||
/**
|
||||
* Maintains a representation of a log in a format that can be processed by a recorder. |
||||
* |
||||
* This class is thread-compatible. |
||||
*/ |
||||
class LogRecord |
||||
{ |
||||
public: |
||||
virtual ~LogRecord() = default; |
||||
|
||||
/**
|
||||
* Set the timestamp for this log. |
||||
* @param timestamp the timestamp to set |
||||
*/ |
||||
virtual void SetTimestamp(common::SystemTimestamp timestamp) noexcept = 0; |
||||
|
||||
/**
|
||||
* Set the observed timestamp for this log. |
||||
* @param timestamp the timestamp to set |
||||
*/ |
||||
virtual void SetObservedTimestamp(common::SystemTimestamp timestamp) noexcept = 0; |
||||
|
||||
/**
|
||||
* Set the severity for this log. |
||||
* @param severity the severity of the event |
||||
*/ |
||||
virtual void SetSeverity(logs::Severity severity) noexcept = 0; |
||||
|
||||
/**
|
||||
* Set body field for this log. |
||||
* @param message the body to set |
||||
*/ |
||||
virtual void SetBody(const common::AttributeValue &message) noexcept = 0; |
||||
|
||||
/**
|
||||
* Set an attribute of a log. |
||||
* @param key the name of the attribute |
||||
* @param value the attribute value |
||||
*/ |
||||
virtual void SetAttribute(nostd::string_view key, |
||||
const common::AttributeValue &value) noexcept = 0; |
||||
|
||||
/**
|
||||
* Set the Event Id. |
||||
* @param id The event id to set |
||||
* @param name Optional event name to set |
||||
*/ |
||||
// TODO: mark this as pure virtual once all exporters have been updated
|
||||
virtual void SetEventId(int64_t id, nostd::string_view name = {}) noexcept = 0; |
||||
|
||||
/**
|
||||
* Set the trace id for this log. |
||||
* @param trace_id the trace id to set |
||||
*/ |
||||
virtual void SetTraceId(const trace::TraceId &trace_id) noexcept = 0; |
||||
|
||||
/**
|
||||
* Set the span id for this log. |
||||
* @param span_id the span id to set |
||||
*/ |
||||
virtual void SetSpanId(const trace::SpanId &span_id) noexcept = 0; |
||||
|
||||
/**
|
||||
* Inject trace_flags for this log. |
||||
* @param trace_flags the trace flags to set |
||||
*/ |
||||
virtual void SetTraceFlags(const trace::TraceFlags &trace_flags) noexcept = 0; |
||||
}; |
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,492 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/logs/logger_type_traits.h" |
||||
#include "opentelemetry/logs/severity.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/unique_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
class KeyValueIterable; |
||||
} // namespace common
|
||||
|
||||
namespace logs |
||||
{ |
||||
|
||||
class EventId; |
||||
class LogRecord; |
||||
|
||||
/**
|
||||
* Handles log record creation. |
||||
**/ |
||||
class Logger |
||||
{ |
||||
public: |
||||
virtual ~Logger() = default; |
||||
|
||||
/* Returns the name of the logger */ |
||||
virtual const nostd::string_view GetName() noexcept = 0; |
||||
|
||||
/**
|
||||
* Create a Log Record object |
||||
* |
||||
* @return nostd::unique_ptr<LogRecord> |
||||
*/ |
||||
virtual nostd::unique_ptr<LogRecord> CreateLogRecord() noexcept = 0; |
||||
|
||||
/**
|
||||
* Emit a Log Record object |
||||
* |
||||
* @param log_record Log record |
||||
*/ |
||||
virtual void EmitLogRecord(nostd::unique_ptr<LogRecord> &&log_record) noexcept = 0; |
||||
|
||||
/**
|
||||
* Emit a Log Record object with arguments |
||||
* |
||||
* @param log_record Log record |
||||
* @param args Arguments which can be used to set data of log record by type. |
||||
* Severity -> severity, severity_text |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,trace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> trace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void EmitLogRecord(nostd::unique_ptr<LogRecord> &&log_record, ArgumentType &&...args) |
||||
{ |
||||
if (!log_record) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
//
|
||||
// Keep the parameter pack unpacking order from left to right because left
|
||||
// ones are usually more important like severity and event_id than the
|
||||
// attributes. The left to right unpack order could pass the more important
|
||||
// data to processors to avoid caching and memory allocating.
|
||||
//
|
||||
#if __cplusplus <= 201402L |
||||
// C++14 does not support fold expressions for parameter pack expansion.
|
||||
int dummy[] = {(detail::LogRecordSetterTrait<typename std::decay<ArgumentType>::type>::Set( |
||||
log_record.get(), std::forward<ArgumentType>(args)), |
||||
0)...}; |
||||
IgnoreTraitResult(dummy); |
||||
#else |
||||
IgnoreTraitResult((detail::LogRecordSetterTrait<typename std::decay<ArgumentType>::type>::Set( |
||||
log_record.get(), std::forward<ArgumentType>(args)), |
||||
...)); |
||||
#endif |
||||
|
||||
EmitLogRecord(std::move(log_record)); |
||||
} |
||||
|
||||
/**
|
||||
* Emit a Log Record object with arguments |
||||
* |
||||
* @param args Arguments which can be used to set data of log record by type. |
||||
* Severity -> severity, severity_text |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,trace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> trace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void EmitLogRecord(ArgumentType &&...args) |
||||
{ |
||||
nostd::unique_ptr<LogRecord> log_record = CreateLogRecord(); |
||||
|
||||
EmitLogRecord(std::move(log_record), std::forward<ArgumentType>(args)...); |
||||
} |
||||
|
||||
/**
|
||||
* Writes a log with a severity of trace. |
||||
* @param args Arguments which can be used to set data of log record by type. |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,trace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> trace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void Trace(ArgumentType &&...args) noexcept |
||||
{ |
||||
static_assert( |
||||
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value, |
||||
"Severity is already set."); |
||||
this->EmitLogRecord(Severity::kTrace, std::forward<ArgumentType>(args)...); |
||||
} |
||||
|
||||
/**
|
||||
* Writes a log with a severity of debug. |
||||
* @param args Arguments which can be used to set data of log record by type. |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,trace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> trace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void Debug(ArgumentType &&...args) noexcept |
||||
{ |
||||
static_assert( |
||||
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value, |
||||
"Severity is already set."); |
||||
this->EmitLogRecord(Severity::kDebug, std::forward<ArgumentType>(args)...); |
||||
} |
||||
|
||||
/**
|
||||
* Writes a log with a severity of info. |
||||
* @param args Arguments which can be used to set data of log record by type. |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,trace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> trace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void Info(ArgumentType &&...args) noexcept |
||||
{ |
||||
static_assert( |
||||
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value, |
||||
"Severity is already set."); |
||||
this->EmitLogRecord(Severity::kInfo, std::forward<ArgumentType>(args)...); |
||||
} |
||||
|
||||
/**
|
||||
* Writes a log with a severity of warn. |
||||
* @param args Arguments which can be used to set data of log record by type. |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,trace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> trace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void Warn(ArgumentType &&...args) noexcept |
||||
{ |
||||
static_assert( |
||||
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value, |
||||
"Severity is already set."); |
||||
this->EmitLogRecord(Severity::kWarn, std::forward<ArgumentType>(args)...); |
||||
} |
||||
|
||||
/**
|
||||
* Writes a log with a severity of error. |
||||
* @param args Arguments which can be used to set data of log record by type. |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,trace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> trace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void Error(ArgumentType &&...args) noexcept |
||||
{ |
||||
static_assert( |
||||
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value, |
||||
"Severity is already set."); |
||||
this->EmitLogRecord(Severity::kError, std::forward<ArgumentType>(args)...); |
||||
} |
||||
|
||||
/**
|
||||
* Writes a log with a severity of fatal. |
||||
* @param args Arguments which can be used to set data of log record by type. |
||||
* string_view -> body |
||||
* AttributeValue -> body |
||||
* SpanContext -> span_id,trace_id and trace_flags |
||||
* SpanId -> span_id |
||||
* TraceId -> trace_id |
||||
* TraceFlags -> trace_flags |
||||
* SystemTimestamp -> timestamp |
||||
* system_clock::time_point -> timestamp |
||||
* KeyValueIterable -> attributes |
||||
* Key value iterable container -> attributes |
||||
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes) |
||||
*/ |
||||
template <class... ArgumentType> |
||||
void Fatal(ArgumentType &&...args) noexcept |
||||
{ |
||||
static_assert( |
||||
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value, |
||||
"Severity is already set."); |
||||
this->EmitLogRecord(Severity::kFatal, std::forward<ArgumentType>(args)...); |
||||
} |
||||
|
||||
//
|
||||
// OpenTelemetry C++ user-facing Logs API
|
||||
//
|
||||
|
||||
inline bool Enabled(Severity severity, const EventId &event_id) const noexcept |
||||
{ |
||||
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity)) |
||||
{ |
||||
return false; |
||||
} |
||||
return EnabledImplementation(severity, event_id); |
||||
} |
||||
|
||||
inline bool Enabled(Severity severity, int64_t event_id) const noexcept |
||||
{ |
||||
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity)) |
||||
{ |
||||
return false; |
||||
} |
||||
return EnabledImplementation(severity, event_id); |
||||
} |
||||
|
||||
inline bool Enabled(Severity severity) const noexcept |
||||
{ |
||||
return static_cast<uint8_t>(severity) >= OPENTELEMETRY_ATOMIC_READ_8(&minimum_severity_); |
||||
} |
||||
|
||||
/**
|
||||
* Log an event |
||||
* |
||||
* @severity severity of the log |
||||
* @event_id event identifier of the log |
||||
* @format an utf-8 string following https://messagetemplates.org/
|
||||
* @attributes key value pairs of the log |
||||
*/ |
||||
virtual void Log(Severity severity, |
||||
const EventId &event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->EmitLogRecord(severity, event_id, format, attributes); |
||||
} |
||||
|
||||
virtual void Log(Severity severity, |
||||
int64_t event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->EmitLogRecord(severity, EventId{event_id}, format, attributes); |
||||
} |
||||
|
||||
virtual void Log(Severity severity, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->EmitLogRecord(severity, format, attributes); |
||||
} |
||||
|
||||
virtual void Log(Severity severity, nostd::string_view message) noexcept |
||||
{ |
||||
this->EmitLogRecord(severity, message); |
||||
} |
||||
|
||||
// Convenient wrappers based on virtual methods Log().
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber
|
||||
|
||||
inline void Trace(const EventId &event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kTrace, event_id, format, attributes); |
||||
} |
||||
|
||||
inline void Trace(int64_t event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kTrace, EventId{event_id}, format, attributes); |
||||
} |
||||
|
||||
inline void Trace(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kTrace, format, attributes); |
||||
} |
||||
|
||||
inline void Trace(nostd::string_view message) noexcept { this->Log(Severity::kTrace, message); } |
||||
|
||||
inline void Debug(const EventId &event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kDebug, event_id, format, attributes); |
||||
} |
||||
|
||||
inline void Debug(int64_t event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kDebug, EventId{event_id}, format, attributes); |
||||
} |
||||
|
||||
inline void Debug(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kDebug, format, attributes); |
||||
} |
||||
|
||||
inline void Debug(nostd::string_view message) noexcept { this->Log(Severity::kDebug, message); } |
||||
|
||||
inline void Info(const EventId &event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kInfo, event_id, format, attributes); |
||||
} |
||||
|
||||
inline void Info(int64_t event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kInfo, EventId{event_id}, format, attributes); |
||||
} |
||||
|
||||
inline void Info(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kInfo, format, attributes); |
||||
} |
||||
|
||||
inline void Info(nostd::string_view message) noexcept { this->Log(Severity::kInfo, message); } |
||||
|
||||
inline void Warn(const EventId &event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kWarn, event_id, format, attributes); |
||||
} |
||||
|
||||
inline void Warn(int64_t event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kWarn, EventId{event_id}, format, attributes); |
||||
} |
||||
|
||||
inline void Warn(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kWarn, format, attributes); |
||||
} |
||||
|
||||
inline void Warn(nostd::string_view message) noexcept { this->Log(Severity::kWarn, message); } |
||||
|
||||
inline void Error(const EventId &event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kError, event_id, format, attributes); |
||||
} |
||||
|
||||
inline void Error(int64_t event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kError, EventId{event_id}, format, attributes); |
||||
} |
||||
|
||||
inline void Error(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kError, format, attributes); |
||||
} |
||||
|
||||
inline void Error(nostd::string_view message) noexcept { this->Log(Severity::kError, message); } |
||||
|
||||
inline void Fatal(const EventId &event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kFatal, event_id, format, attributes); |
||||
} |
||||
|
||||
inline void Fatal(int64_t event_id, |
||||
nostd::string_view format, |
||||
const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kFatal, EventId{event_id}, format, attributes); |
||||
} |
||||
|
||||
inline void Fatal(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept |
||||
{ |
||||
this->Log(Severity::kFatal, format, attributes); |
||||
} |
||||
|
||||
inline void Fatal(nostd::string_view message) noexcept { this->Log(Severity::kFatal, message); } |
||||
|
||||
//
|
||||
// End of OpenTelemetry C++ user-facing Log API.
|
||||
//
|
||||
|
||||
protected: |
||||
// TODO: discuss with community about naming for internal methods.
|
||||
virtual bool EnabledImplementation(Severity /*severity*/, |
||||
const EventId & /*event_id*/) const noexcept |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
virtual bool EnabledImplementation(Severity /*severity*/, int64_t /*event_id*/) const noexcept |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
void SetMinimumSeverity(uint8_t severity_or_max) noexcept |
||||
{ |
||||
OPENTELEMETRY_ATOMIC_WRITE_8(&minimum_severity_, severity_or_max); |
||||
} |
||||
|
||||
private: |
||||
template <class... ValueType> |
||||
void IgnoreTraitResult(ValueType &&...) |
||||
{} |
||||
|
||||
//
|
||||
// minimum_severity_ can be updated concurrently by multiple threads/cores, so race condition on
|
||||
// read/write should be handled. And std::atomic can not be used here because it is not ABI
|
||||
// compatible for OpenTelemetry C++ API.
|
||||
//
|
||||
mutable uint8_t minimum_severity_{kMaxSeverity}; |
||||
}; |
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,71 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/common/key_value_iterable.h" |
||||
#include "opentelemetry/common/key_value_iterable_view.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/span.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/type_traits.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace logs |
||||
{ |
||||
|
||||
class Logger; |
||||
|
||||
/**
|
||||
* Creates new Logger instances. |
||||
*/ |
||||
class OPENTELEMETRY_EXPORT LoggerProvider |
||||
{ |
||||
public: |
||||
virtual ~LoggerProvider() = default; |
||||
|
||||
/**
|
||||
* Gets or creates a named Logger instance. |
||||
* |
||||
* Optionally a version can be passed to create a named and versioned Logger |
||||
* instance. |
||||
* |
||||
* Optionally a configuration file name can be passed to create a configuration for |
||||
* the Logger instance. |
||||
* |
||||
*/ |
||||
|
||||
virtual nostd::shared_ptr<Logger> GetLogger( |
||||
nostd::string_view logger_name, |
||||
nostd::string_view library_name = "", |
||||
nostd::string_view library_version = "", |
||||
nostd::string_view schema_url = "", |
||||
const common::KeyValueIterable &attributes = common::NoopKeyValueIterable()) = 0; |
||||
|
||||
nostd::shared_ptr<Logger> GetLogger( |
||||
nostd::string_view logger_name, |
||||
nostd::string_view library_name, |
||||
nostd::string_view library_version, |
||||
nostd::string_view schema_url, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes) |
||||
{ |
||||
return GetLogger(logger_name, library_name, library_version, schema_url, |
||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}); |
||||
} |
||||
|
||||
template <class T, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr> |
||||
nostd::shared_ptr<Logger> GetLogger(nostd::string_view logger_name, |
||||
nostd::string_view library_name, |
||||
nostd::string_view library_version, |
||||
nostd::string_view schema_url, |
||||
const T &attributes) |
||||
{ |
||||
return GetLogger(logger_name, library_name, library_version, schema_url, |
||||
common::KeyValueIterableView<T>(attributes)); |
||||
} |
||||
}; |
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,204 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <chrono> |
||||
#include <memory> |
||||
#include <type_traits> |
||||
|
||||
#include "opentelemetry/common/attribute_value.h" |
||||
#include "opentelemetry/common/key_value_iterable.h" |
||||
#include "opentelemetry/common/timestamp.h" |
||||
#include "opentelemetry/logs/event_id.h" |
||||
#include "opentelemetry/logs/log_record.h" |
||||
#include "opentelemetry/logs/severity.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/type_traits.h" |
||||
#include "opentelemetry/trace/span_context.h" |
||||
#include "opentelemetry/trace/span_id.h" |
||||
#include "opentelemetry/trace/trace_flags.h" |
||||
#include "opentelemetry/trace/trace_id.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace logs |
||||
{ |
||||
namespace detail |
||||
{ |
||||
template <class ValueType> |
||||
struct LogRecordSetterTrait; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<Severity> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetSeverity(std::forward<ArgumentType>(arg)); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<EventId> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetEventId(arg.id_, nostd::string_view{arg.name_.get()}); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<trace::SpanContext> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetSpanId(arg.span_id()); |
||||
log_record->SetTraceId(arg.trace_id()); |
||||
log_record->SetTraceFlags(arg.trace_flags()); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<trace::SpanId> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetSpanId(std::forward<ArgumentType>(arg)); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<trace::TraceId> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetTraceId(std::forward<ArgumentType>(arg)); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<trace::TraceFlags> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetTraceFlags(std::forward<ArgumentType>(arg)); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<common::SystemTimestamp> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetTimestamp(std::forward<ArgumentType>(arg)); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<std::chrono::system_clock::time_point> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetTimestamp(common::SystemTimestamp(std::forward<ArgumentType>(arg))); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <> |
||||
struct LogRecordSetterTrait<common::KeyValueIterable> |
||||
{ |
||||
template <class ArgumentType> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
arg.ForEachKeyValue( |
||||
[&log_record](nostd::string_view key, common::AttributeValue value) noexcept { |
||||
log_record->SetAttribute(key, value); |
||||
return true; |
||||
}); |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <class ValueType> |
||||
struct LogRecordSetterTrait |
||||
{ |
||||
static_assert(!std::is_same<nostd::unique_ptr<LogRecord>, ValueType>::value && |
||||
!std::is_same<std::unique_ptr<LogRecord>, ValueType>::value, |
||||
"unique_ptr<LogRecord> is not allowed, please use std::move()"); |
||||
|
||||
template <class ArgumentType, |
||||
nostd::enable_if_t<std::is_convertible<ArgumentType, nostd::string_view>::value || |
||||
std::is_convertible<ArgumentType, common::AttributeValue>::value, |
||||
void> * = nullptr> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
log_record->SetBody(std::forward<ArgumentType>(arg)); |
||||
|
||||
return log_record; |
||||
} |
||||
|
||||
template <class ArgumentType, |
||||
nostd::enable_if_t<std::is_base_of<common::KeyValueIterable, ArgumentType>::value, bool> |
||||
* = nullptr> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
return LogRecordSetterTrait<common::KeyValueIterable>::Set(log_record, |
||||
std::forward<ArgumentType>(arg)); |
||||
} |
||||
|
||||
template <class ArgumentType, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<ArgumentType>::value, int> * = |
||||
nullptr> |
||||
inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept |
||||
{ |
||||
for (auto &argv : arg) |
||||
{ |
||||
log_record->SetAttribute(argv.first, argv.second); |
||||
} |
||||
|
||||
return log_record; |
||||
} |
||||
}; |
||||
|
||||
template <class ValueType, class... ArgumentType> |
||||
struct LogRecordHasType; |
||||
|
||||
template <class ValueType> |
||||
struct LogRecordHasType<ValueType> : public std::false_type |
||||
{}; |
||||
|
||||
template <class ValueType, class TargetType, class... ArgumentType> |
||||
struct LogRecordHasType<ValueType, TargetType, ArgumentType...> |
||||
: public std::conditional<std::is_same<ValueType, TargetType>::value, |
||||
std::true_type, |
||||
LogRecordHasType<ValueType, ArgumentType...>>::type |
||||
{}; |
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,131 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
// Please refer to provider.h for documentation on how to obtain a Logger object.
|
||||
//
|
||||
// This file is part of the internal implementation of OpenTelemetry. Nothing in this file should be
|
||||
// used directly. Please refer to logger.h for documentation on these interfaces.
|
||||
|
||||
#include "opentelemetry/logs/event_logger.h" |
||||
#include "opentelemetry/logs/event_logger_provider.h" |
||||
#include "opentelemetry/logs/logger.h" |
||||
#include "opentelemetry/logs/logger_provider.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/unique_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace common |
||||
{ |
||||
class KeyValueIterable; |
||||
} // namespace common
|
||||
|
||||
namespace logs |
||||
{ |
||||
/**
|
||||
* No-op implementation of Logger. This class should not be used directly. It should only be |
||||
* instantiated using a LoggerProvider's GetLogger() call. |
||||
*/ |
||||
class NoopLogger final : public Logger |
||||
{ |
||||
public: |
||||
const nostd::string_view GetName() noexcept override { return "noop logger"; } |
||||
|
||||
nostd::unique_ptr<LogRecord> CreateLogRecord() noexcept override |
||||
{ |
||||
/*
|
||||
* Do not return memory shared between threads, |
||||
* a `new` + `delete` for each noop record can not be avoided, |
||||
* due to the semantic of unique_ptr. |
||||
*/ |
||||
return nostd::unique_ptr<LogRecord>(new NoopLogRecord()); |
||||
} |
||||
|
||||
using Logger::EmitLogRecord; |
||||
|
||||
void EmitLogRecord(nostd::unique_ptr<LogRecord> &&) noexcept override {} |
||||
|
||||
private: |
||||
class NoopLogRecord : public LogRecord |
||||
{ |
||||
public: |
||||
NoopLogRecord() = default; |
||||
~NoopLogRecord() override = default; |
||||
|
||||
void SetTimestamp(common::SystemTimestamp /* timestamp */) noexcept override {} |
||||
void SetObservedTimestamp(common::SystemTimestamp /* timestamp */) noexcept override {} |
||||
void SetSeverity(logs::Severity /* severity */) noexcept override {} |
||||
void SetBody(const common::AttributeValue & /* message */) noexcept override {} |
||||
void SetAttribute(nostd::string_view /* key */, |
||||
const common::AttributeValue & /* value */) noexcept override |
||||
{} |
||||
void SetEventId(int64_t /* id */, nostd::string_view /* name */) noexcept override {} |
||||
void SetTraceId(const trace::TraceId & /* trace_id */) noexcept override {} |
||||
void SetSpanId(const trace::SpanId & /* span_id */) noexcept override {} |
||||
void SetTraceFlags(const trace::TraceFlags & /* trace_flags */) noexcept override {} |
||||
}; |
||||
}; |
||||
|
||||
/**
|
||||
* No-op implementation of a LoggerProvider. |
||||
*/ |
||||
class NoopLoggerProvider final : public LoggerProvider |
||||
{ |
||||
public: |
||||
NoopLoggerProvider() : logger_{nostd::shared_ptr<NoopLogger>(new NoopLogger())} {} |
||||
|
||||
nostd::shared_ptr<Logger> GetLogger(nostd::string_view /* logger_name */, |
||||
nostd::string_view /* library_name */, |
||||
nostd::string_view /* library_version */, |
||||
nostd::string_view /* schema_url */, |
||||
const common::KeyValueIterable & /* attributes */) override |
||||
{ |
||||
return logger_; |
||||
} |
||||
|
||||
private: |
||||
nostd::shared_ptr<Logger> logger_; |
||||
}; |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO < 2 |
||||
class NoopEventLogger final : public EventLogger |
||||
{ |
||||
public: |
||||
NoopEventLogger() : logger_{nostd::shared_ptr<NoopLogger>(new NoopLogger())} {} |
||||
|
||||
const nostd::string_view GetName() noexcept override { return "noop event logger"; } |
||||
|
||||
nostd::shared_ptr<Logger> GetDelegateLogger() noexcept override { return logger_; } |
||||
|
||||
void EmitEvent(nostd::string_view, nostd::unique_ptr<LogRecord> &&) noexcept override {} |
||||
|
||||
private: |
||||
nostd::shared_ptr<Logger> logger_; |
||||
}; |
||||
|
||||
/**
|
||||
* No-op implementation of a EventLoggerProvider. |
||||
*/ |
||||
class NoopEventLoggerProvider final : public EventLoggerProvider |
||||
{ |
||||
public: |
||||
NoopEventLoggerProvider() : event_logger_{nostd::shared_ptr<EventLogger>(new NoopEventLogger())} |
||||
{} |
||||
|
||||
nostd::shared_ptr<EventLogger> CreateEventLogger( |
||||
nostd::shared_ptr<Logger> /*delegate_logger*/, |
||||
nostd::string_view /*event_domain*/) noexcept override |
||||
{ |
||||
return event_logger_; |
||||
} |
||||
|
||||
private: |
||||
nostd::shared_ptr<EventLogger> event_logger_; |
||||
}; |
||||
#endif |
||||
|
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,100 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <mutex> |
||||
|
||||
#include "opentelemetry/common/macros.h" |
||||
#include "opentelemetry/common/spin_lock_mutex.h" |
||||
#include "opentelemetry/logs/noop.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace logs |
||||
{ |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO < 2 |
||||
class EventLoggerProvider; |
||||
#endif |
||||
class LoggerProvider; |
||||
|
||||
/**
|
||||
* Stores the singleton global LoggerProvider. |
||||
*/ |
||||
class OPENTELEMETRY_EXPORT Provider |
||||
{ |
||||
public: |
||||
/**
|
||||
* Returns the singleton LoggerProvider. |
||||
* |
||||
* By default, a no-op LoggerProvider is returned. This will never return a |
||||
* nullptr LoggerProvider. |
||||
*/ |
||||
static nostd::shared_ptr<LoggerProvider> GetLoggerProvider() noexcept |
||||
{ |
||||
std::lock_guard<common::SpinLockMutex> guard(GetLock()); |
||||
return nostd::shared_ptr<LoggerProvider>(GetProvider()); |
||||
} |
||||
|
||||
/**
|
||||
* Changes the singleton LoggerProvider. |
||||
*/ |
||||
static void SetLoggerProvider(const nostd::shared_ptr<LoggerProvider> &tp) noexcept |
||||
{ |
||||
std::lock_guard<common::SpinLockMutex> guard(GetLock()); |
||||
GetProvider() = tp; |
||||
} |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO < 2 |
||||
/**
|
||||
* Returns the singleton EventLoggerProvider. |
||||
* |
||||
* By default, a no-op EventLoggerProvider is returned. This will never return a |
||||
* nullptr EventLoggerProvider. |
||||
*/ |
||||
OPENTELEMETRY_DEPRECATED static nostd::shared_ptr<EventLoggerProvider> |
||||
GetEventLoggerProvider() noexcept |
||||
{ |
||||
std::lock_guard<common::SpinLockMutex> guard(GetLock()); |
||||
return nostd::shared_ptr<EventLoggerProvider>(GetEventProvider()); |
||||
} |
||||
|
||||
/**
|
||||
* Changes the singleton EventLoggerProvider. |
||||
*/ |
||||
OPENTELEMETRY_DEPRECATED static void SetEventLoggerProvider( |
||||
const nostd::shared_ptr<EventLoggerProvider> &tp) noexcept |
||||
{ |
||||
std::lock_guard<common::SpinLockMutex> guard(GetLock()); |
||||
GetEventProvider() = tp; |
||||
} |
||||
#endif |
||||
|
||||
private: |
||||
OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr<LoggerProvider> &GetProvider() noexcept |
||||
{ |
||||
static nostd::shared_ptr<LoggerProvider> provider(new NoopLoggerProvider); |
||||
return provider; |
||||
} |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO < 2 |
||||
OPENTELEMETRY_DEPRECATED |
||||
OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr<EventLoggerProvider> & |
||||
GetEventProvider() noexcept |
||||
{ |
||||
static nostd::shared_ptr<EventLoggerProvider> provider(new NoopEventLoggerProvider); |
||||
return provider; |
||||
} |
||||
#endif |
||||
|
||||
OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept |
||||
{ |
||||
static common::SpinLockMutex lock; |
||||
return lock; |
||||
} |
||||
}; |
||||
|
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,67 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <cstdint> |
||||
|
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace logs |
||||
{ |
||||
|
||||
/**
|
||||
* Severity Levels assigned to log events, based on Log Data Model, |
||||
* with the addition of kInvalid (mapped to a severity number of 0). |
||||
* |
||||
* See |
||||
* https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber
|
||||
*/ |
||||
enum class Severity : uint8_t |
||||
{ |
||||
kInvalid = 0, |
||||
kTrace = 1, |
||||
kTrace2 = 2, |
||||
kTrace3 = 3, |
||||
kTrace4 = 4, |
||||
kDebug = 5, |
||||
kDebug2 = 6, |
||||
kDebug3 = 7, |
||||
kDebug4 = 8, |
||||
kInfo = 9, |
||||
kInfo2 = 10, |
||||
kInfo3 = 11, |
||||
kInfo4 = 12, |
||||
kWarn = 13, |
||||
kWarn2 = 14, |
||||
kWarn3 = 15, |
||||
kWarn4 = 16, |
||||
kError = 17, |
||||
kError2 = 18, |
||||
kError3 = 19, |
||||
kError4 = 20, |
||||
kFatal = 21, |
||||
kFatal2 = 22, |
||||
kFatal3 = 23, |
||||
kFatal4 = 24 |
||||
}; |
||||
|
||||
const uint8_t kMaxSeverity = 255; |
||||
|
||||
/**
|
||||
* Mapping of the severity enum above, to a severity text string (in all caps). |
||||
* This severity text can be printed out by exporters. Capital letters follow the |
||||
* spec naming convention. |
||||
* |
||||
* Included to follow the specification's recommendation to print both |
||||
* severity number and text in each log record. |
||||
*/ |
||||
const nostd::string_view SeverityNumToText[25] = { |
||||
"INVALID", "TRACE", "TRACE2", "TRACE3", "TRACE4", "DEBUG", "DEBUG2", "DEBUG3", "DEBUG4", |
||||
"INFO", "INFO2", "INFO3", "INFO4", "WARN", "WARN2", "WARN3", "WARN4", "ERROR", |
||||
"ERROR2", "ERROR3", "ERROR4", "FATAL", "FATAL2", "FATAL3", "FATAL4"}; |
||||
|
||||
} // namespace logs
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,33 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/metrics/observer_result.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace metrics |
||||
{ |
||||
|
||||
using ObservableCallbackPtr = void (*)(ObserverResult, void *); |
||||
|
||||
class ObservableInstrument |
||||
{ |
||||
public: |
||||
ObservableInstrument() = default; |
||||
virtual ~ObservableInstrument() = default; |
||||
|
||||
/**
|
||||
* Sets up a function that will be called whenever a metric collection is initiated. |
||||
*/ |
||||
virtual void AddCallback(ObservableCallbackPtr, void *state) noexcept = 0; |
||||
|
||||
/**
|
||||
* Remove a function that was configured to be called whenever a metric collection is initiated. |
||||
*/ |
||||
virtual void RemoveCallback(ObservableCallbackPtr, void *state) noexcept = 0; |
||||
}; |
||||
|
||||
} // namespace metrics
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,174 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/unique_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace metrics |
||||
{ |
||||
|
||||
template <typename T> |
||||
class Counter; |
||||
|
||||
template <typename T> |
||||
class Histogram; |
||||
|
||||
template <typename T> |
||||
class UpDownCounter; |
||||
|
||||
template <typename T> |
||||
class Gauge; |
||||
|
||||
class ObservableInstrument; |
||||
|
||||
/**
|
||||
* Handles instrument creation and provides a facility for batch recording. |
||||
* |
||||
* This class provides methods to create new metric instruments, record a |
||||
* batch of values to a specified set of instruments, and collect |
||||
* measurements from all instruments. |
||||
* |
||||
*/ |
||||
class Meter |
||||
{ |
||||
public: |
||||
virtual ~Meter() = default; |
||||
|
||||
/**
|
||||
* Creates a Counter with the passed characteristics and returns a unique_ptr to that Counter. |
||||
* |
||||
* @param name the name of the new Counter. |
||||
* @param description a brief description of what the Counter is used for. |
||||
* @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
|
||||
* @return a shared pointer to the created Counter. |
||||
*/ |
||||
|
||||
virtual nostd::unique_ptr<Counter<uint64_t>> CreateUInt64Counter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
virtual nostd::unique_ptr<Counter<double>> CreateDoubleCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
/**
|
||||
* Creates a Asynchronous (Observable) counter with the passed characteristics and returns a |
||||
* shared_ptr to that Observable Counter |
||||
* |
||||
* @param name the name of the new Observable Counter. |
||||
* @param description a brief description of what the Observable Counter is used for. |
||||
* @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
|
||||
*/ |
||||
virtual nostd::shared_ptr<ObservableInstrument> CreateInt64ObservableCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
virtual nostd::shared_ptr<ObservableInstrument> CreateDoubleObservableCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
/**
|
||||
* Creates a Histogram with the passed characteristics and returns a unique_ptr to that Histogram. |
||||
* |
||||
* @param name the name of the new Histogram. |
||||
* @param description a brief description of what the Histogram is used for. |
||||
* @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
|
||||
* @return a shared pointer to the created Histogram. |
||||
*/ |
||||
virtual nostd::unique_ptr<Histogram<uint64_t>> CreateUInt64Histogram( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
virtual nostd::unique_ptr<Histogram<double>> CreateDoubleHistogram( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
/**
|
||||
* Creates a Gauge with the passed characteristics and returns a unique_ptr to that Gauge. |
||||
* |
||||
* @param name the name of the new Gauge. |
||||
* @param description a brief description of what the Gauge is used for. |
||||
* @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
|
||||
* @return a unique pointer to the created Gauge. |
||||
*/ |
||||
|
||||
virtual nostd::unique_ptr<Gauge<int64_t>> CreateInt64Gauge( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
virtual nostd::unique_ptr<Gauge<double>> CreateDoubleGauge( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
#endif |
||||
|
||||
/**
|
||||
* Creates a Asynchronous (Observable) Gauge with the passed characteristics and returns a |
||||
* shared_ptr to that Observable Gauge |
||||
* |
||||
* @param name the name of the new Observable Gauge. |
||||
* @param description a brief description of what the Observable Gauge is used for. |
||||
* @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
|
||||
*/ |
||||
virtual nostd::shared_ptr<ObservableInstrument> CreateInt64ObservableGauge( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
virtual nostd::shared_ptr<ObservableInstrument> CreateDoubleObservableGauge( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
/**
|
||||
* Creates an UpDownCounter with the passed characteristics and returns a unique_ptr to that |
||||
* UpDownCounter. |
||||
* |
||||
* @param name the name of the new UpDownCounter. |
||||
* @param description a brief description of what the UpDownCounter is used for. |
||||
* @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
|
||||
* @return a shared pointer to the created UpDownCounter. |
||||
*/ |
||||
virtual nostd::unique_ptr<UpDownCounter<int64_t>> CreateInt64UpDownCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
virtual nostd::unique_ptr<UpDownCounter<double>> CreateDoubleUpDownCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
/**
|
||||
* Creates a Asynchronous (Observable) UpDownCounter with the passed characteristics and returns |
||||
* a shared_ptr to that Observable UpDownCounter |
||||
* |
||||
* @param name the name of the new Observable UpDownCounter. |
||||
* @param description a brief description of what the Observable UpDownCounter is used for. |
||||
* @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
|
||||
*/ |
||||
virtual nostd::shared_ptr<ObservableInstrument> CreateInt64ObservableUpDownCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
|
||||
virtual nostd::shared_ptr<ObservableInstrument> CreateDoubleObservableUpDownCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept = 0; |
||||
}; |
||||
} // namespace metrics
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,148 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/common/key_value_iterable.h" |
||||
#include "opentelemetry/common/key_value_iterable_view.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/type_traits.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace metrics |
||||
{ |
||||
|
||||
class Meter; |
||||
|
||||
/**
|
||||
* Creates new Meter instances. |
||||
*/ |
||||
class MeterProvider |
||||
{ |
||||
public: |
||||
virtual ~MeterProvider() = default; |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
|
||||
/**
|
||||
* Gets or creates a named Meter instance (ABI). |
||||
* |
||||
* @since ABI_VERSION 2 |
||||
* |
||||
* @param[in] name Meter instrumentation scope |
||||
* @param[in] version Instrumentation scope version |
||||
* @param[in] schema_url Instrumentation scope schema URL |
||||
* @param[in] attributes Instrumentation scope attributes (optional, may be nullptr) |
||||
*/ |
||||
virtual nostd::shared_ptr<Meter> GetMeter( |
||||
nostd::string_view name, |
||||
nostd::string_view version, |
||||
nostd::string_view schema_url, |
||||
const common::KeyValueIterable *attributes) noexcept = 0; |
||||
|
||||
/**
|
||||
* Gets or creates a named Meter instance (API helper). |
||||
* |
||||
* @since ABI_VERSION 2 |
||||
* |
||||
* @param[in] name Meter instrumentation scope |
||||
* @param[in] version Instrumentation scope version, optional |
||||
* @param[in] schema_url Instrumentation scope schema URL, optional |
||||
*/ |
||||
nostd::shared_ptr<Meter> GetMeter(nostd::string_view name, |
||||
nostd::string_view version = "", |
||||
nostd::string_view schema_url = "") |
||||
{ |
||||
return GetMeter(name, version, schema_url, nullptr); |
||||
} |
||||
|
||||
/**
|
||||
* Gets or creates a named Meter instance (API helper). |
||||
* |
||||
* @since ABI_VERSION 2 |
||||
* |
||||
* @param[in] name Meter instrumentation scope |
||||
* @param[in] version Instrumentation scope version |
||||
* @param[in] schema_url Instrumentation scope schema URL |
||||
* @param[in] attributes Instrumentation scope attributes |
||||
*/ |
||||
nostd::shared_ptr<Meter> GetMeter( |
||||
nostd::string_view name, |
||||
nostd::string_view version, |
||||
nostd::string_view schema_url, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes) |
||||
{ |
||||
/* Build a container from std::initializer_list. */ |
||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>> attributes_span{ |
||||
attributes.begin(), attributes.end()}; |
||||
|
||||
/* Build a view on the container. */ |
||||
common::KeyValueIterableView< |
||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>> |
||||
iterable_attributes{attributes_span}; |
||||
|
||||
/* Add attributes using the view. */ |
||||
return GetMeter(name, version, schema_url, &iterable_attributes); |
||||
} |
||||
|
||||
/**
|
||||
* Gets or creates a named Meter instance (API helper). |
||||
* |
||||
* @since ABI_VERSION 2 |
||||
* |
||||
* @param[in] name Meter instrumentation scope |
||||
* @param[in] version Instrumentation scope version |
||||
* @param[in] schema_url Instrumentation scope schema URL |
||||
* @param[in] attributes Instrumentation scope attributes container |
||||
*/ |
||||
template <class T, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr> |
||||
nostd::shared_ptr<Meter> GetMeter(nostd::string_view name, |
||||
nostd::string_view version, |
||||
nostd::string_view schema_url, |
||||
const T &attributes) |
||||
{ |
||||
/* Build a view on the container. */ |
||||
common::KeyValueIterableView<T> iterable_attributes(attributes); |
||||
|
||||
/* Add attributes using the view. */ |
||||
return GetMeter(name, version, schema_url, &iterable_attributes); |
||||
} |
||||
|
||||
#else |
||||
/**
|
||||
* Gets or creates a named Meter instance (ABI) |
||||
* |
||||
* @since ABI_VERSION 1 |
||||
* |
||||
* @param[in] name Meter instrumentation scope |
||||
* @param[in] version Instrumentation scope version, optional |
||||
* @param[in] schema_url Instrumentation scope schema URL, optional |
||||
*/ |
||||
virtual nostd::shared_ptr<Meter> GetMeter(nostd::string_view name, |
||||
nostd::string_view version = "", |
||||
nostd::string_view schema_url = "") noexcept = 0; |
||||
#endif |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
/**
|
||||
* Remove a named Meter instance (ABI). |
||||
* |
||||
* This API is experimental, see |
||||
* https://github.com/open-telemetry/opentelemetry-specification/issues/2232
|
||||
* |
||||
* @since ABI_VERSION 2 |
||||
* |
||||
* @param[in] name Meter instrumentation scope |
||||
* @param[in] version Instrumentation scope version, optional |
||||
* @param[in] schema_url Instrumentation scope schema URL, optional |
||||
*/ |
||||
virtual void RemoveMeter(nostd::string_view name, |
||||
nostd::string_view version = "", |
||||
nostd::string_view schema_url = "") noexcept = 0; |
||||
#endif |
||||
}; |
||||
} // namespace metrics
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,271 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/metrics/async_instruments.h" |
||||
#include "opentelemetry/metrics/meter.h" |
||||
#include "opentelemetry/metrics/meter_provider.h" |
||||
#include "opentelemetry/metrics/observer_result.h" |
||||
#include "opentelemetry/metrics/sync_instruments.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace metrics |
||||
{ |
||||
|
||||
template <class T> |
||||
class NoopCounter : public Counter<T> |
||||
{ |
||||
public: |
||||
NoopCounter(nostd::string_view /* name */, |
||||
nostd::string_view /* description */, |
||||
nostd::string_view /* unit */) noexcept |
||||
{} |
||||
void Add(T /* value */) noexcept override {} |
||||
void Add(T /* value */, const context::Context & /* context */) noexcept override {} |
||||
void Add(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} |
||||
void Add(T /* value */, |
||||
const common::KeyValueIterable & /* attributes */, |
||||
const context::Context & /* context */) noexcept override |
||||
{} |
||||
}; |
||||
|
||||
template <class T> |
||||
class NoopHistogram : public Histogram<T> |
||||
{ |
||||
public: |
||||
NoopHistogram(nostd::string_view /* name */, |
||||
nostd::string_view /* description */, |
||||
nostd::string_view /* unit */) noexcept |
||||
{} |
||||
void Record(T /* value */, const context::Context & /* context */) noexcept override {} |
||||
void Record(T /* value */, |
||||
const common::KeyValueIterable & /* attributes */, |
||||
const context::Context & /* context */) noexcept override |
||||
{} |
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
void Record(T /*value*/, |
||||
const opentelemetry::common::KeyValueIterable & /*attributes*/) noexcept override |
||||
{} |
||||
|
||||
void Record(T /*value*/) noexcept override {} |
||||
#endif |
||||
}; |
||||
|
||||
template <class T> |
||||
class NoopUpDownCounter : public UpDownCounter<T> |
||||
{ |
||||
public: |
||||
NoopUpDownCounter(nostd::string_view /* name */, |
||||
nostd::string_view /* description */, |
||||
nostd::string_view /* unit */) noexcept |
||||
{} |
||||
~NoopUpDownCounter() override = default; |
||||
void Add(T /* value */) noexcept override {} |
||||
void Add(T /* value */, const context::Context & /* context */) noexcept override {} |
||||
void Add(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} |
||||
void Add(T /* value */, |
||||
const common::KeyValueIterable & /* attributes */, |
||||
const context::Context & /* context */) noexcept override |
||||
{} |
||||
}; |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
template <class T> |
||||
class NoopGauge : public Gauge<T> |
||||
{ |
||||
public: |
||||
NoopGauge(nostd::string_view /* name */, |
||||
nostd::string_view /* description */, |
||||
nostd::string_view /* unit */) noexcept |
||||
{} |
||||
~NoopGauge() override = default; |
||||
void Record(T /* value */) noexcept override {} |
||||
void Record(T /* value */, const context::Context & /* context */) noexcept override {} |
||||
void Record(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} |
||||
void Record(T /* value */, |
||||
const common::KeyValueIterable & /* attributes */, |
||||
const context::Context & /* context */) noexcept override |
||||
{} |
||||
}; |
||||
#endif |
||||
|
||||
class NoopObservableInstrument : public ObservableInstrument |
||||
{ |
||||
public: |
||||
NoopObservableInstrument(nostd::string_view /* name */, |
||||
nostd::string_view /* description */, |
||||
nostd::string_view /* unit */) noexcept |
||||
{} |
||||
|
||||
void AddCallback(ObservableCallbackPtr, void * /* state */) noexcept override {} |
||||
void RemoveCallback(ObservableCallbackPtr, void * /* state */) noexcept override {} |
||||
}; |
||||
|
||||
/**
|
||||
* No-op implementation of Meter. |
||||
*/ |
||||
class NoopMeter final : public Meter |
||||
{ |
||||
public: |
||||
nostd::unique_ptr<Counter<uint64_t>> CreateUInt64Counter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::unique_ptr<Counter<uint64_t>>{new NoopCounter<uint64_t>(name, description, unit)}; |
||||
} |
||||
|
||||
nostd::unique_ptr<Counter<double>> CreateDoubleCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::unique_ptr<Counter<double>>{new NoopCounter<double>(name, description, unit)}; |
||||
} |
||||
|
||||
nostd::shared_ptr<ObservableInstrument> CreateInt64ObservableCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::shared_ptr<ObservableInstrument>( |
||||
new NoopObservableInstrument(name, description, unit)); |
||||
} |
||||
|
||||
nostd::shared_ptr<ObservableInstrument> CreateDoubleObservableCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::shared_ptr<ObservableInstrument>( |
||||
new NoopObservableInstrument(name, description, unit)); |
||||
} |
||||
|
||||
nostd::unique_ptr<Histogram<uint64_t>> CreateUInt64Histogram( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::unique_ptr<Histogram<uint64_t>>{ |
||||
new NoopHistogram<uint64_t>(name, description, unit)}; |
||||
} |
||||
|
||||
nostd::unique_ptr<Histogram<double>> CreateDoubleHistogram( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::unique_ptr<Histogram<double>>{new NoopHistogram<double>(name, description, unit)}; |
||||
} |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
nostd::unique_ptr<Gauge<int64_t>> CreateInt64Gauge(nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::unique_ptr<Gauge<int64_t>>{new NoopGauge<int64_t>(name, description, unit)}; |
||||
} |
||||
|
||||
nostd::unique_ptr<Gauge<double>> CreateDoubleGauge(nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::unique_ptr<Gauge<double>>{new NoopGauge<double>(name, description, unit)}; |
||||
} |
||||
#endif |
||||
|
||||
nostd::shared_ptr<ObservableInstrument> CreateInt64ObservableGauge( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::shared_ptr<ObservableInstrument>( |
||||
new NoopObservableInstrument(name, description, unit)); |
||||
} |
||||
|
||||
nostd::shared_ptr<ObservableInstrument> CreateDoubleObservableGauge( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::shared_ptr<ObservableInstrument>( |
||||
new NoopObservableInstrument(name, description, unit)); |
||||
} |
||||
|
||||
nostd::unique_ptr<UpDownCounter<int64_t>> CreateInt64UpDownCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::unique_ptr<UpDownCounter<int64_t>>{ |
||||
new NoopUpDownCounter<int64_t>(name, description, unit)}; |
||||
} |
||||
|
||||
nostd::unique_ptr<UpDownCounter<double>> CreateDoubleUpDownCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::unique_ptr<UpDownCounter<double>>{ |
||||
new NoopUpDownCounter<double>(name, description, unit)}; |
||||
} |
||||
|
||||
nostd::shared_ptr<ObservableInstrument> CreateInt64ObservableUpDownCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::shared_ptr<ObservableInstrument>( |
||||
new NoopObservableInstrument(name, description, unit)); |
||||
} |
||||
|
||||
nostd::shared_ptr<ObservableInstrument> CreateDoubleObservableUpDownCounter( |
||||
nostd::string_view name, |
||||
nostd::string_view description = "", |
||||
nostd::string_view unit = "") noexcept override |
||||
{ |
||||
return nostd::shared_ptr<ObservableInstrument>( |
||||
new NoopObservableInstrument(name, description, unit)); |
||||
} |
||||
}; |
||||
|
||||
/**
|
||||
* No-op implementation of a MeterProvider. |
||||
*/ |
||||
class NoopMeterProvider final : public MeterProvider |
||||
{ |
||||
public: |
||||
NoopMeterProvider() : meter_{nostd::shared_ptr<Meter>(new NoopMeter)} {} |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
nostd::shared_ptr<Meter> GetMeter( |
||||
nostd::string_view /* name */, |
||||
nostd::string_view /* version */, |
||||
nostd::string_view /* schema_url */, |
||||
const common::KeyValueIterable * /* attributes */) noexcept override |
||||
{ |
||||
return meter_; |
||||
} |
||||
#else |
||||
nostd::shared_ptr<Meter> GetMeter(nostd::string_view /* name */, |
||||
nostd::string_view /* version */, |
||||
nostd::string_view /* schema_url */) noexcept override |
||||
{ |
||||
return meter_; |
||||
} |
||||
#endif |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
void RemoveMeter(nostd::string_view /* name */, |
||||
nostd::string_view /* version */, |
||||
nostd::string_view /* schema_url */) noexcept override |
||||
{} |
||||
#endif |
||||
|
||||
private: |
||||
nostd::shared_ptr<Meter> meter_; |
||||
}; |
||||
} // namespace metrics
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,54 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/common/attribute_value.h" |
||||
#include "opentelemetry/common/key_value_iterable_view.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/nostd/span.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/type_traits.h" |
||||
#include "opentelemetry/nostd/variant.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace metrics |
||||
{ |
||||
|
||||
/**
|
||||
* ObserverResultT class is necessary for the callback recording asynchronous |
||||
* instrument use. |
||||
*/ |
||||
template <class T> |
||||
class ObserverResultT |
||||
{ |
||||
|
||||
public: |
||||
virtual ~ObserverResultT() = default; |
||||
|
||||
virtual void Observe(T value) noexcept = 0; |
||||
|
||||
virtual void Observe(T value, const common::KeyValueIterable &attributes) noexcept = 0; |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Observe(T value, const U &attributes) noexcept |
||||
{ |
||||
this->Observe(value, common::KeyValueIterableView<U>{attributes}); |
||||
} |
||||
|
||||
void Observe(T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> |
||||
attributes) noexcept |
||||
{ |
||||
this->Observe(value, nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}); |
||||
} |
||||
}; |
||||
|
||||
using ObserverResult = nostd::variant<nostd::shared_ptr<ObserverResultT<int64_t>>, |
||||
nostd::shared_ptr<ObserverResultT<double>>>; |
||||
|
||||
} // namespace metrics
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,60 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <mutex> |
||||
|
||||
#include "opentelemetry/common/spin_lock_mutex.h" |
||||
#include "opentelemetry/metrics/meter_provider.h" |
||||
#include "opentelemetry/metrics/noop.h" |
||||
#include "opentelemetry/nostd/shared_ptr.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace metrics |
||||
{ |
||||
|
||||
/**
|
||||
* Stores the singleton global MeterProvider. |
||||
*/ |
||||
class Provider |
||||
{ |
||||
public: |
||||
/**
|
||||
* Returns the singleton MeterProvider. |
||||
* |
||||
* By default, a no-op MeterProvider is returned. This will never return a |
||||
* nullptr MeterProvider. |
||||
*/ |
||||
static nostd::shared_ptr<MeterProvider> GetMeterProvider() noexcept |
||||
{ |
||||
std::lock_guard<common::SpinLockMutex> guard(GetLock()); |
||||
return nostd::shared_ptr<MeterProvider>(GetProvider()); |
||||
} |
||||
|
||||
/**
|
||||
* Changes the singleton MeterProvider. |
||||
*/ |
||||
static void SetMeterProvider(const nostd::shared_ptr<MeterProvider> &tp) noexcept |
||||
{ |
||||
std::lock_guard<common::SpinLockMutex> guard(GetLock()); |
||||
GetProvider() = tp; |
||||
} |
||||
|
||||
private: |
||||
OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr<MeterProvider> &GetProvider() noexcept |
||||
{ |
||||
static nostd::shared_ptr<MeterProvider> provider(new NoopMeterProvider); |
||||
return provider; |
||||
} |
||||
|
||||
OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept |
||||
{ |
||||
static common::SpinLockMutex lock; |
||||
return lock; |
||||
} |
||||
}; |
||||
|
||||
} // namespace metrics
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,328 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include "opentelemetry/common/attribute_value.h" |
||||
#include "opentelemetry/common/key_value_iterable_view.h" |
||||
#include "opentelemetry/context/context.h" |
||||
#include "opentelemetry/nostd/span.h" |
||||
#include "opentelemetry/nostd/string_view.h" |
||||
#include "opentelemetry/nostd/type_traits.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace metrics |
||||
{ |
||||
|
||||
class SynchronousInstrument |
||||
{ |
||||
public: |
||||
SynchronousInstrument() = default; |
||||
virtual ~SynchronousInstrument() = default; |
||||
}; |
||||
|
||||
/* A Counter instrument that adds values. */ |
||||
template <class T> |
||||
class Counter : public SynchronousInstrument |
||||
{ |
||||
|
||||
public: |
||||
/**
|
||||
* Record a value |
||||
* |
||||
* @param value The increment amount. MUST be non-negative. |
||||
*/ |
||||
virtual void Add(T value) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value |
||||
* |
||||
* @param value The increment amount. MUST be non-negative. |
||||
* @param context The explicit context to associate with this measurement. |
||||
*/ |
||||
virtual void Add(T value, const context::Context &context) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value with a set of attributes. |
||||
* |
||||
* @param value The increment amount. MUST be non-negative. |
||||
* @param attributes A set of attributes to associate with the value. |
||||
*/ |
||||
|
||||
virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value with a set of attributes. |
||||
* |
||||
* @param value The increment amount. MUST be non-negative. |
||||
* @param attributes A set of attributes to associate with the value. |
||||
* @param context The explicit context to associate with this measurement. |
||||
*/ |
||||
virtual void Add(T value, |
||||
const common::KeyValueIterable &attributes, |
||||
const context::Context &context) noexcept = 0; |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Add(T value, const U &attributes) noexcept |
||||
{ |
||||
this->Add(value, common::KeyValueIterableView<U>{attributes}); |
||||
} |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Add(T value, const U &attributes, const context::Context &context) noexcept |
||||
{ |
||||
this->Add(value, common::KeyValueIterableView<U>{attributes}, context); |
||||
} |
||||
|
||||
void Add(T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> |
||||
attributes) noexcept |
||||
{ |
||||
this->Add(value, nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}); |
||||
} |
||||
|
||||
void Add(T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes, |
||||
const context::Context &context) noexcept |
||||
{ |
||||
this->Add(value, |
||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}, |
||||
context); |
||||
} |
||||
}; |
||||
|
||||
/** A histogram instrument that records values. */ |
||||
|
||||
template <class T> |
||||
class Histogram : public SynchronousInstrument |
||||
{ |
||||
public: |
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
/**
|
||||
* @since ABI_VERSION 2 |
||||
* Records a value. |
||||
* |
||||
* @param value The measurement value. MUST be non-negative. |
||||
*/ |
||||
virtual void Record(T value) noexcept = 0; |
||||
|
||||
/**
|
||||
* @since ABI_VERSION 2 |
||||
* Records a value with a set of attributes. |
||||
* |
||||
* @param value The measurement value. MUST be non-negative. |
||||
* @param attribute A set of attributes to associate with the value. |
||||
*/ |
||||
virtual void Record(T value, const common::KeyValueIterable &attribute) noexcept = 0; |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Record(T value, const U &attributes) noexcept |
||||
{ |
||||
this->Record(value, common::KeyValueIterableView<U>{attributes}); |
||||
} |
||||
|
||||
void Record(T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> |
||||
attributes) noexcept |
||||
{ |
||||
this->Record(value, nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}); |
||||
} |
||||
#endif |
||||
|
||||
/**
|
||||
* Records a value. |
||||
* |
||||
* @param value The measurement value. MUST be non-negative. |
||||
* @param context The explicit context to associate with this measurement. |
||||
*/ |
||||
virtual void Record(T value, const context::Context &context) noexcept = 0; |
||||
|
||||
/**
|
||||
* Records a value with a set of attributes. |
||||
* |
||||
* @param value The measurement value. MUST be non-negative. |
||||
* @param attributes A set of attributes to associate with the value.. |
||||
* @param context The explicit context to associate with this measurement. |
||||
*/ |
||||
virtual void Record(T value, |
||||
const common::KeyValueIterable &attributes, |
||||
const context::Context &context) noexcept = 0; |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Record(T value, const U &attributes, const context::Context &context) noexcept |
||||
{ |
||||
this->Record(value, common::KeyValueIterableView<U>{attributes}, context); |
||||
} |
||||
|
||||
void Record( |
||||
T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes, |
||||
const context::Context &context) noexcept |
||||
{ |
||||
this->Record(value, |
||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}, |
||||
context); |
||||
} |
||||
}; |
||||
|
||||
/** An up-down-counter instrument that adds or reduce values. */ |
||||
|
||||
template <class T> |
||||
class UpDownCounter : public SynchronousInstrument |
||||
{ |
||||
public: |
||||
/**
|
||||
* Record a value. |
||||
* |
||||
* @param value The increment amount. May be positive, negative or zero. |
||||
*/ |
||||
virtual void Add(T value) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value. |
||||
* |
||||
* @param value The increment amount. May be positive, negative or zero. |
||||
* @param context The explicit context to associate with this measurement. |
||||
*/ |
||||
virtual void Add(T value, const context::Context &context) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value with a set of attributes. |
||||
* |
||||
* @param value The increment amount. May be positive, negative or zero. |
||||
* @param attributes A set of attributes to associate with the count. |
||||
*/ |
||||
virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value with a set of attributes. |
||||
* |
||||
* @param value The increment amount. May be positive, negative or zero. |
||||
* @param attributes A set of attributes to associate with the count. |
||||
* @param context The explicit context to associate with this measurement. |
||||
*/ |
||||
virtual void Add(T value, |
||||
const common::KeyValueIterable &attributes, |
||||
const context::Context &context) noexcept = 0; |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Add(T value, const U &attributes) noexcept |
||||
{ |
||||
this->Add(value, common::KeyValueIterableView<U>{attributes}); |
||||
} |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Add(T value, const U &attributes, const context::Context &context) noexcept |
||||
{ |
||||
this->Add(value, common::KeyValueIterableView<U>{attributes}, context); |
||||
} |
||||
|
||||
void Add(T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> |
||||
attributes) noexcept |
||||
{ |
||||
this->Add(value, nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}); |
||||
} |
||||
|
||||
void Add(T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes, |
||||
const context::Context &context) noexcept |
||||
{ |
||||
this->Add(value, |
||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}, |
||||
context); |
||||
} |
||||
}; |
||||
|
||||
#if OPENTELEMETRY_ABI_VERSION_NO >= 2 |
||||
/* A Gauge instrument that records values. */ |
||||
template <class T> |
||||
class Gauge : public SynchronousInstrument |
||||
{ |
||||
|
||||
public: |
||||
/**
|
||||
* Record a value |
||||
* |
||||
* @param value The measurement value. May be positive, negative or zero. |
||||
*/ |
||||
virtual void Record(T value) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value |
||||
* |
||||
* @param value The measurement value. May be positive, negative or zero. |
||||
* @param context The explicit context to associate with this measurement. |
||||
*/ |
||||
virtual void Record(T value, const context::Context &context) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value with a set of attributes. |
||||
* |
||||
* @param value The measurement value. May be positive, negative or zero. |
||||
* @param attributes A set of attributes to associate with the value. |
||||
*/ |
||||
|
||||
virtual void Record(T value, const common::KeyValueIterable &attributes) noexcept = 0; |
||||
|
||||
/**
|
||||
* Record a value with a set of attributes. |
||||
* |
||||
* @param value The measurement value. May be positive, negative or zero. |
||||
* @param attributes A set of attributes to associate with the value. |
||||
* @param context The explicit context to associate with this measurement. |
||||
*/ |
||||
virtual void Record(T value, |
||||
const common::KeyValueIterable &attributes, |
||||
const context::Context &context) noexcept = 0; |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Record(T value, const U &attributes) noexcept |
||||
{ |
||||
this->Record(value, common::KeyValueIterableView<U>{attributes}); |
||||
} |
||||
|
||||
template <class U, |
||||
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr> |
||||
void Record(T value, const U &attributes, const context::Context &context) noexcept |
||||
{ |
||||
this->Record(value, common::KeyValueIterableView<U>{attributes}, context); |
||||
} |
||||
|
||||
void Record(T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> |
||||
attributes) noexcept |
||||
{ |
||||
this->Record(value, nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}); |
||||
} |
||||
|
||||
void Record( |
||||
T value, |
||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes, |
||||
const context::Context &context) noexcept |
||||
{ |
||||
this->Record(value, |
||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{ |
||||
attributes.begin(), attributes.end()}, |
||||
context); |
||||
} |
||||
}; |
||||
#endif |
||||
|
||||
} // namespace metrics
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,21 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <type_traits> |
||||
|
||||
#include "opentelemetry/nostd/utility.h" |
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace nostd |
||||
{ |
||||
namespace detail |
||||
{ |
||||
template <bool... Bs> |
||||
using all = std::is_same<integer_sequence<bool, true, Bs...>, integer_sequence<bool, Bs..., true>>; |
||||
|
||||
} // namespace detail
|
||||
} // namespace nostd
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
@ -0,0 +1,16 @@
|
||||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once |
||||
|
||||
#include <type_traits> |
||||
|
||||
#include "opentelemetry/version.h" |
||||
|
||||
OPENTELEMETRY_BEGIN_NAMESPACE |
||||
namespace nostd |
||||
{ |
||||
template <class T> |
||||
using decay_t = typename std::decay<T>::type; |
||||
} // namespace nostd
|
||||
OPENTELEMETRY_END_NAMESPACE |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue