From 3f2d60007d4ad32db6295ac9e3d9cc1a6fa13d52 Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Sun, 17 May 2026 18:11:27 +0200 Subject: [PATCH 01/13] wip --- include/motis/ctx_data.h | 6 +++ include/motis/otel_runtime_context.h | 68 ++++++++++++++++++++++++++++ include/motis/otel_tracer.h | 15 ++++++ src/otel_tracer.cc | 64 ++++++++++++++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 include/motis/otel_runtime_context.h create mode 100644 include/motis/otel_tracer.h create mode 100644 src/otel_tracer.cc diff --git a/include/motis/ctx_data.h b/include/motis/ctx_data.h index c6d0092bfc..ec11fac84c 100644 --- a/include/motis/ctx_data.h +++ b/include/motis/ctx_data.h @@ -1,5 +1,9 @@ #pragma once +#include + +#include "opentelemetry/context/context.h" + #include "ctx/op_id.h" #include "ctx/operation.h" @@ -7,6 +11,8 @@ namespace motis { struct ctx_data { void transition(ctx::transition, ctx::op_id, ctx::op_id) {} + + std::vector otel_context_stack_; }; } // namespace motis \ No newline at end of file diff --git a/include/motis/otel_runtime_context.h b/include/motis/otel_runtime_context.h new file mode 100644 index 0000000000..e0955925b5 --- /dev/null +++ b/include/motis/otel_runtime_context.h @@ -0,0 +1,68 @@ +#pragma once + +#include + +#include "utl/helpers/algorithm.h" + +#include "opentelemetry/context/context.h" +#include "opentelemetry/context/runtime_context.h" + +#include "ctx/operation.h" + +#include "motis/ctx_data.h" + +namespace motis::otel { + +struct otel_runtime_context_storage + : public opentelemetry::context::RuntimeContextStorage { + opentelemetry::context::Context GetCurrent() noexcept override { + auto const op = ctx::current_op(); + + if (op == nullptr) { + return default_storage_->GetCurrent(); + } + + // How to get stack of contexts from op (operation*) + auto& stack = op->otel_context_stack_; + return stack.empty() ? opentelemetry::context::Context{} : stack.back(); + } + + opentelemetry::nostd::unique_ptr Attach( + opentelemetry::context::Context& context) noexcept override { + auto const op = ctx::current_op(); + + if (op == nullptr) { + return default_storage_->Attach(context); + } + + op->otel_context_stack_.push_back(context); + return CreateToken(context); + } + + bool Detach(opentelemetry::context::Token& token) noexcept override { + auto const op = ctx::current_op(); + + if (op == nullptr) { + return default_storage_->Detach(token); + } + + auto& stack = op->otel_context_stack_; + + if (utl::find(stack, token) == stack.end()) { + return false; + } + + while (!(token == stack.back())) { + stack.pop_back(); + } + stack.pop_back(); + return true; + } + +private: + std::unique_ptr + default_storage_{std::make_unique< + opentelemetry::context::ThreadLocalContextStorage>()}; +}; + +} // namespace motis::otel \ No newline at end of file diff --git a/include/motis/otel_tracer.h b/include/motis/otel_tracer.h new file mode 100644 index 0000000000..ee4d4b3b50 --- /dev/null +++ b/include/motis/otel_tracer.h @@ -0,0 +1,15 @@ +#pragma once + +#include "opentelemetry/sdk/resource/resource.h" + +#include "motis/config.h" +#include "motis/otel_runtime_context.h" + +namespace motis { + +void init_opentelemetry(config::otlp const&); + +void init_opentelemetry_tracer_http( + opentelemetry::sdk::resource::Resource const&, config::otlp const&); + +} // namespace motis \ No newline at end of file diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc new file mode 100644 index 0000000000..e36702b33f --- /dev/null +++ b/src/otel_tracer.cc @@ -0,0 +1,64 @@ +#include "motis/otel_tracer.h" + +#include +#include + +#include "opentelemetry/context/propagation/global_propagator.h" +#include "opentelemetry/context/runtime_context.h" +#include "opentelemetry/exporters/otlp_http_exporter.h" +#include "opentelemetry/sdk/trace/exporter.h" +#include "opentelemetry/sdk/trace/processor.h" +#include "opentelemetry/sdk/trace/samplers/always_on.h" +#include "opentelemetry/sdk/trace/simple_processor.h" +#include "opentelemetry/trace/propagation/http_trace_context.h" +#include "opentelemetry/trace/tracer_provider.h" + +namespace motis { + +void init_opentelemetry(config::otlp const& opts) { + auto resource_attributes = opentelemetry::sdk::resource::ResourceAttributes{ + {"service.name", "motis"}, + { + "service.version" /* TODO add version*/ + }}; + auto resource = + opentelemetry::sdk::resource::Resource::Create(resource_attributes); + + opentelemetry::context::RuntimeContext::SetRuntimeContextStorage( + std::make_shared()); + + if (opts.otlp_http_) { + init_opentelemetry_tracer(resource, opts); + } + + // What is this used for exactly? + opentelemetry::context::propagation::GlobalTextMapPropagator:: + SetGlobalPropagator( + std::make_shared< + opentelemetry::trace::propagation::HttpTraceContext>()); +} + +void init_opentelemetry_tracer( + opentelemetry::sdk::resource::Resource const& resource, + config::otlp const&) { + + // TODO + // create otlp opts from config - or pass otlp opts directly + + auto exporter = std::unique_ptr( + new opentelemetry::exporter::otlp::OtlpHttpExporter(opts)); + + auto procesor = std::unique_ptr( + new opentelemetry::sdk::trace::SimpleSpanProcessor(std::move(exporter))); + + auto sampler = std::unique_ptr( + new opentelemetry::sdk::trace::AlwaysOnSampler); + + // When e.g. net gets named Tracer does this is created as child to this + // provider? + auto provider = nostd::shared_ptr( + std::move(procesor), resource, std::move(sampler)); + opentelemtry::trace::provider::SetTracerProvider(provider); +} + +} // namespace motis \ No newline at end of file From 022dd9b1855e8fa1fc6e25e4ff789c7eea31bb2f Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Sun, 24 May 2026 13:11:55 +0200 Subject: [PATCH 02/13] Add configs --- include/motis/config.h | 5 +++++ src/otel_tracer.cc | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/motis/config.h b/include/motis/config.h index 19c2bdd4ec..4f3324fac0 100644 --- a/include/motis/config.h +++ b/include/motis/config.h @@ -258,6 +258,11 @@ struct config { limits get_limits() const { return limits_.value_or(limits{}); } std::optional limits_{}; + struct otlp { + std::string otlp_url{"http://localhost:4318"}; + }; + otlp otlp_{}; + struct logging { bool operator==(logging const&) const = default; std::optional log_level_{}; diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index e36702b33f..08e0670694 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -40,11 +40,15 @@ void init_opentelemetry(config::otlp const& opts) { void init_opentelemetry_tracer( opentelemetry::sdk::resource::Resource const& resource, - config::otlp const&) { + config::otlp const& c) { // TODO // create otlp opts from config - or pass otlp opts directly + auto const opts = opentelemetry::exporter::otlp::OtlpHttpExporterOptions { + .url = c.otlp_url + } + auto exporter = std::unique_ptr( new opentelemetry::exporter::otlp::OtlpHttpExporter(opts)); From c63d81c8f55a8a9a82d9dcca416772dfb80b0ade Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Sun, 24 May 2026 13:21:12 +0200 Subject: [PATCH 03/13] Add otlp config --- exe/main.cc | 6 ++++++ include/motis/config.h | 2 +- include/motis/otel_tracer.h | 3 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/exe/main.cc b/exe/main.cc index 1b77482437..3d70c78fb6 100644 --- a/exe/main.cc +++ b/exe/main.cc @@ -19,6 +19,7 @@ #include "motis/data.h" #include "motis/import.h" #include "motis/logging.h" +#include "motis/otel_tracer.h" #include "motis/server.h" #include "./flags.h" @@ -137,6 +138,11 @@ int main(int ac, char** av) { (return_value = set_log_level(std::move(log_lvl)))) { break; } + + if (c.otlp_ && c.otlp_.has_value()) { + init_opentelemetry(c.otlp_); + } + return_value = server(data{data_path, c}, c, motis_version); } catch (std::exception const& e) { std::cerr << "unable to start server: " << e.what() << "\n"; diff --git a/include/motis/config.h b/include/motis/config.h index 4f3324fac0..95392d50f4 100644 --- a/include/motis/config.h +++ b/include/motis/config.h @@ -261,7 +261,7 @@ struct config { struct otlp { std::string otlp_url{"http://localhost:4318"}; }; - otlp otlp_{}; + std::variant> otlp_{false}; struct logging { bool operator==(logging const&) const = default; diff --git a/include/motis/otel_tracer.h b/include/motis/otel_tracer.h index ee4d4b3b50..09502172a0 100644 --- a/include/motis/otel_tracer.h +++ b/include/motis/otel_tracer.h @@ -9,7 +9,4 @@ namespace motis { void init_opentelemetry(config::otlp const&); -void init_opentelemetry_tracer_http( - opentelemetry::sdk::resource::Resource const&, config::otlp const&); - } // namespace motis \ No newline at end of file From 6f22a86ce3a3367c3308e04585c12022cd242f5a Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Sun, 24 May 2026 13:27:38 +0200 Subject: [PATCH 04/13] Minor changes --- include/motis/config.h | 3 ++- include/motis/otel_tracer.h | 2 +- src/otel_tracer.cc | 46 ++++++++++++++++++------------------- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/include/motis/config.h b/include/motis/config.h index 95392d50f4..5c816f1ecd 100644 --- a/include/motis/config.h +++ b/include/motis/config.h @@ -259,7 +259,8 @@ struct config { std::optional limits_{}; struct otlp { - std::string otlp_url{"http://localhost:4318"}; + std::string url_{"http://localhost:4318"}; + bool http_{true}; }; std::variant> otlp_{false}; diff --git a/include/motis/otel_tracer.h b/include/motis/otel_tracer.h index 09502172a0..41d3acf052 100644 --- a/include/motis/otel_tracer.h +++ b/include/motis/otel_tracer.h @@ -7,6 +7,6 @@ namespace motis { -void init_opentelemetry(config::otlp const&); +void init_opentelemetry(config::otlp const&, std::string_view const); } // namespace motis \ No newline at end of file diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index 08e0670694..d5e0539086 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -15,29 +15,6 @@ namespace motis { -void init_opentelemetry(config::otlp const& opts) { - auto resource_attributes = opentelemetry::sdk::resource::ResourceAttributes{ - {"service.name", "motis"}, - { - "service.version" /* TODO add version*/ - }}; - auto resource = - opentelemetry::sdk::resource::Resource::Create(resource_attributes); - - opentelemetry::context::RuntimeContext::SetRuntimeContextStorage( - std::make_shared()); - - if (opts.otlp_http_) { - init_opentelemetry_tracer(resource, opts); - } - - // What is this used for exactly? - opentelemetry::context::propagation::GlobalTextMapPropagator:: - SetGlobalPropagator( - std::make_shared< - opentelemetry::trace::propagation::HttpTraceContext>()); -} - void init_opentelemetry_tracer( opentelemetry::sdk::resource::Resource const& resource, config::otlp const& c) { @@ -46,7 +23,7 @@ void init_opentelemetry_tracer( // create otlp opts from config - or pass otlp opts directly auto const opts = opentelemetry::exporter::otlp::OtlpHttpExporterOptions { - .url = c.otlp_url + .url = c.url_ } auto exporter = std::unique_ptr( @@ -65,4 +42,25 @@ void init_opentelemetry_tracer( opentelemtry::trace::provider::SetTracerProvider(provider); } +void init_opentelemetry(config::otlp const& c, + std::string_view const motis_version) { + auto resource_attributes = opentelemetry::sdk::resource::ResourceAttributes{ + {"service.name", "motis"}, {"service.version", motis_version}}; + auto resource = + opentelemetry::sdk::resource::Resource::Create(resource_attributes); + + opentelemetry::context::RuntimeContext::SetRuntimeContextStorage( + std::make_shared()); + + if (c.http_) { + init_opentelemetry_tracer(resource, c); + } + + // What is this used for exactly? + opentelemetry::context::propagation::GlobalTextMapPropagator:: + SetGlobalPropagator( + std::make_shared< + opentelemetry::trace::propagation::HttpTraceContext>()); +} + } // namespace motis \ No newline at end of file From 61e6af7b2f1c1377051b6b605b06b419cf17ab2d Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Tue, 26 May 2026 15:44:16 +0200 Subject: [PATCH 05/13] Fix --- exe/main.cc | 4 ++-- include/motis/config.h | 3 ++- include/motis/otel_runtime_context.h | 18 +++++++------- src/otel_tracer.cc | 35 ++++++++++++++++------------ 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/exe/main.cc b/exe/main.cc index 3d70c78fb6..3bf8915418 100644 --- a/exe/main.cc +++ b/exe/main.cc @@ -139,8 +139,8 @@ int main(int ac, char** av) { break; } - if (c.otlp_ && c.otlp_.has_value()) { - init_opentelemetry(c.otlp_); + if (c.otlp_.has_value()) { + init_opentelemetry(*c.otlp_, motis_version); } return_value = server(data{data_path, c}, c, motis_version); diff --git a/include/motis/config.h b/include/motis/config.h index 5c816f1ecd..37881f8ff0 100644 --- a/include/motis/config.h +++ b/include/motis/config.h @@ -259,10 +259,11 @@ struct config { std::optional limits_{}; struct otlp { + bool operator==(otlp const&) const = default; std::string url_{"http://localhost:4318"}; bool http_{true}; }; - std::variant> otlp_{false}; + std::optional otlp_{}; struct logging { bool operator==(logging const&) const = default; diff --git a/include/motis/otel_runtime_context.h b/include/motis/otel_runtime_context.h index e0955925b5..502f385633 100644 --- a/include/motis/otel_runtime_context.h +++ b/include/motis/otel_runtime_context.h @@ -11,42 +11,42 @@ #include "motis/ctx_data.h" -namespace motis::otel { +namespace motis { struct otel_runtime_context_storage : public opentelemetry::context::RuntimeContextStorage { opentelemetry::context::Context GetCurrent() noexcept override { - auto const op = ctx::current_op(); + auto const op = ctx::current_op(); if (op == nullptr) { return default_storage_->GetCurrent(); } // How to get stack of contexts from op (operation*) - auto& stack = op->otel_context_stack_; + auto& stack = op->data_.otel_context_stack_; return stack.empty() ? opentelemetry::context::Context{} : stack.back(); } opentelemetry::nostd::unique_ptr Attach( - opentelemetry::context::Context& context) noexcept override { - auto const op = ctx::current_op(); + opentelemetry::context::Context const& context) noexcept override { + auto const op = ctx::current_op(); if (op == nullptr) { return default_storage_->Attach(context); } - op->otel_context_stack_.push_back(context); + op->data_.otel_context_stack_.push_back(context); return CreateToken(context); } bool Detach(opentelemetry::context::Token& token) noexcept override { - auto const op = ctx::current_op(); + auto const op = ctx::current_op(); if (op == nullptr) { return default_storage_->Detach(token); } - auto& stack = op->otel_context_stack_; + auto& stack = op->data_.otel_context_stack_; if (utl::find(stack, token) == stack.end()) { return false; @@ -65,4 +65,4 @@ struct otel_runtime_context_storage opentelemetry::context::ThreadLocalContextStorage>()}; }; -} // namespace motis::otel \ No newline at end of file +} // namespace motis \ No newline at end of file diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index d5e0539086..8b7ed56815 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -5,41 +5,47 @@ #include "opentelemetry/context/propagation/global_propagator.h" #include "opentelemetry/context/runtime_context.h" -#include "opentelemetry/exporters/otlp_http_exporter.h" +#include "opentelemetry/exporters/otlp/otlp_http_exporter.h" +#include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h" #include "opentelemetry/sdk/trace/exporter.h" #include "opentelemetry/sdk/trace/processor.h" #include "opentelemetry/sdk/trace/samplers/always_on.h" +#include "opentelemetry/sdk/trace/samplers/always_on_factory.h" #include "opentelemetry/sdk/trace/simple_processor.h" +#include "opentelemetry/sdk/trace/simple_processor_factory.h" +#include "opentelemetry/sdk/trace/tracer_provider.h" +#include "opentelemetry/sdk/trace/tracer_provider_factory.h" #include "opentelemetry/trace/propagation/http_trace_context.h" -#include "opentelemetry/trace/tracer_provider.h" +#include "opentelemetry/trace/provider.h" namespace motis { void init_opentelemetry_tracer( opentelemetry::sdk::resource::Resource const& resource, config::otlp const& c) { + namespace sdktrace = opentelemetry::sdk::trace; // TODO // create otlp opts from config - or pass otlp opts directly - auto const opts = opentelemetry::exporter::otlp::OtlpHttpExporterOptions { - .url = c.url_ - } + auto opts = opentelemetry::exporter::otlp::OtlpHttpExporterOptions{}; + opts.url = c.url_; - auto exporter = std::unique_ptr( - new opentelemetry::exporter::otlp::OtlpHttpExporter(opts)); + auto exporter = + opentelemetry::exporter::otlp::OtlpHttpExporterFactory::Create(opts); - auto procesor = std::unique_ptr( - new opentelemetry::sdk::trace::SimpleSpanProcessor(std::move(exporter))); + auto processor = + opentelemetry::sdk::trace::SimpleSpanProcessorFactory::Create( + std::move(exporter)); - auto sampler = std::unique_ptr( - new opentelemetry::sdk::trace::AlwaysOnSampler); + auto sampler = opentelemetry::sdk::trace::AlwaysOnSamplerFactory::Create(); // When e.g. net gets named Tracer does this is created as child to this // provider? - auto provider = nostd::shared_ptr( - std::move(procesor), resource, std::move(sampler)); - opentelemtry::trace::provider::SetTracerProvider(provider); + auto provider = + std::shared_ptr{opentelemetry::sdk::trace::TracerProviderFactory::Create( + std::move(processor), resource, std::move(sampler))}; + opentelemetry::trace::Provider::SetTracerProvider(provider); } void init_opentelemetry(config::otlp const& c, @@ -56,7 +62,6 @@ void init_opentelemetry(config::otlp const& c, init_opentelemetry_tracer(resource, c); } - // What is this used for exactly? opentelemetry::context::propagation::GlobalTextMapPropagator:: SetGlobalPropagator( std::make_shared< From 5e424d5b653cc0abafd26a0b466414da3a989def Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Tue, 26 May 2026 20:09:52 +0200 Subject: [PATCH 06/13] Fix ubsan --- tools/ubsan-suppress.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/ubsan-suppress.txt b/tools/ubsan-suppress.txt index 98924a5a37..cf11b9113b 100644 --- a/tools/ubsan-suppress.txt +++ b/tools/ubsan-suppress.txt @@ -1,2 +1,3 @@ src:*/LuaJIT/* -src:*/libressl/* \ No newline at end of file +src:*/libressl/* +src:*/curl/* \ No newline at end of file From 7c8722d75e616df78cdbc5095663159e65e537c0 Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Wed, 27 May 2026 15:29:21 +0200 Subject: [PATCH 07/13] Add config --- exe/main.cc | 2 +- include/motis/config.h | 22 ++++++++++++++++++++-- src/config.cc | 6 ++++++ src/otel_tracer.cc | 26 +++++++++++++++++++------- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/exe/main.cc b/exe/main.cc index 3bf8915418..0f9907eda1 100644 --- a/exe/main.cc +++ b/exe/main.cc @@ -139,7 +139,7 @@ int main(int ac, char** av) { break; } - if (c.otlp_.has_value()) { + if (c.use_otlp()) { init_opentelemetry(*c.otlp_, motis_version); } diff --git a/include/motis/config.h b/include/motis/config.h index 37881f8ff0..eb185e503f 100644 --- a/include/motis/config.h +++ b/include/motis/config.h @@ -34,6 +34,7 @@ struct config { bool has_elevators() const; bool has_rt_feeds() const; bool use_street_routing() const; + bool use_otlp() const; bool operator==(config const&) const = default; @@ -260,8 +261,25 @@ struct config { struct otlp { bool operator==(otlp const&) const = default; - std::string url_{"http://localhost:4318"}; - bool http_{true}; + struct http { + bool operator==(http const&) const = default; + std::string url_{"http://localhost:4318"}; + std::string content_type_{"json"}; + bool use_json_name_{false}; + }; + std::optional http_{}; + + // struct grpc { + // bool operator==(grpc const&) const = default; + // std::string url_{"http://localhost:4317"}; + // bool use_ssl_credentials_{false}; + // std::string ssl_credentials_cacert_path_{""}; + // std::string ssl_credentials_cacert_{""}; + // }; + // std::optional grpc_{}; + + unsigned timeout_{10U}; + headers_t headers_{}; }; std::optional otlp_{}; diff --git a/src/config.cc b/src/config.cc index 3834a8357e..4f17d88fb9 100644 --- a/src/config.cc +++ b/src/config.cc @@ -287,4 +287,10 @@ bool config::use_street_routing() const { street_routing_); } +bool config::use_otlp() const { + return otlp_.has_value() && + // (otlp_->http_.has_value() || otlp_->grpc_.has_value()); + otlp_->http_.has_value(); +} + } // namespace motis diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index 8b7ed56815..093a27062b 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -1,10 +1,12 @@ #include "motis/otel_tracer.h" +#include #include #include #include "opentelemetry/context/propagation/global_propagator.h" #include "opentelemetry/context/runtime_context.h" +#include "opentelemetry/exporters/otlp/otlp_http.h" #include "opentelemetry/exporters/otlp/otlp_http_exporter.h" #include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h" #include "opentelemetry/sdk/trace/exporter.h" @@ -17,19 +19,31 @@ #include "opentelemetry/sdk/trace/tracer_provider_factory.h" #include "opentelemetry/trace/propagation/http_trace_context.h" #include "opentelemetry/trace/provider.h" +#include "utl/verify.h" namespace motis { void init_opentelemetry_tracer( opentelemetry::sdk::resource::Resource const& resource, config::otlp const& c) { - namespace sdktrace = opentelemetry::sdk::trace; - - // TODO - // create otlp opts from config - or pass otlp opts directly + auto const& http_opts = c.http_.value(); auto opts = opentelemetry::exporter::otlp::OtlpHttpExporterOptions{}; - opts.url = c.url_; + opts.url = http_opts.url_; + if (http_opts.content_type_ == "json") { + opts.content_type = + opentelemetry::exporter::otlp::HttpRequestContentType::kJson; + } else if (http_opts.content_type_ == "binary") { + opts.content_type = + opentelemetry::exporter::otlp::HttpRequestContentType::kBinary; + } else { + utl::fail("Invalid OTLP content type {}", http_opts.content_type_); + } + opts.use_json_name = http_opts.use_json_name_; + opts.timeout = std::chrono::seconds(c.timeout_); + for (auto [key, value] : c.headers_) { + opts.http_headers.insert({key, value}); + } auto exporter = opentelemetry::exporter::otlp::OtlpHttpExporterFactory::Create(opts); @@ -40,8 +54,6 @@ void init_opentelemetry_tracer( auto sampler = opentelemetry::sdk::trace::AlwaysOnSamplerFactory::Create(); - // When e.g. net gets named Tracer does this is created as child to this - // provider? auto provider = std::shared_ptr{opentelemetry::sdk::trace::TracerProviderFactory::Create( std::move(processor), resource, std::move(sampler))}; From f69824862c72fd6fcccea08f4ee2580db4f2c1a9 Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Thu, 28 May 2026 16:23:29 +0200 Subject: [PATCH 08/13] Add cleanup --- exe/main.cc | 1 + include/motis/otel_tracer.h | 14 ++++++++++++-- src/otel_tracer.cc | 17 ++++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/exe/main.cc b/exe/main.cc index 0f9907eda1..2cb0b01dbd 100644 --- a/exe/main.cc +++ b/exe/main.cc @@ -299,6 +299,7 @@ int main(int ac, char** av) { break; } + cleanup_opentelemetry_tracer(); google::protobuf::ShutdownProtobufLibrary(); return return_value; } diff --git a/include/motis/otel_tracer.h b/include/motis/otel_tracer.h index 41d3acf052..976c9a51d9 100644 --- a/include/motis/otel_tracer.h +++ b/include/motis/otel_tracer.h @@ -1,12 +1,22 @@ #pragma once -#include "opentelemetry/sdk/resource/resource.h" +#include "opentelemetry/trace/provider.h" +#include "opentelemetry/trace/scope.h" +#include "opentelemetry/trace/span.h" +#include "opentelemetry/trace/tracer.h" #include "motis/config.h" -#include "motis/otel_runtime_context.h" namespace motis { void init_opentelemetry(config::otlp const&, std::string_view const); +void cleanup_opentelemetry_tracer(); + +inline opentelemetry::nostd::shared_ptr +get_otel_tracer() { + return opentelemetry::trace::Provider::GetTracerProvider()->GetTracer( + "motis"); +} + } // namespace motis \ No newline at end of file diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index 093a27062b..72778a4886 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -4,11 +4,15 @@ #include #include +#include "opentelemetry/nostd/shared_ptr.h" +#include "utl/verify.h" + #include "opentelemetry/context/propagation/global_propagator.h" #include "opentelemetry/context/runtime_context.h" #include "opentelemetry/exporters/otlp/otlp_http.h" #include "opentelemetry/exporters/otlp/otlp_http_exporter.h" #include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h" +#include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/exporter.h" #include "opentelemetry/sdk/trace/processor.h" #include "opentelemetry/sdk/trace/samplers/always_on.h" @@ -19,7 +23,8 @@ #include "opentelemetry/sdk/trace/tracer_provider_factory.h" #include "opentelemetry/trace/propagation/http_trace_context.h" #include "opentelemetry/trace/provider.h" -#include "utl/verify.h" + +#include "motis/otel_runtime_context.h" namespace motis { @@ -80,4 +85,14 @@ void init_opentelemetry(config::otlp const& c, opentelemetry::trace::propagation::HttpTraceContext>()); } +void cleanup_opentelemetry_tracer() { + if (auto const provider = opentelemetry::trace::Provider::GetTracerProvider(); + provider) { + provider->ForceFlush(); + } + + auto const none = std::shared_ptr(); + opentelemetry::trace::Provider::SetTracerProvider(none); +} + } // namespace motis \ No newline at end of file From c43fdc8794d7ed6939ace0fe29f37feedb6e030f Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Thu, 28 May 2026 16:40:52 +0200 Subject: [PATCH 09/13] Add cleanup --- include/motis/config.h | 16 ++++++++-------- src/otel_tracer.cc | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/motis/config.h b/include/motis/config.h index eb185e503f..d17ac54653 100644 --- a/include/motis/config.h +++ b/include/motis/config.h @@ -269,14 +269,14 @@ struct config { }; std::optional http_{}; - // struct grpc { - // bool operator==(grpc const&) const = default; - // std::string url_{"http://localhost:4317"}; - // bool use_ssl_credentials_{false}; - // std::string ssl_credentials_cacert_path_{""}; - // std::string ssl_credentials_cacert_{""}; - // }; - // std::optional grpc_{}; + struct grpc { + bool operator==(grpc const&) const = default; + std::string url_{"http://localhost:4317"}; + bool use_ssl_credentials_{false}; + std::string ssl_credentials_cacert_path_{""}; + std::string ssl_credentials_cacert_{""}; + }; + std::optional grpc_{}; unsigned timeout_{10U}; headers_t headers_{}; diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index 72778a4886..18cd8acac8 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -89,6 +89,7 @@ void cleanup_opentelemetry_tracer() { if (auto const provider = opentelemetry::trace::Provider::GetTracerProvider(); provider) { provider->ForceFlush(); + provider->reset(); } auto const none = std::shared_ptr(); From 1b0b4384ebb48507bab39526488bd7ce9853f024 Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Fri, 29 May 2026 14:43:46 +0200 Subject: [PATCH 10/13] Cleanup --- include/motis/config.h | 9 --------- src/config.cc | 6 +----- src/otel_tracer.cc | 7 ------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/include/motis/config.h b/include/motis/config.h index d17ac54653..7b13631c27 100644 --- a/include/motis/config.h +++ b/include/motis/config.h @@ -269,15 +269,6 @@ struct config { }; std::optional http_{}; - struct grpc { - bool operator==(grpc const&) const = default; - std::string url_{"http://localhost:4317"}; - bool use_ssl_credentials_{false}; - std::string ssl_credentials_cacert_path_{""}; - std::string ssl_credentials_cacert_{""}; - }; - std::optional grpc_{}; - unsigned timeout_{10U}; headers_t headers_{}; }; diff --git a/src/config.cc b/src/config.cc index 4f17d88fb9..8be229bde0 100644 --- a/src/config.cc +++ b/src/config.cc @@ -287,10 +287,6 @@ bool config::use_street_routing() const { street_routing_); } -bool config::use_otlp() const { - return otlp_.has_value() && - // (otlp_->http_.has_value() || otlp_->grpc_.has_value()); - otlp_->http_.has_value(); -} +bool config::use_otlp() const { return otlp_.has_value(); } } // namespace motis diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index 18cd8acac8..8426875232 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -4,25 +4,18 @@ #include #include -#include "opentelemetry/nostd/shared_ptr.h" #include "utl/verify.h" #include "opentelemetry/context/propagation/global_propagator.h" #include "opentelemetry/context/runtime_context.h" #include "opentelemetry/exporters/otlp/otlp_http.h" -#include "opentelemetry/exporters/otlp/otlp_http_exporter.h" #include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h" #include "opentelemetry/sdk/resource/resource.h" -#include "opentelemetry/sdk/trace/exporter.h" -#include "opentelemetry/sdk/trace/processor.h" -#include "opentelemetry/sdk/trace/samplers/always_on.h" #include "opentelemetry/sdk/trace/samplers/always_on_factory.h" -#include "opentelemetry/sdk/trace/simple_processor.h" #include "opentelemetry/sdk/trace/simple_processor_factory.h" #include "opentelemetry/sdk/trace/tracer_provider.h" #include "opentelemetry/sdk/trace/tracer_provider_factory.h" #include "opentelemetry/trace/propagation/http_trace_context.h" -#include "opentelemetry/trace/provider.h" #include "motis/otel_runtime_context.h" From 3aa40dae662b1f7411fe51edd6dcda859698da06 Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Fri, 29 May 2026 16:37:21 +0200 Subject: [PATCH 11/13] Fix cleanup code, see open-telemetry/opentelemetry-cpp#2506 --- src/otel_tracer.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index 8426875232..75f94de9f9 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -21,6 +21,8 @@ namespace motis { +static std::shared_ptr provider_; + void init_opentelemetry_tracer( opentelemetry::sdk::resource::Resource const& resource, config::otlp const& c) { @@ -56,6 +58,7 @@ void init_opentelemetry_tracer( std::shared_ptr{opentelemetry::sdk::trace::TracerProviderFactory::Create( std::move(processor), resource, std::move(sampler))}; opentelemetry::trace::Provider::SetTracerProvider(provider); + provider_ = provider; } void init_opentelemetry(config::otlp const& c, @@ -79,11 +82,8 @@ void init_opentelemetry(config::otlp const& c, } void cleanup_opentelemetry_tracer() { - if (auto const provider = opentelemetry::trace::Provider::GetTracerProvider(); - provider) { - provider->ForceFlush(); - provider->reset(); - } + provider_->ForceFlush(); + provider_.reset(); auto const none = std::shared_ptr(); opentelemetry::trace::Provider::SetTracerProvider(none); From 07687a4e8f20247b01209d25691915eeacbddfbd Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Fri, 29 May 2026 16:41:02 +0200 Subject: [PATCH 12/13] Cleanup --- include/motis/otel_tracer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/motis/otel_tracer.h b/include/motis/otel_tracer.h index 976c9a51d9..54f51fe36f 100644 --- a/include/motis/otel_tracer.h +++ b/include/motis/otel_tracer.h @@ -1,7 +1,6 @@ #pragma once #include "opentelemetry/trace/provider.h" -#include "opentelemetry/trace/scope.h" #include "opentelemetry/trace/span.h" #include "opentelemetry/trace/tracer.h" From c9e684577942711ec48cd3fc68d7086c3facfba1 Mon Sep 17 00:00:00 2001 From: Jurek Elliesen <91612967+aff3npirat@users.noreply.github.com> Date: Fri, 29 May 2026 16:56:09 +0200 Subject: [PATCH 13/13] Fix --- src/config.cc | 4 +++- src/otel_tracer.cc | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/config.cc b/src/config.cc index 8be229bde0..cd939d151f 100644 --- a/src/config.cc +++ b/src/config.cc @@ -287,6 +287,8 @@ bool config::use_street_routing() const { street_routing_); } -bool config::use_otlp() const { return otlp_.has_value(); } +bool config::use_otlp() const { + return otlp_.has_value() && otlp_->http_.has_value(); +} } // namespace motis diff --git a/src/otel_tracer.cc b/src/otel_tracer.cc index 75f94de9f9..951dd695f7 100644 --- a/src/otel_tracer.cc +++ b/src/otel_tracer.cc @@ -71,7 +71,7 @@ void init_opentelemetry(config::otlp const& c, opentelemetry::context::RuntimeContext::SetRuntimeContextStorage( std::make_shared()); - if (c.http_) { + if (c.http_.has_value()) { init_opentelemetry_tracer(resource, c); } @@ -82,8 +82,10 @@ void init_opentelemetry(config::otlp const& c, } void cleanup_opentelemetry_tracer() { - provider_->ForceFlush(); - provider_.reset(); + if (provider_) { + provider_->ForceFlush(); + provider_.reset(); + } auto const none = std::shared_ptr(); opentelemetry::trace::Provider::SetTracerProvider(none);