Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
kcenon::monitoring::zipkin_exporter Class Reference

Zipkin trace exporter implementation. More...

#include <trace_exporters.h>

Inheritance diagram for kcenon::monitoring::zipkin_exporter:
Inheritance graph
Collaboration diagram for kcenon::monitoring::zipkin_exporter:
Collaboration graph

Public Member Functions

 zipkin_exporter (const trace_export_config &config)
 
 zipkin_exporter (const trace_export_config &config, std::unique_ptr< http_transport > transport)
 
zipkin_span_data convert_span (const trace_span &span) const
 Convert internal span to Zipkin format.
 
common::VoidResult export_spans (const std::vector< trace_span > &spans) override
 Export a batch of spans.
 
common::VoidResult flush () override
 Flush any pending spans.
 
common::VoidResult shutdown () override
 Shutdown the exporter.
 
std::unordered_map< std::string, std::size_t > get_stats () const override
 Get exporter statistics.
 
- Public Member Functions inherited from kcenon::monitoring::trace_exporter_interface
virtual ~trace_exporter_interface ()=default
 

Private Member Functions

common::VoidResult send_json_batch (const std::vector< zipkin_span_data > &spans)
 
common::VoidResult send_protobuf_batch (const std::vector< zipkin_span_data > &spans)
 
common::VoidResult send_with_retry (const http_request &request)
 

Private Attributes

trace_export_config config_
 
std::unique_ptr< http_transporttransport_
 
std::atomic< std::size_t > exported_spans_ {0}
 
std::atomic< std::size_t > failed_exports_ {0}
 
std::atomic< std::size_t > dropped_spans_ {0}
 
std::size_t max_retries_ {3}
 
std::chrono::milliseconds base_retry_delay_ {100}
 

Detailed Description

Zipkin trace exporter implementation.

Supports JSON v2 and Protocol Buffers formats. Default endpoint: /api/v2/spans

Definition at line 632 of file trace_exporters.h.

Constructor & Destructor Documentation

◆ zipkin_exporter() [1/2]

kcenon::monitoring::zipkin_exporter::zipkin_exporter ( const trace_export_config & config)
inlineexplicit

Definition at line 643 of file trace_exporters.h.

std::unique_ptr< http_transport > transport_
std::unique_ptr< http_transport > create_default_transport()
Create default HTTP transport.

◆ zipkin_exporter() [2/2]

kcenon::monitoring::zipkin_exporter::zipkin_exporter ( const trace_export_config & config,
std::unique_ptr< http_transport > transport )
inline

Definition at line 646 of file trace_exporters.h.

647 : config_(config), transport_(std::move(transport)) {}

Member Function Documentation

◆ convert_span()

zipkin_span_data kcenon::monitoring::zipkin_exporter::convert_span ( const trace_span & span) const
inline

Convert internal span to Zipkin format.

Definition at line 652 of file trace_exporters.h.

652 {
653 zipkin_span_data zipkin_span;
654 zipkin_span.trace_id = span.trace_id;
655 zipkin_span.span_id = span.span_id;
656 zipkin_span.parent_id = span.parent_span_id;
657 zipkin_span.name = span.operation_name;
658 zipkin_span.local_endpoint_service_name = config_.service_name.value_or(span.service_name);
659
660 // Convert timestamps (Zipkin uses microseconds since epoch)
661 auto start_epoch = span.start_time.time_since_epoch();
662 zipkin_span.timestamp = std::chrono::duration_cast<std::chrono::microseconds>(start_epoch);
663
664 auto end_epoch = span.end_time.time_since_epoch();
665 zipkin_span.duration = std::chrono::duration_cast<std::chrono::microseconds>(end_epoch - start_epoch);
666
667 // Determine span kind from tags
668 auto kind_it = span.tags.find("span.kind");
669 if (kind_it != span.tags.end()) {
670 zipkin_span.kind = kind_it->second;
671 } else {
672 zipkin_span.kind = "INTERNAL";
673 }
674
675 // Convert tags (exclude special fields)
676 for (const auto& [key, value] : span.tags) {
677 if (key != "span.kind") {
678 zipkin_span.tags[key] = value;
679 }
680 }
681
682 return zipkin_span;
683 }
std::optional< std::string > service_name
Override service name.

References config_, kcenon::monitoring::zipkin_span_data::duration, kcenon::monitoring::trace_span::end_time, kcenon::monitoring::zipkin_span_data::kind, kcenon::monitoring::zipkin_span_data::local_endpoint_service_name, kcenon::monitoring::zipkin_span_data::name, kcenon::monitoring::trace_span::operation_name, kcenon::monitoring::zipkin_span_data::parent_id, kcenon::monitoring::trace_span::parent_span_id, kcenon::monitoring::trace_export_config::service_name, kcenon::monitoring::trace_span::service_name, kcenon::monitoring::trace_span::span_id, kcenon::monitoring::zipkin_span_data::span_id, kcenon::monitoring::trace_span::start_time, kcenon::monitoring::trace_span::tags, kcenon::monitoring::zipkin_span_data::tags, kcenon::monitoring::zipkin_span_data::timestamp, kcenon::monitoring::trace_span::trace_id, and kcenon::monitoring::zipkin_span_data::trace_id.

Referenced by export_spans(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

Here is the caller graph for this function:

◆ export_spans()

common::VoidResult kcenon::monitoring::zipkin_exporter::export_spans ( const std::vector< trace_span > & spans)
inlineoverridevirtual

Export a batch of spans.

Implements kcenon::monitoring::trace_exporter_interface.

Definition at line 685 of file trace_exporters.h.

685 {
686 try {
687 std::vector<zipkin_span_data> zipkin_spans;
688 zipkin_spans.reserve(spans.size());
689
690 for (const auto& span : spans) {
691 zipkin_spans.push_back(convert_span(span));
692 }
693
694 // Convert to appropriate format and send
695 common::VoidResult send_result = common::ok();
697 send_result = send_json_batch(zipkin_spans);
699 send_result = send_protobuf_batch(zipkin_spans);
700 } else {
701 return common::VoidResult::err(error_info(monitoring_error_code::invalid_configuration,
702 "Invalid Zipkin export format", "monitoring_system").to_common_error());
703 }
704
705 if (send_result.is_ok()) {
706 exported_spans_ += spans.size();
707 } else {
709 return send_result;
710 }
711
712 return common::ok();
713
714 } catch (const std::exception& e) {
716 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
717 "Zipkin export failed: " + std::string(e.what()), "monitoring_system").to_common_error());
718 }
719 }
zipkin_span_data convert_span(const trace_span &span) const
Convert internal span to Zipkin format.
std::atomic< std::size_t > failed_exports_
std::atomic< std::size_t > exported_spans_
common::VoidResult send_json_batch(const std::vector< zipkin_span_data > &spans)
common::VoidResult send_protobuf_batch(const std::vector< zipkin_span_data > &spans)
@ zipkin_json
Zipkin JSON v2 format.
@ zipkin_protobuf
Zipkin Protocol Buffers format.

References config_, convert_span(), exported_spans_, failed_exports_, kcenon::monitoring::trace_export_config::format, kcenon::monitoring::invalid_configuration, kcenon::monitoring::operation_failed, send_json_batch(), send_protobuf_batch(), kcenon::monitoring::error_info::to_common_error(), kcenon::monitoring::zipkin_json, and kcenon::monitoring::zipkin_protobuf.

Referenced by TEST_F(), and TEST_F().

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

◆ flush()

common::VoidResult kcenon::monitoring::zipkin_exporter::flush ( )
inlineoverridevirtual

Flush any pending spans.

Implements kcenon::monitoring::trace_exporter_interface.

Definition at line 721 of file trace_exporters.h.

721 {
722 // Zipkin exporter typically sends immediately, so flush is a no-op
723 return common::ok();
724 }

Referenced by shutdown(), and TEST_F().

Here is the caller graph for this function:

◆ get_stats()

std::unordered_map< std::string, std::size_t > kcenon::monitoring::zipkin_exporter::get_stats ( ) const
inlineoverridevirtual

Get exporter statistics.

Implements kcenon::monitoring::trace_exporter_interface.

Definition at line 730 of file trace_exporters.h.

730 {
731 return {
732 {"exported_spans", exported_spans_.load()},
733 {"failed_exports", failed_exports_.load()},
734 {"dropped_spans", dropped_spans_.load()}
735 };
736 }
std::atomic< std::size_t > dropped_spans_

References dropped_spans_, exported_spans_, and failed_exports_.

Referenced by TEST_F().

Here is the caller graph for this function:

◆ send_json_batch()

common::VoidResult kcenon::monitoring::zipkin_exporter::send_json_batch ( const std::vector< zipkin_span_data > & spans)
inlineprivate

Definition at line 739 of file trace_exporters.h.

739 {
740 // Build JSON array payload for Zipkin v2 API
741 std::ostringstream payload;
742 payload << "[";
743 bool first = true;
744 for (const auto& span : spans) {
745 if (!first) payload << ",";
746 payload << span.to_json_v2();
747 first = false;
748 }
749 payload << "]";
750
751 std::string body = payload.str();
752
753 // Build HTTP request
754 http_request request;
755 request.url = config_.endpoint + "/api/v2/spans";
756 request.method = "POST";
757 request.headers["Content-Type"] = "application/json";
758 request.headers["Accept"] = "application/json";
759 for (const auto& [key, value] : config_.headers) {
760 request.headers[key] = value;
761 }
762 request.body = std::vector<uint8_t>(body.begin(), body.end());
763 request.timeout = config_.timeout;
764
765 return send_with_retry(request);
766 }
common::VoidResult send_with_retry(const http_request &request)
std::chrono::milliseconds timeout
Request timeout.
std::unordered_map< std::string, std::string > headers
Custom HTTP headers.

References kcenon::monitoring::http_request::body, config_, kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::http_request::headers, kcenon::monitoring::trace_export_config::headers, kcenon::monitoring::http_request::method, send_with_retry(), kcenon::monitoring::http_request::timeout, kcenon::monitoring::trace_export_config::timeout, and kcenon::monitoring::http_request::url.

Referenced by export_spans().

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

◆ send_protobuf_batch()

common::VoidResult kcenon::monitoring::zipkin_exporter::send_protobuf_batch ( const std::vector< zipkin_span_data > & spans)
inlineprivate

Definition at line 768 of file trace_exporters.h.

768 {
769 // Serialize as a Zipkin `ListOfSpans` protobuf message. POST target
770 // accepts application/x-protobuf per Zipkin v2 API.
771 auto payload = encode_zipkin_list_of_spans(spans);
772
773 http_request request;
774 request.url = config_.endpoint + "/api/v2/spans";
775 request.method = "POST";
776 request.headers["Content-Type"] = "application/x-protobuf";
777 for (const auto& [key, value] : config_.headers) {
778 request.headers[key] = value;
779 }
780 request.body = payload;
781 request.timeout = config_.timeout;
782
783 return send_with_retry(request);
784 }
std::vector< uint8_t > encode_zipkin_list_of_spans(const std::vector< zipkin_span_data > &spans)
Encode a batch of Zipkin spans into a ListOfSpans protobuf message suitable for POST /api/v2/spans wi...

References kcenon::monitoring::http_request::body, config_, kcenon::monitoring::encode_zipkin_list_of_spans(), kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::http_request::headers, kcenon::monitoring::trace_export_config::headers, kcenon::monitoring::http_request::method, send_with_retry(), kcenon::monitoring::http_request::timeout, kcenon::monitoring::trace_export_config::timeout, and kcenon::monitoring::http_request::url.

Referenced by export_spans().

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

◆ send_with_retry()

common::VoidResult kcenon::monitoring::zipkin_exporter::send_with_retry ( const http_request & request)
inlineprivate

Definition at line 786 of file trace_exporters.h.

786 {
787 std::size_t attempt = 0;
788 std::chrono::milliseconds delay = base_retry_delay_;
789
790 while (attempt < max_retries_) {
791 auto result = transport_->send(request);
792 if (result.is_ok()) {
793 const auto& response = result.value();
794 if (response.status_code >= 200 && response.status_code < 300) {
795 return common::ok();
796 }
797 // Retry on 5xx errors
798 if (response.status_code >= 500) {
799 attempt++;
800 if (attempt < max_retries_) {
801 std::this_thread::sleep_for(delay);
802 delay *= 2; // Exponential backoff
803 }
804 continue;
805 }
806 // Non-retryable error
807 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
808 "Zipkin export failed with status: " + std::to_string(response.status_code),
809 "monitoring_system").to_common_error());
810 }
811 attempt++;
812 if (attempt < max_retries_) {
813 std::this_thread::sleep_for(delay);
814 delay *= 2;
815 }
816 }
817 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
818 "Zipkin export failed after " + std::to_string(max_retries_) + " retries",
819 "monitoring_system").to_common_error());
820 }
std::chrono::milliseconds base_retry_delay_
@ delay
Delay requests until resources are available.

References base_retry_delay_, kcenon::monitoring::delay, max_retries_, kcenon::monitoring::operation_failed, kcenon::monitoring::error_info::to_common_error(), and transport_.

Referenced by send_json_batch(), and send_protobuf_batch().

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

◆ shutdown()

common::VoidResult kcenon::monitoring::zipkin_exporter::shutdown ( )
inlineoverridevirtual

Shutdown the exporter.

Implements kcenon::monitoring::trace_exporter_interface.

Definition at line 726 of file trace_exporters.h.

726 {
727 return flush();
728 }
common::VoidResult flush() override
Flush any pending spans.

References flush().

Referenced by TEST_F().

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

Member Data Documentation

◆ base_retry_delay_

std::chrono::milliseconds kcenon::monitoring::zipkin_exporter::base_retry_delay_ {100}
private

Definition at line 640 of file trace_exporters.h.

640{100};

Referenced by send_with_retry().

◆ config_

trace_export_config kcenon::monitoring::zipkin_exporter::config_
private

◆ dropped_spans_

std::atomic<std::size_t> kcenon::monitoring::zipkin_exporter::dropped_spans_ {0}
private

Definition at line 638 of file trace_exporters.h.

638{0};

Referenced by get_stats().

◆ exported_spans_

std::atomic<std::size_t> kcenon::monitoring::zipkin_exporter::exported_spans_ {0}
private

Definition at line 636 of file trace_exporters.h.

636{0};

Referenced by export_spans(), and get_stats().

◆ failed_exports_

std::atomic<std::size_t> kcenon::monitoring::zipkin_exporter::failed_exports_ {0}
private

Definition at line 637 of file trace_exporters.h.

637{0};

Referenced by export_spans(), and get_stats().

◆ max_retries_

std::size_t kcenon::monitoring::zipkin_exporter::max_retries_ {3}
private

Definition at line 639 of file trace_exporters.h.

639{3};

Referenced by send_with_retry().

◆ transport_

std::unique_ptr<http_transport> kcenon::monitoring::zipkin_exporter::transport_
private

Definition at line 635 of file trace_exporters.h.

Referenced by send_with_retry().


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