Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3deb332
[EXPORTER] Add a JsonWriter interface for OTLP/JSON serialization
ltowarek Sep 7, 2026
7937ce2
Fix Bazel build
ltowarek Sep 10, 2026
dd3964b
Fix CI
ltowarek Sep 11, 2026
30f1738
Pass a string_view to Base64Escape in the nlohmann JSON writer
ltowarek Sep 13, 2026
7eec588
Reuse the pending key buffer in the nlohmann JSON writer
ltowarek Sep 13, 2026
1a9780e
Fail the OTLP/JSON export when ToString() fails or the factory return…
ltowarek Sep 13, 2026
fc0f530
Resolve the default JSON writer only for JSON content in the OTLP HTT…
ltowarek Sep 13, 2026
803fcce
Complete the pkg-config dependency chain of the OTLP JSON libraries
ltowarek Sep 13, 2026
6a869fc
Document the JsonWriter and JsonWriterFactory contracts
ltowarek Sep 13, 2026
5c4e118
Test the JsonWriter contract with a suite shared by writer backends
ltowarek Sep 13, 2026
f35605b
Add a benchmark for OTLP/JSON serialization without I/O
ltowarek Sep 13, 2026
b9530db
Avoid key copies and initializer_list construction in the nlohmann JS…
ltowarek Sep 13, 2026
94b2f64
Format hex IDs and 64-bit integers into stack buffers in the JSON con…
ltowarek Sep 13, 2026
ff92b5b
Fetch reflection once per message in the JSON converter
ltowarek Sep 13, 2026
5fdd156
Merge main into json-writer-seam
ltowarek Sep 13, 2026
07b30c8
Make the concurrency contract test constants static for MSVC
ltowarek Sep 13, 2026
a07346a
Fix clang-tidy and include-what-you-use findings in the OTLP JSON tests
ltowarek Sep 13, 2026
8ea7620
Merge main into json-writer-seam
ltowarek Sep 13, 2026
e9deb3e
Merge main into json-writer-seam
ltowarek Sep 20, 2026
660bdeb
Build the default file exporter factory tests only with a JSON writer…
ltowarek Sep 20, 2026
505ffc4
Merge main into json-writer-seam
ltowarek Sep 21, 2026
5e5c295
Guard the default file exporter factory Bazel tests without a JSON wr…
ltowarek Sep 21, 2026
08f3cdf
Add missing string includes reported by include-what-you-use
ltowarek Sep 21, 2026
6a6e4a6
Merge main into json-writer-seam
ltowarek Oct 6, 2026
85f9c45
Merge main into json-writer-seam
ltowarek Oct 7, 2026
24b0b1b
Merge main into json-writer-seam
ltowarek Oct 11, 2026
c149144
Merge main into json-writer-seam
ltowarek Oct 14, 2026
9d55e1e
Merge main into json-writer-seam
ltowarek Oct 21, 2026
8cd1f22
Link the CHANGELOG entry to the pull request
ltowarek Oct 21, 2026
674fdfa
Merge main into json-writer-seam
ltowarek Oct 22, 2026
ca544c2
Merge main into json-writer-seam
ltowarek Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Increment the:

## [Unreleased]

* [EXPORTER] Add a `JsonWriter` interface for OTLP/JSON serialization, so a
consumer can supply their own JSON backend in place of the default
nlohmann-json one.
[#4556](https://github.com/open-telemetry/opentelemetry-cpp/pull/4556)

## [1.30.0] 2026-10-22

This release contains:
Expand Down
18 changes: 16 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,17 @@ otelcpp_dependent_option(
"OTELCPP_WITH_OTLP_HTTP OR OTELCPP_WITH_ELASTICSEARCH OR OTELCPP_WITH_ZIPKIN OR OTELCPP_BUILD_W3CTRACECONTEXT_TEST OR OTELCPP_WITH_EXAMPLES_HTTP"
OFF)

#
# Do we need the NLOHMANN JSON WRITER ?
#

otelcpp_dependent_option(
OTELCPP_WITH_JSON_WRITER_NLOHMANN
"Use the nlohmann-json JsonWriter backend. Defaults to ON when an OTLP exporter that emits JSON is enabled; set OFF to supply a custom JsonWriterFactory."
ON
"OTELCPP_WITH_OTLP_HTTP OR OTELCPP_WITH_OTLP_FILE"
OFF)

#
# Locally override options if OTELCPP_WITH_API_ONLY is set to prevent third
# party dependencies from being imported
Expand All @@ -369,6 +380,7 @@ if(OTELCPP_WITH_API_ONLY)
otelcpp_set_option(OTELCPP_WITH_ETW OFF)
otelcpp_set_option(OTELCPP_WITH_CONFIGURATION OFF)
otelcpp_set_option(OTELCPP_WITH_HTTP_CLIENT_CURL OFF)
otelcpp_set_option(OTELCPP_WITH_JSON_WRITER_NLOHMANN OFF)
otelcpp_set_option(OTELCPP_WITH_OTLP_HTTP_COMPRESSION OFF)
otelcpp_set_option(OTELCPP_WITH_BENCHMARK OFF)
otelcpp_set_option(OTELCPP_WITH_FUNC_TESTS OFF)
Expand Down Expand Up @@ -425,8 +437,7 @@ endif()

if(OTELCPP_WITH_ELASTICSEARCH
OR OTELCPP_WITH_ZIPKIN
OR OTELCPP_WITH_OTLP_HTTP
OR OTELCPP_WITH_OTLP_FILE
OR OTELCPP_WITH_JSON_WRITER_NLOHMANN
OR OTELCPP_BUILD_W3CTRACECONTEXT_TEST
OR OTELCPP_WITH_ETW)
set(USE_NLOHMANN_JSON ON)
Expand Down Expand Up @@ -603,6 +614,9 @@ message(STATUS "OTELCPP_WITH_OTLP_HTTP: ${OTELCPP_WITH_OTLP_HTTP}")
message(STATUS "OTELCPP_WITH_OTLP_FILE: ${OTELCPP_WITH_OTLP_FILE}")
message(
STATUS "OTELCPP_WITH_HTTP_CLIENT_CURL: ${OTELCPP_WITH_HTTP_CLIENT_CURL}")
message(
STATUS
"OTELCPP_WITH_JSON_WRITER_NLOHMANN: ${OTELCPP_WITH_JSON_WRITER_NLOHMANN}")
message(STATUS "OTELCPP_WITH_ZIPKIN: ${OTELCPP_WITH_ZIPKIN}")
message(STATUS "OTELCPP_WITH_PROMETHEUS: ${OTELCPP_WITH_PROMETHEUS}")
message(STATUS "OTELCPP_WITH_ELASTICSEARCH: ${OTELCPP_WITH_ELASTICSEARCH}")
Expand Down
3 changes: 3 additions & 0 deletions ci/verify_packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ done
# OTLP exporters
validate_package "opentelemetry_otlp_recordable"
validate_package "opentelemetry_exporter_otlp_builder_utils"
for variant in json_writer json_writer_nlohmann json_converter; do
validate_package "opentelemetry_exporter_otlp_${variant}"
done

# OTLP gRPC exporter
validate_package "opentelemetry_exporter_otlp_grpc"
Expand Down
221 changes: 212 additions & 9 deletions exporters/otlp/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,71 @@ cc_library(
],
)

cc_library(
name = "otlp_json_writer",
srcs = select({
":json_writer_nlohmann_enabled": ["src/otlp_json_writer_nlohmann.cc"],
"//conditions:default": [],
}),
hdrs = [
"include/opentelemetry/exporters/otlp/detail/default_json_writer_factory.h",
"include/opentelemetry/exporters/otlp/otlp_json_writer.h",
"include/opentelemetry/exporters/otlp/otlp_json_writer_factory.h",
] + select({
":json_writer_nlohmann_enabled": [
"include/opentelemetry/exporters/otlp/otlp_json_writer_factory_nlohmann.h",
],
"//conditions:default": [],
}),
defines = select({
":json_writer_nlohmann_enabled": ["ENABLE_JSON_WRITER_NLOHMANN"],
"//conditions:default": [],
}),
strip_include_prefix = "include",
tags = ["otlp"],
deps = [
"//api",
"//sdk/src/common:base64",
"//sdk/src/common:global_log_handler",
] + select({
":json_writer_nlohmann_enabled": ["@github_nlohmann_json//:json"],
"//conditions:default": [],
}),
)

config_setting(
name = "json_writer_nlohmann_enabled",
flag_values = {
":with_json_writer_nlohmann": "true",
},
)

bool_flag(
name = "with_json_writer_nlohmann",
build_setting_default = True,
)

cc_library(
name = "otlp_json_converter",
srcs = [
"src/otlp_json_converter.cc",
],
hdrs = [
"include/opentelemetry/exporters/otlp/otlp_http.h",
"include/opentelemetry/exporters/otlp/otlp_json_converter.h",
"include/opentelemetry/exporters/otlp/protobuf_include_prefix.h",
"include/opentelemetry/exporters/otlp/protobuf_include_suffix.h",
],
strip_include_prefix = "include",
tags = ["otlp"],
deps = [
":otlp_json_writer",
"//api",
"//sdk/src/common:base64",
"@com_google_protobuf//:protobuf",
],
)

cc_library(
name = "otlp_builder_utils",
srcs = [
Expand Down Expand Up @@ -224,14 +289,15 @@ cc_library(
"otlp_http_log",
],
deps = [
":otlp_json_converter",
":otlp_json_writer",
"//api",
"//ext/src/http/client/curl:http_client_curl",
"//sdk:headers",
"//sdk/src/common:base64",
"@com_github_opentelemetry_proto//:common_proto_cc",
"@com_google_absl//absl/strings",
"@com_google_protobuf//:protobuf",
"@github_nlohmann_json//:json",
],
)

Expand Down Expand Up @@ -305,12 +371,13 @@ cc_library(
"otlp_file",
],
deps = [
":otlp_json_converter",
":otlp_json_writer",
"//api",
"//sdk:headers",
"//sdk/src/common:base64",
"@com_github_opentelemetry_proto//:common_proto_cc",
"@com_google_absl//absl/strings",
"@github_nlohmann_json//:json",
],
)

Expand Down Expand Up @@ -673,6 +740,44 @@ cc_library(
],
)

cc_test(
name = "otlp_json_converter_test",
srcs = [
"test/otlp_json_converter_test.cc",
"test/otlp_stub_json_writer.h",
],
tags = [
"otlp",
"test",
],
deps = [
":otlp_json_converter",
"@com_github_opentelemetry_proto//:common_proto_cc",
"@com_github_opentelemetry_proto//:metrics_service_proto_cc",
"@com_github_opentelemetry_proto//:trace_service_proto_cc",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "otlp_json_writer_nlohmann_test",
srcs = [
"test/otlp_json_writer_contract_test.cc",
"test/otlp_json_writer_contract_test.h",
"test/otlp_json_writer_nlohmann_test.cc",
],
tags = [
"otlp",
"test",
],
deps = [
":otlp_json_writer",
"//sdk/src/common:global_log_handler",
"//test_common:headers",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "otlp_recordable_test",
srcs = ["test/otlp_recordable_test.cc"],
Expand Down Expand Up @@ -724,7 +829,10 @@ cc_test(

cc_test(
name = "otlp_file_client_test",
srcs = ["test/otlp_file_client_test.cc"],
srcs = [
"test/otlp_file_client_test.cc",
"test/otlp_stub_json_writer.h",
],
tags = [
"otlp",
"otlp_file",
Expand Down Expand Up @@ -789,7 +897,10 @@ cc_test(

cc_test(
name = "otlp_http_exporter_test",
srcs = ["test/otlp_http_exporter_test.cc"],
srcs = [
"test/otlp_http_exporter_test.cc",
"test/otlp_http_request_body_capture.h",
],
tags = [
"otlp",
"otlp_http",
Expand Down Expand Up @@ -839,7 +950,10 @@ cc_test(

cc_test(
name = "otlp_file_exporter_factory_test",
srcs = ["test/otlp_file_exporter_factory_test.cc"],
srcs = [
"test/otlp_file_exporter_factory_test.cc",
"test/otlp_stub_json_writer.h",
],
tags = [
"otlp",
"otlp_file",
Expand All @@ -855,7 +969,10 @@ cc_test(

cc_test(
name = "otlp_http_log_record_exporter_test",
srcs = ["test/otlp_http_log_record_exporter_test.cc"],
srcs = [
"test/otlp_http_log_record_exporter_test.cc",
"test/otlp_http_request_body_capture.h",
],
tags = [
"otlp",
"otlp_http_log",
Expand Down Expand Up @@ -905,7 +1022,10 @@ cc_test(

cc_test(
name = "otlp_file_log_record_exporter_factory_test",
srcs = ["test/otlp_file_log_record_exporter_factory_test.cc"],
srcs = [
"test/otlp_file_log_record_exporter_factory_test.cc",
"test/otlp_stub_json_writer.h",
],
tags = [
"otlp",
"otlp_file_log",
Expand Down Expand Up @@ -989,7 +1109,10 @@ cc_test(

cc_test(
name = "otlp_http_metric_exporter_test",
srcs = ["test/otlp_http_metric_exporter_test.cc"],
srcs = [
"test/otlp_http_metric_exporter_test.cc",
"test/otlp_http_request_body_capture.h",
],
tags = [
"otlp",
"otlp_http_metric",
Expand Down Expand Up @@ -1036,7 +1159,10 @@ cc_test(

cc_test(
name = "otlp_file_metric_exporter_factory_test",
srcs = ["test/otlp_file_metric_exporter_factory_test.cc"],
srcs = [
"test/otlp_file_metric_exporter_factory_test.cc",
"test/otlp_stub_json_writer.h",
],
tags = [
"otlp",
"otlp_file_metric",
Expand All @@ -1049,6 +1175,66 @@ cc_test(
],
)

cc_test(
name = "otlp_file_exporter_default_json_writer_test",
srcs = ["test/otlp_file_exporter_default_json_writer_test.cc"],
tags = [
"otlp",
"otlp_file",
"test",
],
target_compatible_with = select({
":json_writer_nlohmann_enabled": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
deps = [
":otlp_file_exporter",
"//api",
"//sdk/src/metrics",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "otlp_file_log_record_exporter_default_json_writer_test",
srcs = ["test/otlp_file_log_record_exporter_default_json_writer_test.cc"],
tags = [
"otlp",
"otlp_file",
"test",
],
target_compatible_with = select({
":json_writer_nlohmann_enabled": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
deps = [
":otlp_file_log_record_exporter",
"//api",
"//sdk/src/metrics",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "otlp_file_metric_exporter_default_json_writer_test",
srcs = ["test/otlp_file_metric_exporter_default_json_writer_test.cc"],
tags = [
"otlp",
"otlp_file",
"test",
],
target_compatible_with = select({
":json_writer_nlohmann_enabled": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
deps = [
":otlp_file_metric_exporter",
"//api",
"//sdk/src/metrics",
"@com_google_googletest//:gtest_main",
],
)

otel_cc_benchmark(
name = "otlp_grpc_exporter_benchmark",
srcs = ["test/otlp_grpc_exporter_benchmark.cc"],
Expand All @@ -1065,6 +1251,23 @@ otel_cc_benchmark(
],
)

otel_cc_benchmark(
name = "otlp_file_client_json_benchmark",
srcs = ["benchmark/otlp_file_client_json_benchmark.cc"],
tags = [
"benchmark",
"otlp",
"otlp_file",
"test",
],
deps = [
":otlp_file_client",
"//sdk/src/common:global_log_handler",
"@com_github_opentelemetry_proto//:common_proto_cc",
"@com_github_opentelemetry_proto//:trace_service_proto_cc",
],
)

otel_cc_benchmark(
name = "otlp_recordable_benchmark",
srcs = ["test/otlp_recordable_benchmark.cc"],
Expand Down
Loading
Loading