mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-27 15:28:03 +00:00
MetricsRegistry did two jobs. It owned the OTel metrics pipeline, and it registered the observable gauges whose callbacks read live application services. The second job is what made the whole class xrpld-tier, so the pipeline's lifecycle -- the recording() gate and the stop() teardown that closes a use-after-free window -- could not be unit-tested in xrpl_tests. Split it in two: - xrpl::telemetry::MetricsRegistry (libxrpl) owns the exporter, provider, meter, the 16 synchronous instruments, recording(), stop(), and the record*/increment* methods. - xrpl::telemetry::AppMetricGauges (xrpld) owns the 19 observable gauges and their callbacks, holding a reference to the core and to the ServiceRegistry. MetricMacros.h and ValidationTracker move with the core. The macros need only recording() and meter(), both core members; the core holds a tracker by value, and a libxrpl header cannot include one from src/. ApplicationImp owns both objects and sequences them. The core is built in the member-init list, so every synchronous instrument exists before any subsystem can record one. The gauges are armed once overlay_ exists, the last service their callbacks read. Shutdown detaches the gauge callbacks before the core drops the provider, and each shutdown step is isolated so a failure in one cannot skip the others. That detach call is new. detachCallbacks() had no callers, and the flag it sets is read by the gauge callbacks but can no longer be written by the core, so the caller now has to make the ordering explicit. The telemetry module links xrpl.libxrpl.core and xrpl.libxrpl.protocol PUBLIC: ValidationTracker.h takes a LedgerIndex and MetricMacros.h takes a ServiceRegistry, both in interfaces a consumer compiles against. Adds a MetricsRegistry gtest that drives an enabled core with telemetry on and pins the recording() gate, stop() leaving the registry inert, and stop() being idempotent. The libxrpl test tree no longer depends on xrpld.telemetry at all, and the two CMake workarounds that compiled xrpld sources into xrpl_tests are gone. Documentation and dashboard source links follow the code to their new paths, split between the two classes by which one now defines each metric.
380 lines
10 KiB
CMake
380 lines
10 KiB
CMake
#[===================================================================[
|
|
Exported targets.
|
|
#]===================================================================]
|
|
|
|
include(target_protobuf_sources)
|
|
|
|
# Protocol buffers cannot participate in a unity build,
|
|
# because all the generated sources
|
|
# define a bunch of `static const` variables with the same names,
|
|
# so we just build them as a separate library.
|
|
add_library(xrpl.libpb)
|
|
set_target_properties(xrpl.libpb PROPERTIES UNITY_BUILD OFF)
|
|
target_protobuf_sources(
|
|
xrpl.libpb
|
|
xrpl/proto
|
|
LANGUAGE cpp
|
|
IMPORT_DIRS include/xrpl/proto
|
|
PROTOS include/xrpl/proto/xrpl.proto
|
|
)
|
|
|
|
file(GLOB_RECURSE protos "include/xrpl/proto/org/*.proto")
|
|
target_protobuf_sources(
|
|
xrpl.libpb
|
|
xrpl/proto
|
|
LANGUAGE cpp
|
|
IMPORT_DIRS include/xrpl/proto
|
|
PROTOS "${protos}"
|
|
)
|
|
target_protobuf_sources(
|
|
xrpl.libpb
|
|
xrpl/proto
|
|
LANGUAGE grpc
|
|
IMPORT_DIRS include/xrpl/proto
|
|
PROTOS "${protos}"
|
|
PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
|
|
GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
|
|
)
|
|
|
|
target_compile_options(
|
|
xrpl.libpb
|
|
PUBLIC
|
|
$<$<BOOL:${is_msvc}>:-wd4996>
|
|
$<$<BOOL:${is_xcode}>:
|
|
--system-header-prefix="google/protobuf"
|
|
-Wno-deprecated-dynamic-exception-spec
|
|
>
|
|
PRIVATE
|
|
$<$<BOOL:${is_msvc}>:-wd4065>
|
|
$<$<NOT:$<BOOL:${is_msvc}>>:-Wno-deprecated-declarations>
|
|
)
|
|
|
|
target_link_libraries(xrpl.libpb PUBLIC protobuf::libprotobuf gRPC::grpc++)
|
|
|
|
add_dependencies(tidy_prerequisites xrpl.libpb)
|
|
|
|
# TODO: Clean up the number of library targets later.
|
|
add_library(xrpl.imports.main INTERFACE)
|
|
|
|
target_link_libraries(
|
|
xrpl.imports.main
|
|
INTERFACE
|
|
absl::random_random
|
|
date::date
|
|
ed25519::ed25519
|
|
LibArchive::LibArchive
|
|
OpenSSL::Crypto
|
|
Xrpl::boost
|
|
Xrpl::libs
|
|
Xrpl::opts
|
|
Xrpl::syslibs
|
|
secp256k1::secp256k1
|
|
xrpl.libpb
|
|
xxHash::xxhash
|
|
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
|
|
)
|
|
|
|
include(add_module)
|
|
include(target_link_modules)
|
|
|
|
# Level 01
|
|
add_module(xrpl beast)
|
|
target_link_libraries(xrpl.libxrpl.beast PUBLIC xrpl.imports.main)
|
|
# OTelCollector in beast/insight uses the OTel Metrics SDK when telemetry is
|
|
# enabled. Link the Conan-provided umbrella target rather than individual
|
|
# component targets: the OTel package's per-component dependency graph is
|
|
# under-declared (e.g. the OTLP client references sdk::common symbols without
|
|
# declaring the edge), so naming components directly reorders the static-link
|
|
# line into an unresolvable state. The umbrella carries the full, internally
|
|
# consistent graph the package authors validated.
|
|
if(telemetry)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.beast
|
|
PUBLIC opentelemetry-cpp::opentelemetry-cpp
|
|
)
|
|
endif()
|
|
|
|
include(GitInfo)
|
|
add_module(xrpl git)
|
|
target_compile_definitions(
|
|
xrpl.libxrpl.git
|
|
PRIVATE
|
|
GIT_COMMIT_HASH="${GIT_COMMIT_HASH}"
|
|
GIT_BUILD_BRANCH="${GIT_BUILD_BRANCH}"
|
|
)
|
|
target_link_libraries(xrpl.libxrpl.git PUBLIC xrpl.imports.main)
|
|
|
|
# Level 02
|
|
add_module(xrpl basics)
|
|
target_link_libraries(xrpl.libxrpl.basics PUBLIC xrpl.libxrpl.beast)
|
|
|
|
# Level 03
|
|
add_module(xrpl config)
|
|
target_link_libraries(xrpl.libxrpl.config PUBLIC xrpl.libxrpl.basics)
|
|
|
|
add_module(xrpl json)
|
|
target_link_libraries(xrpl.libxrpl.json PUBLIC xrpl.libxrpl.basics)
|
|
|
|
add_module(xrpl crypto)
|
|
target_link_libraries(xrpl.libxrpl.crypto PUBLIC xrpl.libxrpl.basics)
|
|
|
|
# Level 04
|
|
add_module(xrpl protocol)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.protocol
|
|
PUBLIC xrpl.libxrpl.crypto xrpl.libxrpl.git xrpl.libxrpl.json
|
|
)
|
|
|
|
# Level 05
|
|
add_module(xrpl protocol_autogen)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.protocol_autogen
|
|
PUBLIC xrpl.libxrpl.protocol
|
|
)
|
|
|
|
# Level 06
|
|
add_module(xrpl core)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.core
|
|
PUBLIC
|
|
xrpl.libxrpl.basics
|
|
xrpl.libxrpl.config
|
|
xrpl.libxrpl.json
|
|
xrpl.libxrpl.protocol
|
|
xrpl.libxrpl.protocol_autogen
|
|
)
|
|
|
|
# Level 07
|
|
add_module(xrpl resource)
|
|
target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
|
|
|
|
add_module(xrpl peerfinder)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.peerfinder
|
|
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.protocol
|
|
)
|
|
|
|
# Level 08
|
|
add_module(xrpl net)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.net
|
|
PUBLIC
|
|
xrpl.libxrpl.basics
|
|
xrpl.libxrpl.json
|
|
xrpl.libxrpl.protocol
|
|
xrpl.libxrpl.resource
|
|
)
|
|
|
|
add_module(xrpl nodestore)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.nodestore
|
|
PUBLIC
|
|
xrpl.libxrpl.basics
|
|
xrpl.libxrpl.config
|
|
xrpl.libxrpl.json
|
|
xrpl.libxrpl.protocol
|
|
)
|
|
|
|
add_module(xrpl shamap)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.shamap
|
|
PUBLIC
|
|
xrpl.libxrpl.basics
|
|
xrpl.libxrpl.crypto
|
|
xrpl.libxrpl.protocol
|
|
xrpl.libxrpl.nodestore
|
|
)
|
|
|
|
add_module(xrpl rdb)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.rdb
|
|
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.config xrpl.libxrpl.core
|
|
)
|
|
|
|
add_module(xrpl server)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.server
|
|
PUBLIC
|
|
xrpl.libxrpl.config
|
|
xrpl.libxrpl.protocol
|
|
xrpl.libxrpl.core
|
|
xrpl.libxrpl.rdb
|
|
xrpl.libxrpl.resource
|
|
)
|
|
|
|
add_module(xrpl conditions)
|
|
target_link_libraries(xrpl.libxrpl.conditions PUBLIC xrpl.libxrpl.server)
|
|
|
|
add_module(xrpl ledger)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.ledger
|
|
PUBLIC
|
|
xrpl.libxrpl.basics
|
|
xrpl.libxrpl.json
|
|
xrpl.libxrpl.protocol
|
|
xrpl.libxrpl.protocol_autogen
|
|
xrpl.libxrpl.rdb
|
|
xrpl.libxrpl.server
|
|
xrpl.libxrpl.shamap
|
|
xrpl.libxrpl.conditions
|
|
)
|
|
|
|
# Telemetry module — OpenTelemetry distributed tracing support.
|
|
# Sources: include/xrpl/telemetry/ (headers), src/libxrpl/telemetry/ (impl).
|
|
# When telemetry=ON, links the Conan-provided umbrella target
|
|
# opentelemetry-cpp::opentelemetry-cpp (individual component targets like
|
|
# ::api, ::sdk are not available in the Conan package).
|
|
#
|
|
# Declared before its consumers (consensus, tx) because add_module isolates
|
|
# each module's headers: a module can only include xrpl/telemetry/ headers if
|
|
# it links this target, and the target must already exist at that point.
|
|
#
|
|
# Links xrpl.libxrpl.protocol and xrpl.libxrpl.core PUBLICLY: ValidationTracker.h
|
|
# takes LedgerIndex and MetricMacros.h takes ServiceRegistry, both in interfaces.
|
|
add_module(xrpl telemetry)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.telemetry
|
|
PUBLIC
|
|
xrpl.libxrpl.basics
|
|
xrpl.libxrpl.beast
|
|
xrpl.libxrpl.config
|
|
xrpl.libxrpl.core
|
|
xrpl.libxrpl.protocol
|
|
)
|
|
if(telemetry)
|
|
# Telemetry owns both the trace and (as of the direct-metrics API) the
|
|
# metrics pipeline. Link the umbrella target: it supplies the trace and
|
|
# metrics SDK components with the correct static-link ordering, which
|
|
# naming components individually does not (the package under-declares
|
|
# inter-component dependencies).
|
|
target_link_libraries(
|
|
xrpl.libxrpl.telemetry
|
|
PUBLIC opentelemetry-cpp::opentelemetry-cpp
|
|
)
|
|
endif()
|
|
|
|
# Links xrpl.libxrpl.telemetry for the consensus tracing spans declared in
|
|
# include/xrpl/consensus/ConsensusSpanNames.h.
|
|
add_module(xrpl consensus)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.consensus
|
|
PUBLIC
|
|
xrpl.libxrpl.basics
|
|
xrpl.libxrpl.json
|
|
xrpl.libxrpl.protocol
|
|
xrpl.libxrpl.ledger
|
|
xrpl.libxrpl.telemetry
|
|
)
|
|
|
|
add_module(xrpl tx)
|
|
target_link_libraries(
|
|
xrpl.libxrpl.tx
|
|
PUBLIC xrpl.libxrpl.ledger xrpl.libxrpl.telemetry
|
|
)
|
|
|
|
add_library(xrpl.libxrpl)
|
|
set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
|
|
|
|
add_library(xrpl::libxrpl ALIAS xrpl.libxrpl)
|
|
|
|
file(
|
|
GLOB_RECURSE sources
|
|
CONFIGURE_DEPENDS
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/libxrpl/*.cpp"
|
|
)
|
|
target_sources(xrpl.libxrpl PRIVATE ${sources})
|
|
|
|
target_link_modules(
|
|
xrpl
|
|
PUBLIC
|
|
basics
|
|
beast
|
|
conditions
|
|
config
|
|
consensus
|
|
core
|
|
crypto
|
|
git
|
|
json
|
|
ledger
|
|
net
|
|
nodestore
|
|
peerfinder
|
|
protocol
|
|
protocol_autogen
|
|
rdb
|
|
resource
|
|
server
|
|
shamap
|
|
telemetry
|
|
tx
|
|
)
|
|
|
|
# All headers in libxrpl are in modules.
|
|
# Uncomment this stanza if you have not yet moved new headers into a module.
|
|
# target_include_directories(xrpl.libxrpl
|
|
# PRIVATE
|
|
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
|
# PUBLIC
|
|
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
|
# $<INSTALL_INTERFACE:include>)
|
|
|
|
if(xrpld)
|
|
add_executable(xrpld)
|
|
patch_nix_binary(xrpld)
|
|
if(tests)
|
|
target_compile_definitions(xrpld PUBLIC ENABLE_TESTS)
|
|
target_compile_definitions(
|
|
xrpld
|
|
PRIVATE UNIT_TEST_REFERENCE_FEE=${UNIT_TEST_REFERENCE_FEE}
|
|
)
|
|
endif()
|
|
target_include_directories(
|
|
xrpld
|
|
PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
|
)
|
|
|
|
file(
|
|
GLOB_RECURSE sources
|
|
CONFIGURE_DEPENDS
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld/*.cpp"
|
|
)
|
|
target_sources(xrpld PRIVATE ${sources})
|
|
|
|
if(tests)
|
|
file(
|
|
GLOB_RECURSE sources
|
|
CONFIGURE_DEPENDS
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/test/*.cpp"
|
|
)
|
|
target_sources(xrpld PRIVATE ${sources})
|
|
endif()
|
|
|
|
target_link_libraries(xrpld Xrpl::boost Xrpl::opts Xrpl::libs xrpl.libxrpl)
|
|
exclude_if_included(xrpld)
|
|
# define a macro for tests that might need to
|
|
# be excluded or run differently in CI environment
|
|
if(is_ci)
|
|
target_compile_definitions(xrpld PRIVATE XRPL_RUNNING_IN_CI)
|
|
endif()
|
|
|
|
if(voidstar)
|
|
target_compile_options(xrpld PRIVATE -fsanitize-coverage=trace-pc-guard)
|
|
# xrpld requires access to antithesis-sdk-cpp implementation file
|
|
# antithesis_instrumentation.h, which is not exported as INTERFACE
|
|
target_include_directories(
|
|
xrpld
|
|
PRIVATE ${CMAKE_SOURCE_DIR}/external/antithesis-sdk
|
|
)
|
|
endif()
|
|
|
|
# The xrpld headers are not built with add_module, so verify them against
|
|
# the executable's own compile environment.
|
|
if(verify_headers)
|
|
verify_target_headers(xrpld "${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld")
|
|
if(tests)
|
|
verify_target_headers(xrpld "${CMAKE_CURRENT_SOURCE_DIR}/src/test")
|
|
endif()
|
|
endif()
|
|
endif()
|