The trick is to design your common-layer value type as a strict subset of OTel's AttributeValue alternatives. If every alternative your variant can hold is also a native alternative of opentelemetry::common::AttributeValue, then the OTel conversion becomes identity-construction (a one-line visitor that just returns the value), while Prometheus visits the same variant and stringifies — paying the heap/map cost alone. The common header stays OTel-free, so ODR and the Prometheus build are unaffected.
OTel's AttributeValue includes bool, int64_t, double, std::string_view (among its 16 arms). Those are exactly the spec-blessed types — so make your variant those four.
- Common layer (OTel-free) — common/include/ebay/observability/attributes.hpp
#pragma once
#include <concepts>
#include <cstdint>
#include <span>