mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-10 13:48:04 +00:00
Merge branch 'pratik/otel-phase8-log-correlation' into pratik/otel-phase9-metric-gap-fill
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/consensus/ConsensusParms.h>
|
||||
#include <xrpl/consensus/ConsensusProposal.h>
|
||||
#include <xrpl/consensus/ConsensusSpanLabels.h>
|
||||
#include <xrpl/consensus/ConsensusSpanNames.h>
|
||||
#include <xrpl/consensus/ConsensusTypes.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
@@ -34,9 +35,9 @@ namespace xrpl {
|
||||
/**
|
||||
* Determines why the current ledger should close at this time.
|
||||
*
|
||||
* Holds the close decision that shouldCloseLedger() reduces to a bool. Call
|
||||
* this one when the deciding branch matters. Both log identically, so call
|
||||
* one or the other, never both. Parameters match shouldCloseLedger().
|
||||
* Holds the close decision. shouldCloseLedger() delegates here and adds only
|
||||
* a comparison, so the logging happens once either way; call whichever suits.
|
||||
* Parameters match shouldCloseLedger().
|
||||
*
|
||||
* @return The deciding branch, or KeepOpen if no close condition is met.
|
||||
*/
|
||||
@@ -692,6 +693,24 @@ private:
|
||||
*/
|
||||
std::optional<xrpl::telemetry::SpanGuard> openSpan_;
|
||||
|
||||
/**
|
||||
* Record how the open-phase span began.
|
||||
*
|
||||
* @param reason Which startRoundInternal() entry path created it.
|
||||
* @param prevLedger The prior ledger, read before previousLedger_ is set.
|
||||
*/
|
||||
void
|
||||
annotateOpenStart(StartRoundReason reason, Ledger_t const& prevLedger);
|
||||
|
||||
/**
|
||||
* Record what ended the open phase.
|
||||
*
|
||||
* @param closeReason The deciding whyCloseLedger() branch.
|
||||
* @param proposersValidated Trusted peers already past the prior ledger.
|
||||
*/
|
||||
void
|
||||
annotateOpenClose(LedgerCloseReason closeReason, std::size_t proposersValidated);
|
||||
|
||||
/**
|
||||
* Create the establish-phase span if not yet active.
|
||||
* Called on each phaseEstablish() invocation; no-op while span is live.
|
||||
@@ -811,18 +830,7 @@ Consensus<Adaptor>::startRoundInternal(
|
||||
openSpan_.emplace(
|
||||
telemetry::SpanGuard::childSpan(
|
||||
telemetry::consensus::span::phaseOpen, adaptor_.roundSpanContext()));
|
||||
if (*openSpan_)
|
||||
{
|
||||
namespace cs = telemetry::consensus::span;
|
||||
// A recovery emplaces a SECOND phase.open span under the same round,
|
||||
// so this is what tells the two apart.
|
||||
openSpan_->setAttribute(
|
||||
cs::attr::startReason,
|
||||
reason == StartRoundReason::Recovered ? std::string_view{cs::val::startRecovered}
|
||||
: std::string_view{cs::val::startInitial});
|
||||
// From the parameter: previousLedger_ is not assigned until below.
|
||||
openSpan_->setAttribute(cs::attr::previousCloseAgree, prevLedger.closeAgree());
|
||||
}
|
||||
annotateOpenStart(reason, prevLedger);
|
||||
// On the Recovered path, fire phase.open here because startRoundTracing
|
||||
// (which fires it for the Initial path) is not called on re-entry. On
|
||||
// the Initial path this is a no-op because the round span hasn't been
|
||||
@@ -1376,16 +1384,7 @@ Consensus<Adaptor>::phaseOpen(std::unique_ptr<std::stringstream> const& clog)
|
||||
clog);
|
||||
if (closeReason != LedgerCloseReason::KeepOpen)
|
||||
{
|
||||
// Annotate before closeLedger() ends the span. Set once: the phase
|
||||
// moves to Establish, so phaseOpen() is not entered again this round.
|
||||
// Absent on the simulate() path, which bypasses this decision.
|
||||
if (openSpan_ && *openSpan_)
|
||||
{
|
||||
namespace cs = telemetry::consensus::span;
|
||||
openSpan_->setAttribute(cs::attr::closeReason, cs::closeReasonLabel(closeReason));
|
||||
openSpan_->setAttribute(
|
||||
cs::attr::proposersValidated, static_cast<int64_t>(proposersValidated));
|
||||
}
|
||||
annotateOpenClose(closeReason, proposersValidated);
|
||||
CLOG(clog) << "closing ledger. ";
|
||||
closeLedger(clog);
|
||||
}
|
||||
@@ -2160,6 +2159,36 @@ Consensus<Adaptor>::asCloseTime(NetClock::time_point raw) const
|
||||
return roundCloseTime(raw, closeResolution_);
|
||||
}
|
||||
|
||||
template <class Adaptor>
|
||||
void
|
||||
Consensus<Adaptor>::annotateOpenStart(StartRoundReason const reason, Ledger_t const& prevLedger)
|
||||
{
|
||||
if (!openSpan_ || !*openSpan_)
|
||||
return;
|
||||
namespace cs = telemetry::consensus::span;
|
||||
openSpan_->setAttribute(
|
||||
cs::attr::startReason,
|
||||
reason == StartRoundReason::Recovered ? std::string_view{cs::val::startRecovered}
|
||||
: std::string_view{cs::val::startInitial});
|
||||
// From the parameter: previousLedger_ is not assigned until later.
|
||||
openSpan_->setAttribute(cs::attr::previousCloseAgree, prevLedger.closeAgree());
|
||||
}
|
||||
|
||||
template <class Adaptor>
|
||||
void
|
||||
Consensus<Adaptor>::annotateOpenClose(
|
||||
LedgerCloseReason const closeReason,
|
||||
std::size_t const proposersValidated)
|
||||
{
|
||||
// Called before closeLedger() ends the span, and only on the closing tick,
|
||||
// so each attribute is written once per round.
|
||||
if (!openSpan_ || !*openSpan_)
|
||||
return;
|
||||
namespace cs = telemetry::consensus::span;
|
||||
openSpan_->setAttribute(cs::attr::closeReason, cs::closeReasonLabel(closeReason));
|
||||
openSpan_->setAttribute(cs::attr::proposersValidated, static_cast<int64_t>(proposersValidated));
|
||||
}
|
||||
|
||||
template <class Adaptor>
|
||||
void
|
||||
Consensus<Adaptor>::startEstablishTracing()
|
||||
@@ -2207,9 +2236,9 @@ Consensus<Adaptor>::endEstablishTracing()
|
||||
// Terminal convergence regime, recorded once before the span ends.
|
||||
if (establishSpan_ && *establishSpan_)
|
||||
{
|
||||
namespace cs = telemetry::consensus::span;
|
||||
establishSpan_->setAttribute(
|
||||
telemetry::consensus::span::attr::closeTimeAvalancheState,
|
||||
telemetry::consensus::span::avalancheStateLabel(closeTimeAvalancheState_));
|
||||
cs::attr::closeTimeAvalancheState, cs::avalancheStateLabel(closeTimeAvalancheState_));
|
||||
}
|
||||
establishSpan_.reset();
|
||||
establishSpanContext_ = telemetry::SpanContext{};
|
||||
|
||||
85
include/xrpl/consensus/ConsensusSpanLabels.h
Normal file
85
include/xrpl/consensus/ConsensusSpanLabels.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Enum-to-label mappings for consensus span attribute values.
|
||||
*
|
||||
* Split from ConsensusSpanNames.h so that header stays dependency-free like
|
||||
* its siblings: the span-name and attribute-key constants are included by
|
||||
* overlay and app translation units that have no use for the consensus
|
||||
* enums, while these mappings are needed only by Consensus.h.
|
||||
*
|
||||
* ConsensusSpanNames.h (constants only, no domain deps)
|
||||
* ^
|
||||
* | includes
|
||||
* ConsensusSpanLabels.h --includes--> ConsensusParms.h, ConsensusTypes.h
|
||||
* ^
|
||||
* | includes
|
||||
* Consensus.h
|
||||
*/
|
||||
|
||||
#include <xrpl/consensus/ConsensusParms.h>
|
||||
#include <xrpl/consensus/ConsensusSpanNames.h>
|
||||
#include <xrpl/consensus/ConsensusTypes.h>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace xrpl::telemetry::consensus::span {
|
||||
|
||||
/**
|
||||
* Map a close-time avalanche state to its `avalanche_state` label.
|
||||
*
|
||||
* The regime escalates Init -> Mid -> Late -> Stuck, raising the close-time
|
||||
* agreement threshold at each step.
|
||||
*
|
||||
* @param state The state held by Consensus::closeTimeAvalancheState_.
|
||||
* @return The wire label; one of val::avalanche*.
|
||||
*
|
||||
* @note No default arm, so a new enumerator is a -Wswitch warning; the
|
||||
* fall-through returns "unknown" rather than a plausible-looking regime.
|
||||
*/
|
||||
[[nodiscard]] constexpr std::string_view
|
||||
avalancheStateLabel(ConsensusParms::AvalancheState const state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case ConsensusParms::AvalancheState::Init:
|
||||
return val::avalancheInit;
|
||||
case ConsensusParms::AvalancheState::Mid:
|
||||
return val::avalancheMid;
|
||||
case ConsensusParms::AvalancheState::Late:
|
||||
return val::avalancheLate;
|
||||
case ConsensusParms::AvalancheState::Stuck:
|
||||
return val::avalancheStuck;
|
||||
}
|
||||
return val::unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a ledger-close decision to its `close_reason` label.
|
||||
*
|
||||
* @param reason The value returned by whyCloseLedger().
|
||||
* @return The wire label; one of val::close*.
|
||||
*
|
||||
* @note No default arm, so a new enumerator is a -Wswitch warning; the
|
||||
* fall-through returns "unknown". `keep_open` is mapped but never emitted.
|
||||
*/
|
||||
[[nodiscard]] constexpr std::string_view
|
||||
closeReasonLabel(LedgerCloseReason const reason)
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
case LedgerCloseReason::KeepOpen:
|
||||
return val::closeKeepOpen;
|
||||
case LedgerCloseReason::Anomaly:
|
||||
return val::closeAnomaly;
|
||||
case LedgerCloseReason::OthersClosed:
|
||||
return val::closeOthersClosed;
|
||||
case LedgerCloseReason::Idle:
|
||||
return val::closeIdle;
|
||||
case LedgerCloseReason::Normal:
|
||||
return val::closeNormal;
|
||||
}
|
||||
return val::unknown;
|
||||
}
|
||||
|
||||
} // namespace xrpl::telemetry::consensus::span
|
||||
@@ -86,8 +86,6 @@
|
||||
* +~~~ follows-from link (separate sub-tree, causal link)
|
||||
*/
|
||||
|
||||
#include <xrpl/consensus/ConsensusParms.h>
|
||||
#include <xrpl/consensus/ConsensusTypes.h>
|
||||
#include <xrpl/telemetry/SpanNames.h>
|
||||
|
||||
#include <string_view>
|
||||
@@ -194,11 +192,8 @@ inline constexpr auto earlyCloseTriggered = makeStr("early_close_triggered");
|
||||
/**
|
||||
* Open-phase end metadata (set on consensus.phase.open before reset).
|
||||
*
|
||||
* A low `tx_sets_acquired` next to a high peer_positions_at_close suggests
|
||||
* tx-set fetches did not land; the reverse skew is also possible, because
|
||||
* handleWrongLedger clears currPeerPositions_ but not acquired_.
|
||||
* `close_reason` plus `proposers_validated` separate "the network moved on
|
||||
* without us" from "the network was quiet".
|
||||
* `proposers_validated` counts validators of the previous ledger, unlike
|
||||
* `proposers_finished` below, which counts those already past it.
|
||||
*/
|
||||
inline constexpr auto openDurationMs = makeStr("open_duration_ms");
|
||||
inline constexpr auto peerPositionsAtClose = makeStr("peer_positions_at_close");
|
||||
@@ -349,61 +344,4 @@ inline constexpr auto closeIdle = makeStr("idle");
|
||||
inline constexpr auto closeNormal = makeStr("normal");
|
||||
} // namespace val
|
||||
|
||||
/**
|
||||
* Map a close-time avalanche state to its `avalanche_state` label.
|
||||
*
|
||||
* The regime escalates Init -> Mid -> Late -> Stuck, raising the close-time
|
||||
* agreement threshold at each step.
|
||||
*
|
||||
* @param state The state held by Consensus::closeTimeAvalancheState_.
|
||||
* @return The wire label; one of val::avalanche*.
|
||||
*
|
||||
* @note No default arm, so a new enumerator is a -Wswitch warning; the
|
||||
* fall-through returns "unknown" rather than a plausible-looking regime.
|
||||
*/
|
||||
[[nodiscard]] constexpr std::string_view
|
||||
avalancheStateLabel(ConsensusParms::AvalancheState const state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case ConsensusParms::AvalancheState::Init:
|
||||
return val::avalancheInit;
|
||||
case ConsensusParms::AvalancheState::Mid:
|
||||
return val::avalancheMid;
|
||||
case ConsensusParms::AvalancheState::Late:
|
||||
return val::avalancheLate;
|
||||
case ConsensusParms::AvalancheState::Stuck:
|
||||
return val::avalancheStuck;
|
||||
}
|
||||
return val::unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a ledger-close decision to its `close_reason` label.
|
||||
*
|
||||
* @param reason The value returned by whyCloseLedger().
|
||||
* @return The wire label; one of val::close*.
|
||||
*
|
||||
* @note No default arm, so a new enumerator is a -Wswitch warning; the
|
||||
* fall-through returns "unknown". `keep_open` is mapped but never emitted.
|
||||
*/
|
||||
[[nodiscard]] constexpr std::string_view
|
||||
closeReasonLabel(LedgerCloseReason const reason)
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
case LedgerCloseReason::KeepOpen:
|
||||
return val::closeKeepOpen;
|
||||
case LedgerCloseReason::Anomaly:
|
||||
return val::closeAnomaly;
|
||||
case LedgerCloseReason::OthersClosed:
|
||||
return val::closeOthersClosed;
|
||||
case LedgerCloseReason::Idle:
|
||||
return val::closeIdle;
|
||||
case LedgerCloseReason::Normal:
|
||||
return val::closeNormal;
|
||||
}
|
||||
return val::unknown;
|
||||
}
|
||||
|
||||
} // namespace xrpl::telemetry::consensus::span
|
||||
|
||||
Reference in New Issue
Block a user