Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::tracing::trace_context Class Reference

Immutable trace context for distributed tracing. More...

#include <trace_context.h>

Collaboration diagram for kcenon::network::tracing::trace_context:
Collaboration graph

Public Member Functions

 trace_context ()=default
 Default constructor creates an invalid context.
 
 trace_context (trace_id_t trace_id, span_id_t span_id, trace_flags flags, std::optional< span_id_t > parent_span_id=std::nullopt)
 Construct a trace context with all components.
 
auto create_child_span (std::string_view name) const -> span
 Create a child span inheriting this context.
 
auto to_traceparent () const -> std::string
 Convert context to W3C traceparent header value.
 
auto to_headers () const -> std::vector< std::pair< std::string, std::string > >
 Convert context to HTTP headers for propagation.
 
auto is_valid () const noexcept -> bool
 Check if this context is valid.
 
auto is_sampled () const noexcept -> bool
 Check if this trace is sampled.
 
auto trace_id () const noexcept -> const trace_id_t &
 Get the trace ID.
 
auto span_id () const noexcept -> const span_id_t &
 Get the span ID.
 
auto parent_span_id () const noexcept -> const std::optional< span_id_t > &
 Get the parent span ID.
 
auto flags () const noexcept -> trace_flags
 Get the trace flags.
 
auto trace_id_hex () const -> std::string
 Convert trace ID to hex string.
 
auto span_id_hex () const -> std::string
 Convert span ID to hex string.
 
auto operator== (const trace_context &other) const noexcept -> bool
 Equality comparison.
 
auto operator!= (const trace_context &other) const noexcept -> bool
 Inequality comparison.
 

Static Public Member Functions

static auto current () -> trace_context
 Get the current trace context from thread-local storage.
 
static auto create_span (std::string_view name) -> span
 Create a new root span with a new trace context.
 
static auto from_traceparent (std::string_view traceparent) -> trace_context
 Parse trace context from W3C traceparent header.
 
static auto from_headers (const std::vector< std::pair< std::string, std::string > > &headers) -> trace_context
 Parse trace context from HTTP headers.
 

Static Private Member Functions

static void set_current (const trace_context &ctx)
 Set the current thread-local trace context.
 
static void clear_current ()
 Clear the current thread-local trace context.
 

Private Attributes

trace_id_t trace_id_ {}
 
span_id_t span_id_ {}
 
std::optional< span_id_tparent_span_id_
 
trace_flags flags_ {trace_flags::none}
 
bool valid_ {false}
 

Friends

class span
 

Detailed Description

Immutable trace context for distributed tracing.

This class represents a W3C Trace Context compatible trace context that can be propagated across network boundaries. It stores trace ID, span ID, parent span ID, and sampling decision.

Thread-local storage is used to maintain the current trace context, enabling automatic context propagation within a thread.

Example usage:
// Create a new root span
auto span = trace_context::create_span("http.request");
// Get current context for propagation
auto headers = ctx.to_headers();
// Parse context from incoming request
auto parsed_ctx = trace_context::from_headers(incoming_headers);
RAII span for distributed tracing.
Definition span.h:103
static auto create_span(std::string_view name) -> span
Create a new root span with a new trace context.
static auto current() -> trace_context
Get the current trace context from thread-local storage.
static auto from_headers(const std::vector< std::pair< std::string, std::string > > &headers) -> trace_context
Parse trace context from HTTP headers.
See also
span
https://www.w3.org/TR/trace-context/
Examples
network_tracing_example.cpp.

Definition at line 77 of file trace_context.h.

Constructor & Destructor Documentation

◆ trace_context() [1/2]

kcenon::network::tracing::trace_context::trace_context ( )
default

Default constructor creates an invalid context.

◆ trace_context() [2/2]

kcenon::network::tracing::trace_context::trace_context ( trace_id_t trace_id,
span_id_t span_id,
trace_flags flags,
std::optional< span_id_t > parent_span_id = std::nullopt )

Construct a trace context with all components.

Parameters
trace_id128-bit trace identifier
span_id64-bit span identifier
flagsTrace flags (sampling decision)
parent_span_idOptional parent span identifier

Definition at line 80 of file trace_context.cpp.

85 , flags_(flags)
86 , valid_(!is_zero_trace_id(trace_id) && !is_zero_span_id(span_id))
87{
88}
auto trace_id() const noexcept -> const trace_id_t &
Get the trace ID.
auto parent_span_id() const noexcept -> const std::optional< span_id_t > &
Get the parent span ID.
auto flags() const noexcept -> trace_flags
Get the trace flags.
std::optional< span_id_t > parent_span_id_
auto span_id() const noexcept -> const span_id_t &
Get the span ID.

Member Function Documentation

◆ clear_current()

void kcenon::network::tracing::trace_context::clear_current ( )
staticprivate

Clear the current thread-local trace context.

Definition at line 100 of file trace_context.cpp.

101{
102 tls_current_context = trace_context{};
103}
trace_context()=default
Default constructor creates an invalid context.

Referenced by kcenon::network::tracing::span::impl::do_end().

Here is the caller graph for this function:

◆ create_child_span()

auto kcenon::network::tracing::trace_context::create_child_span ( std::string_view name) const -> span
nodiscard

Create a child span inheriting this context.

Parameters
nameName of the child span
Returns
New span that is a child of this context

Definition at line 121 of file trace_context.cpp.

122{
123 if (!is_valid())
124 {
125 // If parent context is invalid, create a new root span
126 auto new_trace_id = generate_trace_id();
127 auto new_span_id = generate_span_id();
128
129 trace_context new_ctx(new_trace_id, new_span_id, trace_flags::sampled);
130 return span(name, new_ctx);
131 }
132
133 // Create child span with same trace ID but new span ID
134 auto new_span_id = generate_span_id();
135 trace_context child_ctx(trace_id_, new_span_id, flags_, span_id_);
136
137 return span(name, child_ctx);
138}
auto is_valid() const noexcept -> bool
Check if this context is valid.
auto generate_span_id() -> span_id_t
Generate a random span ID.
auto generate_trace_id() -> trace_id_t
Generate a random trace ID.

References kcenon::network::tracing::generate_span_id(), kcenon::network::tracing::generate_trace_id(), and kcenon::network::tracing::sampled.

Here is the call graph for this function:

◆ create_span()

auto kcenon::network::tracing::trace_context::create_span ( std::string_view name) -> span
staticnodiscard

Create a new root span with a new trace context.

Parameters
nameName of the span
Returns
New span with a fresh trace context
Examples
network_tracing_example.cpp.

Definition at line 105 of file trace_context.cpp.

106{
107 // If there's a current context, create a child span
108 if (tls_current_context.is_valid())
109 {
110 return tls_current_context.create_child_span(name);
111 }
112
113 // Create a new root span with a fresh trace context
114 auto new_trace_id = generate_trace_id();
115 auto new_span_id = generate_span_id();
116
117 trace_context new_ctx(new_trace_id, new_span_id, trace_flags::sampled);
118 return span(name, new_ctx);
119}

References kcenon::network::tracing::generate_span_id(), kcenon::network::tracing::generate_trace_id(), and kcenon::network::tracing::sampled.

Referenced by kcenon::network::protocols::grpc::grpc_client::impl::call_raw(), kcenon::network::protocols::quic::connection::close(), kcenon::network::protocols::quic::connection::close_application(), kcenon::network::protocols::grpc::grpc_client::impl::connect(), kcenon::network::protocols::http2::http2_client::connect(), kcenon::network::protocols::quic::connection::init_server_handshake(), kcenon::network::core::messaging_server::on_accept(), kcenon::network::protocols::quic::connection::receive_packet(), kcenon::network::core::messaging_quic_client::send_on_stream(), kcenon::network::core::messaging_client::send_packet(), kcenon::network::core::messaging_quic_client::send_packet(), kcenon::network::protocols::http2::http2_client::send_request(), simulate_cache_lookup(), simulate_database_query(), kcenon::network::protocols::grpc::grpc_server::impl::start(), kcenon::network::core::messaging_client::start_client(), kcenon::network::core::messaging_quic_client::start_client(), kcenon::network::protocols::quic::connection::start_handshake(), and kcenon::network::core::messaging_server::start_server().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ current()

auto kcenon::network::tracing::trace_context::current ( ) -> trace_context
staticnodiscard

Get the current trace context from thread-local storage.

Returns
Current trace context, or invalid context if none set

Definition at line 90 of file trace_context.cpp.

91{
92 return tls_current_context;
93}

◆ flags()

auto kcenon::network::tracing::trace_context::flags ( ) const -> trace_flags
nodiscardnoexcept

Get the trace flags.

Returns
Trace flags

Definition at line 274 of file trace_context.cpp.

275{
276 return flags_;
277}

References flags_.

◆ from_headers()

auto kcenon::network::tracing::trace_context::from_headers ( const std::vector< std::pair< std::string, std::string > > & headers) -> trace_context
staticnodiscard

Parse trace context from HTTP headers.

Parameters
headersVector of header name-value pairs
Returns
Parsed trace context, or invalid context if not found

Definition at line 226 of file trace_context.cpp.

228{
229 for (const auto& [name, value] : headers)
230 {
231 // Case-insensitive comparison
232 std::string lower_name = name;
233 std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(),
234 [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
235
236 if (lower_name == "traceparent")
237 {
238 auto ctx = from_traceparent(value);
239 if (ctx.is_valid())
240 {
241 return ctx;
242 }
243 }
244 }
245
246 return trace_context{};
247}
static auto from_traceparent(std::string_view traceparent) -> trace_context
Parse trace context from W3C traceparent header.

Referenced by main().

Here is the caller graph for this function:

◆ from_traceparent()

auto kcenon::network::tracing::trace_context::from_traceparent ( std::string_view traceparent) -> trace_context
staticnodiscard

Parse trace context from W3C traceparent header.

Parameters
traceparentThe traceparent header value
Returns
Parsed trace context, or invalid context if parsing fails

Definition at line 173 of file trace_context.cpp.

174{
175 // Minimum length check: 00-{32}-{16}-{2} = 55 characters
176 if (traceparent.size() < 55)
177 {
178 return trace_context{};
179 }
180
181 // Parse version
182 if (traceparent[0] != '0' || traceparent[1] != '0' || traceparent[2] != '-')
183 {
184 return trace_context{};
185 }
186
187 // Parse trace ID (32 hex chars)
189 if (!hex_to_bytes(traceparent.substr(3, 32), trace_id.data(), 16))
190 {
191 return trace_context{};
192 }
193
194 // Check separator
195 if (traceparent[35] != '-')
196 {
197 return trace_context{};
198 }
199
200 // Parse span ID (16 hex chars)
202 if (!hex_to_bytes(traceparent.substr(36, 16), span_id.data(), 8))
203 {
204 return trace_context{};
205 }
206
207 // Check separator
208 if (traceparent[52] != '-')
209 {
210 return trace_context{};
211 }
212
213 // Parse flags (2 hex chars)
214 int high = hex_char_to_value(traceparent[53]);
215 int low = hex_char_to_value(traceparent[54]);
216 if (high < 0 || low < 0)
217 {
218 return trace_context{};
219 }
220
221 auto flags = static_cast<trace_flags>((high << 4) | low);
222
224}
trace_flags
Trace flags (8-bit)
std::array< uint8_t, 8 > span_id_t
Span ID type (64-bit identifier)
auto hex_to_bytes(std::string_view hex, uint8_t *out, size_t size) -> bool
Parse hex string to bytes.
std::array< uint8_t, 16 > trace_id_t
Trace ID type (128-bit identifier)

References kcenon::network::tracing::hex_to_bytes(), and kcenon::network::tracing::trace_id.

Here is the call graph for this function:

◆ is_sampled()

auto kcenon::network::tracing::trace_context::is_sampled ( ) const -> bool
nodiscardnoexcept

Check if this trace is sampled.

Returns
true if the trace should be recorded

Definition at line 254 of file trace_context.cpp.

255{
256 return (static_cast<uint8_t>(flags_) & static_cast<uint8_t>(trace_flags::sampled)) != 0;
257}

References flags_, and kcenon::network::tracing::sampled.

Referenced by to_traceparent().

Here is the caller graph for this function:

◆ is_valid()

auto kcenon::network::tracing::trace_context::is_valid ( ) const -> bool
nodiscardnoexcept

Check if this context is valid.

Returns
true if the context has valid trace and span IDs

Definition at line 249 of file trace_context.cpp.

250{
251 return valid_;
252}

References valid_.

Referenced by kcenon::network::tracing::span::impl::do_end(), to_headers(), and to_traceparent().

Here is the caller graph for this function:

◆ operator!=()

auto kcenon::network::tracing::trace_context::operator!= ( const trace_context & other) const -> bool
nodiscardnoexcept

Inequality comparison.

Definition at line 296 of file trace_context.cpp.

297{
298 return !(*this == other);
299}

◆ operator==()

auto kcenon::network::tracing::trace_context::operator== ( const trace_context & other) const -> bool
nodiscardnoexcept

Equality comparison.

Definition at line 289 of file trace_context.cpp.

290{
291 return trace_id_ == other.trace_id_ && span_id_ == other.span_id_ &&
292 parent_span_id_ == other.parent_span_id_ && flags_ == other.flags_ &&
293 valid_ == other.valid_;
294}

◆ parent_span_id()

auto kcenon::network::tracing::trace_context::parent_span_id ( ) const -> const std::optional<span_id_t>&
nodiscardnoexcept

Get the parent span ID.

Returns
Optional parent span identifier

Definition at line 269 of file trace_context.cpp.

270{
271 return parent_span_id_;
272}

References parent_span_id_.

◆ set_current()

void kcenon::network::tracing::trace_context::set_current ( const trace_context & ctx)
staticprivate

Set the current thread-local trace context.

Parameters
ctxContext to set

Definition at line 95 of file trace_context.cpp.

96{
97 tls_current_context = ctx;
98}

Referenced by kcenon::network::tracing::span::impl::do_end(), and kcenon::network::tracing::span::impl::impl().

Here is the caller graph for this function:

◆ span_id()

auto kcenon::network::tracing::trace_context::span_id ( ) const -> const span_id_t&
nodiscardnoexcept

Get the span ID.

Returns
64-bit span identifier

Definition at line 264 of file trace_context.cpp.

265{
266 return span_id_;
267}

References span_id_.

◆ span_id_hex()

auto kcenon::network::tracing::trace_context::span_id_hex ( ) const -> std::string
nodiscard

Convert span ID to hex string.

Returns
16-character lowercase hex string

Definition at line 284 of file trace_context.cpp.

285{
286 return bytes_to_hex(span_id_.data(), span_id_.size());
287}
auto bytes_to_hex(const uint8_t *data, size_t size) -> std::string
Convert bytes to lowercase hex string.

References kcenon::network::tracing::bytes_to_hex(), and span_id_.

Referenced by to_traceparent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_headers()

auto kcenon::network::tracing::trace_context::to_headers ( ) const -> std::vector<std::pair<std::string, std::string>>
nodiscard

Convert context to HTTP headers for propagation.

Returns
Vector of header name-value pairs

Returns headers conforming to W3C Trace Context specification.

Examples
network_tracing_example.cpp.

Definition at line 160 of file trace_context.cpp.

162{
163 std::vector<std::pair<std::string, std::string>> headers;
164
165 if (is_valid())
166 {
167 headers.emplace_back("traceparent", to_traceparent());
168 }
169
170 return headers;
171}
auto to_traceparent() const -> std::string
Convert context to W3C traceparent header value.

References is_valid(), and to_traceparent().

Here is the call graph for this function:

◆ to_traceparent()

auto kcenon::network::tracing::trace_context::to_traceparent ( ) const -> std::string
nodiscard

Convert context to W3C traceparent header value.

Returns
traceparent header value string

Format: {version}-{trace-id}-{parent-id}-{trace-flags} Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

Definition at line 140 of file trace_context.cpp.

141{
142 if (!is_valid())
143 {
144 return {};
145 }
146
147 // Format: {version}-{trace-id}-{parent-id}-{trace-flags}
148 // Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
149 std::ostringstream oss;
150 oss << "00-";
151 oss << trace_id_hex();
152 oss << "-";
153 oss << span_id_hex();
154 oss << "-";
155 oss << (is_sampled() ? "01" : "00");
156
157 return oss.str();
158}
auto span_id_hex() const -> std::string
Convert span ID to hex string.
auto trace_id_hex() const -> std::string
Convert trace ID to hex string.
auto is_sampled() const noexcept -> bool
Check if this trace is sampled.

References is_sampled(), is_valid(), span_id_hex(), and trace_id_hex().

Referenced by to_headers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ trace_id()

auto kcenon::network::tracing::trace_context::trace_id ( ) const -> const trace_id_t&
nodiscardnoexcept

Get the trace ID.

Returns
128-bit trace identifier

Definition at line 259 of file trace_context.cpp.

260{
261 return trace_id_;
262}

References trace_id_.

◆ trace_id_hex()

auto kcenon::network::tracing::trace_context::trace_id_hex ( ) const -> std::string
nodiscard

Convert trace ID to hex string.

Returns
32-character lowercase hex string

Definition at line 279 of file trace_context.cpp.

280{
281 return bytes_to_hex(trace_id_.data(), trace_id_.size());
282}

References kcenon::network::tracing::bytes_to_hex(), and trace_id_.

Referenced by to_traceparent().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ span

friend class span
friend

Definition at line 230 of file trace_context.h.

Member Data Documentation

◆ flags_

trace_flags kcenon::network::tracing::trace_context::flags_ {trace_flags::none}
private

Definition at line 215 of file trace_context.h.

Referenced by flags(), and is_sampled().

◆ parent_span_id_

std::optional<span_id_t> kcenon::network::tracing::trace_context::parent_span_id_
private

Definition at line 214 of file trace_context.h.

Referenced by parent_span_id().

◆ span_id_

span_id_t kcenon::network::tracing::trace_context::span_id_ {}
private

Definition at line 213 of file trace_context.h.

213{};

Referenced by span_id(), and span_id_hex().

◆ trace_id_

trace_id_t kcenon::network::tracing::trace_context::trace_id_ {}
private

Definition at line 212 of file trace_context.h.

212{};

Referenced by trace_id(), and trace_id_hex().

◆ valid_

bool kcenon::network::tracing::trace_context::valid_ {false}
private

Definition at line 216 of file trace_context.h.

216{false};

Referenced by is_valid().


The documentation for this class was generated from the following files: