Skip to content

Commit 91e1347

Browse files
committed
merged from upstream
2 parents 89e6af7 + 465cb4a commit 91e1347

File tree

11 files changed

+360
-37
lines changed

11 files changed

+360
-37
lines changed

.devcontainer/Dockerfile.dev

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright The OpenTelemetry Authors
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
FROM otel/cpp_format_tools
5+
6+
ARG GRPC_VERSION=v1.55.0
7+
ARG PROTOBUF_VERSION=23.4
8+
ARG ABSEIL_CPP_VERSION=20240116.1
9+
10+
ENV PROTOBUF_VERSION=${PROTOBUF_VERSION}
11+
ENV ABSEIL_CPP_VERSION=${ABSEIL_CPP_VERSION}
12+
13+
COPY ci /opt/ci
14+
15+
RUN apt update && apt install -y wget \
16+
ninja-build \
17+
libcurl4-openssl-dev \
18+
markdownlint
19+
20+
RUN cd /opt/ci && bash setup_cmake.sh
21+
RUN cd /opt/ci && bash setup_ci_environment.sh
22+
RUN cd /opt && bash ci/setup_googletest.sh \
23+
&& bash ci/setup_grpc.sh -r ${GRPC_VERSION}
24+
25+
ADD https://github.com/bazelbuild/bazelisk/releases/download/v1.22.1/bazelisk-linux-amd64 /usr/local/bin
26+
27+
RUN git config --global core.autocrlf input \
28+
&& chmod +x /usr/local/bin/bazelisk-linux-amd64

.devcontainer/devcontainer.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
4+
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/javascript-node
5+
{
6+
"name": "opentelemetry-cpp",
7+
"build": {
8+
"context": "..",
9+
"dockerfile": "Dockerfile.dev",
10+
"args": {
11+
"GRPC_VERSION": "v1.55.0",
12+
"PROTOBUF_VERSION": "23.4",
13+
"ABSEIL_CPP_VERSION":"20240116.1"
14+
}
15+
},
16+
"settings": {
17+
"terminal.integrated.shell.linux": "/bin/sh"
18+
},
19+
"extensions": [
20+
"ms-vscode.cpptools",
21+
"ms-azuretools.vscode-docker",
22+
"ms-vscode.cpptools-extension-pack"
23+
],
24+
25+
"remoteUser": "root"
26+
}

.github/dependabot.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ updates:
66
interval: "daily"
77
labels:
88
- "GHA"
9+
10+
- package-ecosystem: "devcontainers"
11+
directory: "/"
12+
schedule:
13+
interval: daily

CONTRIBUTING.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,91 @@ bazel build //examples/simple:example_simple
6060
bazel-bin/examples/simple/example_simple
6161
```
6262

63+
### DevContainer Setup for Project
64+
65+
This guide provides instructions on how to set up and use the development
66+
container (`devcontainer`) environment to streamline testing and development
67+
for this project. With the DevContainer, you can work in a consistent environment
68+
configured with all the necessary dependencies and tools.
69+
70+
#### Prerequisites
71+
72+
Before getting started, ensure you have the following installed:
73+
74+
* **Docker**: DevContainers require Docker for containerization.
75+
* **Visual Studio Code (VSCode)** with the **Remote - Containers** extension.
76+
77+
#### Getting Started
78+
79+
* **Open the Project in DevContainer**:
80+
81+
Open the project in VSCode. When prompted to "Reopen in Container," select
82+
this option. If you’re not prompted, you can manually open the container by
83+
selecting **Remote-Containers: Reopen in Container** from the command palette
84+
(`F1` or `Ctrl+Shift+P`).
85+
86+
* **Container Setup**:
87+
88+
The DevContainer environment will automatically build based on the configuration
89+
files provided (e.g., `.devcontainer/devcontainer.json`). This setup will install
90+
required dependencies, tools, and environment variables needed for the project.
91+
92+
#### Available Commands
93+
94+
Once inside the DevContainer, you can use the following commands to run tests
95+
and CI workflows.
96+
97+
##### 1. Run Tests with Bazelisk
98+
99+
To run tests with Bazelisk using specific compilation options, use:
100+
101+
```bash
102+
bazelisk-linux-amd64 test --copt=-DENABLE_LOGS_PREVIEW
103+
--test_output=errors --cache_test_results=no --copt=-DENABLE_TEST //exporters/otlp/...
104+
```
105+
106+
###### Command Breakdown
107+
108+
* `--copt=-DENABLE_LOGS_PREVIEW`: Enables preview logs.
109+
* `--test_output=errors`: Shows only the errors in the test output.
110+
* `--cache_test_results=no`: Forces Bazel to re-run tests without caching.
111+
* `--copt=-DENABLE_TEST`: Enables testing capabilities for the target code.
112+
* `//exporters/otlp/...`: Specifies the test target path.
113+
114+
##### 2. Run CI Script
115+
116+
You can also run the CI script provided to perform testing with the
117+
following command as an
118+
example:
119+
120+
```bash
121+
bash ci/do_ci.sh cmake.exporter.otprotocol.test
122+
```
123+
124+
This command initiates the CI pipeline, executing tests specifically for the
125+
**cmake.exporter.otprotocol** module.
126+
127+
#### Troubleshooting
128+
129+
If you encounter issues:
130+
131+
* **Rebuild the DevContainer**: From the command palette, run
132+
**Remote-Containers: Rebuild Container** to reinitialize the environment.
133+
* **Check Bazelisk and CI Script Logs**: Inspect logs for any configuration or
134+
dependency issues.
135+
136+
#### Additional Notes
137+
138+
* You can adjust compiler options (`--copt`) as needed to test additional flags
139+
or enable/disable specific features.
140+
* The test results will be displayed in the terminal within the DevContainer for
141+
easy debugging.
142+
143+
#### Resources
144+
145+
* **Bazelisk Documentation**: [https://github.com/bazelbuild/bazelisk](https://github.com/bazelbuild/bazelisk)
146+
* **VSCode DevContainer Documentation**: [https://code.visualstudio.com/docs/remote/containers](https://code.visualstudio.com/docs/remote/containers)
147+
63148
## Pull Requests
64149

65150
### How to Send Pull Requests

ci/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Building and running tests as a developer
22

33
CI tests can be run on docker by invoking the script `./ci/run_docker.sh
4-
./ci/do_ci.sh {TARGET}` where the targets are:
4+
./ci/do_ci.sh {TARGET}`or inside
5+
[devcontainer](../CONTRIBUTING.md#devcontainer-setup-for-project)
6+
by invoking the script
7+
`./ci/do_ci.sh {TARGET}` where the targets are:
58

69
* `cmake.test`: build cmake targets and run tests.
710
* `cmake.maintainer.test`: build with cmake and test, in maintainer mode.

ci/run_docker.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ set -e
77

88
BUILD_IMAGE=opentelemetry-cpp-build
99
docker image inspect "$BUILD_IMAGE" &> /dev/null || {
10-
docker build -t "$BUILD_IMAGE" ci
10+
docker build -t "$BUILD_IMAGE" -f .devcontainer/Dockerfile.dev .
1111
}
1212

1313
if [[ $# -ge 1 ]]; then

sdk/include/opentelemetry/sdk/common/global_log_handler.h

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -99,37 +99,28 @@ class OPENTELEMETRY_EXPORT_TYPE GlobalLogHandler
9999
*
100100
* By default, a default LogHandler is returned.
101101
*/
102-
static inline const nostd::shared_ptr<LogHandler> &GetLogHandler() noexcept
103-
{
104-
return GetHandlerAndLevel().first;
105-
}
102+
static nostd::shared_ptr<LogHandler> GetLogHandler() noexcept;
106103

107104
/**
108105
* Changes the singleton LogHandler.
109106
* This should be called once at the start of application before creating any Provider
110107
* instance.
111108
*/
112-
static inline void SetLogHandler(const nostd::shared_ptr<LogHandler> &eh) noexcept
113-
{
114-
GetHandlerAndLevel().first = eh;
115-
}
109+
static void SetLogHandler(const nostd::shared_ptr<LogHandler> &eh) noexcept;
116110

117111
/**
118112
* Returns the singleton log level.
119113
*
120114
* By default, a default log level is returned.
121115
*/
122-
static inline LogLevel GetLogLevel() noexcept { return GetHandlerAndLevel().second; }
116+
static LogLevel GetLogLevel() noexcept;
123117

124118
/**
125119
* Changes the singleton Log level.
126120
* This should be called once at the start of application before creating any Provider
127121
* instance.
128122
*/
129-
static inline void SetLogLevel(LogLevel level) noexcept { GetHandlerAndLevel().second = level; }
130-
131-
private:
132-
static std::pair<nostd::shared_ptr<LogHandler>, LogLevel> &GetHandlerAndLevel() noexcept;
123+
static void SetLogLevel(LogLevel level) noexcept;
133124
};
134125

135126
} // namespace internal_log
@@ -142,24 +133,23 @@ OPENTELEMETRY_END_NAMESPACE
142133
* To ensure that GlobalLogHandler is the first one to be initialized (and so last to be
143134
* destroyed), it is first used inside the constructors of TraceProvider, MeterProvider
144135
* and LoggerProvider for debug logging. */
145-
#define OTEL_INTERNAL_LOG_DISPATCH(level, message, attributes) \
146-
do \
147-
{ \
148-
using opentelemetry::sdk::common::internal_log::GlobalLogHandler; \
149-
using opentelemetry::sdk::common::internal_log::LogHandler; \
150-
if (level > GlobalLogHandler::GetLogLevel()) \
151-
{ \
152-
break; \
153-
} \
154-
const opentelemetry::nostd::shared_ptr<LogHandler> &log_handler = \
155-
GlobalLogHandler::GetLogHandler(); \
156-
if (!log_handler) \
157-
{ \
158-
break; \
159-
} \
160-
std::stringstream tmp_stream; \
161-
tmp_stream << message; \
162-
log_handler->Handle(level, __FILE__, __LINE__, tmp_stream.str().c_str(), attributes); \
136+
#define OTEL_INTERNAL_LOG_DISPATCH(level, message, attributes) \
137+
do \
138+
{ \
139+
using opentelemetry::sdk::common::internal_log::GlobalLogHandler; \
140+
using opentelemetry::sdk::common::internal_log::LogHandler; \
141+
if (level > GlobalLogHandler::GetLogLevel()) \
142+
{ \
143+
break; \
144+
} \
145+
opentelemetry::nostd::shared_ptr<LogHandler> log_handler = GlobalLogHandler::GetLogHandler(); \
146+
if (!log_handler) \
147+
{ \
148+
break; \
149+
} \
150+
std::stringstream tmp_stream; \
151+
tmp_stream << message; \
152+
log_handler->Handle(level, __FILE__, __LINE__, tmp_stream.str().c_str(), attributes); \
163153
} while (false);
164154

165155
#define OTEL_INTERNAL_LOG_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3

sdk/src/common/global_log_handler.cc

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,38 @@ namespace common
1313
namespace internal_log
1414
{
1515

16+
namespace
17+
{
18+
struct GlobalLogHandlerData
19+
{
20+
nostd::shared_ptr<LogHandler> handler;
21+
LogLevel log_level;
22+
23+
GlobalLogHandlerData()
24+
: handler(nostd::shared_ptr<LogHandler>(new DefaultLogHandler)), log_level(LogLevel::Warning)
25+
{}
26+
~GlobalLogHandlerData() { is_singleton_destroyed = true; }
27+
28+
GlobalLogHandlerData(const GlobalLogHandlerData &) = delete;
29+
GlobalLogHandlerData(GlobalLogHandlerData &&) = delete;
30+
31+
GlobalLogHandlerData &operator=(const GlobalLogHandlerData &) = delete;
32+
GlobalLogHandlerData &operator=(GlobalLogHandlerData &&) = delete;
33+
34+
static GlobalLogHandlerData &Instance() noexcept;
35+
static bool is_singleton_destroyed;
36+
};
37+
38+
bool GlobalLogHandlerData::is_singleton_destroyed = false;
39+
40+
GlobalLogHandlerData &GlobalLogHandlerData::Instance() noexcept
41+
{
42+
static GlobalLogHandlerData instance;
43+
return instance;
44+
}
45+
46+
} // namespace
47+
1648
LogHandler::~LogHandler() {}
1749

1850
void DefaultLogHandler::Handle(LogLevel level,
@@ -57,11 +89,43 @@ void NoopLogHandler::Handle(LogLevel,
5789
const sdk::common::AttributeMap &) noexcept
5890
{}
5991

60-
std::pair<nostd::shared_ptr<LogHandler>, LogLevel> &GlobalLogHandler::GetHandlerAndLevel() noexcept
92+
nostd::shared_ptr<LogHandler> GlobalLogHandler::GetLogHandler() noexcept
93+
{
94+
if OPENTELEMETRY_UNLIKELY_CONDITION (GlobalLogHandlerData::is_singleton_destroyed)
95+
{
96+
return nostd::shared_ptr<LogHandler>();
97+
}
98+
99+
return GlobalLogHandlerData::Instance().handler;
100+
}
101+
102+
void GlobalLogHandler::SetLogHandler(const nostd::shared_ptr<LogHandler> &eh) noexcept
103+
{
104+
if OPENTELEMETRY_UNLIKELY_CONDITION (GlobalLogHandlerData::is_singleton_destroyed)
105+
{
106+
return;
107+
}
108+
109+
GlobalLogHandlerData::Instance().handler = eh;
110+
}
111+
112+
LogLevel GlobalLogHandler::GetLogLevel() noexcept
61113
{
62-
static std::pair<nostd::shared_ptr<LogHandler>, LogLevel> handler_and_level{
63-
nostd::shared_ptr<LogHandler>(new DefaultLogHandler), LogLevel::Warning};
64-
return handler_and_level;
114+
if OPENTELEMETRY_UNLIKELY_CONDITION (GlobalLogHandlerData::is_singleton_destroyed)
115+
{
116+
return LogLevel::None;
117+
}
118+
119+
return GlobalLogHandlerData::Instance().log_level;
120+
}
121+
122+
void GlobalLogHandler::SetLogLevel(LogLevel level) noexcept
123+
{
124+
if OPENTELEMETRY_UNLIKELY_CONDITION (GlobalLogHandlerData::is_singleton_destroyed)
125+
{
126+
return;
127+
}
128+
GlobalLogHandlerData::Instance().log_level = level;
65129
}
66130

67131
} // namespace internal_log

sdk/test/common/BUILD

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,20 @@ otel_cc_test(
163163
]),
164164
)
165165

166+
otel_cc_test(
167+
name = "global_log_handle_singleton_lifetime_test",
168+
srcs = [
169+
"global_log_handle_singleton_lifetime_test.cc",
170+
],
171+
tags = ["test"],
172+
deps = dll_deps([
173+
"//api",
174+
"//sdk:headers",
175+
"//sdk/src/common:global_log_handler",
176+
"@com_google_googletest//:gtest_main",
177+
]),
178+
)
179+
166180
otel_cc_test(
167181
name = "attributemap_hash_test",
168182
srcs = [

sdk/test/common/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ foreach(
1111
attribute_utils_test
1212
attributemap_hash_test
1313
global_log_handle_test
14+
global_log_handle_singleton_lifetime_test
1415
env_var_test)
1516

1617
add_executable(${testname} "${testname}.cc")

0 commit comments

Comments
 (0)