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

StatsD metric exporter implementation. More...

#include <metric_exporters.h>

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

Public Member Functions

 statsd_exporter (const metric_export_config &config)
 Construct StatsD exporter with default UDP transport.
 
 statsd_exporter (const metric_export_config &config, std::unique_ptr< udp_transport > transport)
 Construct StatsD exporter with custom UDP transport.
 
std::vector< statsd_metric_dataconvert_monitoring_data (const monitoring_data &data) const
 Convert monitoring_data to StatsD format.
 
std::vector< statsd_metric_dataconvert_snapshot (const metrics_snapshot &snapshot) const
 Convert metrics_snapshot to StatsD format.
 
common::VoidResult export_metrics (const std::vector< monitoring_data > &metrics) override
 Export a batch of metrics.
 
common::VoidResult export_snapshot (const metrics_snapshot &snapshot) override
 Export a single metrics snapshot.
 
common::VoidResult start () override
 Start the exporter (for pull-based systems)
 
common::VoidResult stop () override
 Stop the exporter.
 
common::VoidResult flush () override
 Flush any pending metrics.
 
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::metric_exporter_interface
virtual ~metric_exporter_interface ()=default
 

Private Member Functions

common::VoidResult send_udp_batch (const std::vector< std::string > &lines)
 
std::string sanitize_metric_name (const std::string &name) const
 
metric_type infer_metric_type (const std::string &name, double) const
 

Private Attributes

metric_export_config config_
 
std::unique_ptr< udp_transporttransport_
 
std::atomic< std::size_t > exported_metrics_ {0}
 
std::atomic< std::size_t > failed_exports_ {0}
 
std::atomic< std::size_t > sent_packets_ {0}
 
bool started_ {false}
 

Detailed Description

StatsD metric exporter implementation.

Exports metrics to StatsD-compatible backends via UDP. Supports both plain StatsD and DataDog extension formats.

Definition at line 505 of file metric_exporters.h.

Constructor & Destructor Documentation

◆ statsd_exporter() [1/2]

kcenon::monitoring::statsd_exporter::statsd_exporter ( const metric_export_config & config)
inlineexplicit

Construct StatsD exporter with default UDP transport.

Parameters
configExport configuration with endpoint and port

Definition at line 519 of file metric_exporters.h.

520 : config_(config)
std::unique_ptr< udp_transport > transport_
std::unique_ptr< udp_transport > create_default_udp_transport()
Create default UDP transport.

◆ statsd_exporter() [2/2]

kcenon::monitoring::statsd_exporter::statsd_exporter ( const metric_export_config & config,
std::unique_ptr< udp_transport > transport )
inline

Construct StatsD exporter with custom UDP transport.

Parameters
configExport configuration
transportCustom UDP transport implementation

Definition at line 528 of file metric_exporters.h.

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

Member Function Documentation

◆ convert_monitoring_data()

std::vector< statsd_metric_data > kcenon::monitoring::statsd_exporter::convert_monitoring_data ( const monitoring_data & data) const
inline

Convert monitoring_data to StatsD format.

Definition at line 536 of file metric_exporters.h.

536 {
537 std::vector<statsd_metric_data> statsd_metrics;
538
539 for (const auto& [name, value] : data.get_metrics()) {
540 statsd_metric_data metric;
541 metric.name = sanitize_metric_name(name);
542 metric.type = infer_metric_type(name, value);
543 metric.value = value;
544 metric.sample_rate = 1.0;
545
546 // Add component as tag
547 metric.tags["component"] = data.get_component_name();
548
549 // Add custom tags from config
550 for (const auto& [key, tag_value] : config_.labels) {
551 metric.tags[key] = tag_value;
552 }
553
554 // Add tags from data
555 for (const auto& [key, tag_value] : data.get_tags()) {
556 metric.tags[key] = tag_value;
557 }
558
559 if (!config_.instance_id.empty()) {
560 metric.tags["instance"] = config_.instance_id;
561 }
562
563 statsd_metrics.push_back(std::move(metric));
564 }
565
566 return statsd_metrics;
567 }
std::string sanitize_metric_name(const std::string &name) const
metric_type infer_metric_type(const std::string &name, double) const
std::unordered_map< std::string, std::string > labels
Default labels/tags.
std::string instance_id
Instance identifier.

References config_, kcenon::monitoring::monitoring_data::get_component_name(), kcenon::monitoring::monitoring_data::get_metrics(), kcenon::monitoring::monitoring_data::get_tags(), infer_metric_type(), kcenon::monitoring::metric_export_config::instance_id, kcenon::monitoring::metric_export_config::labels, kcenon::monitoring::metric::name, sanitize_metric_name(), kcenon::monitoring::metric::tags, kcenon::monitoring::metric::type, and kcenon::monitoring::metric::value.

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

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

◆ convert_snapshot()

std::vector< statsd_metric_data > kcenon::monitoring::statsd_exporter::convert_snapshot ( const metrics_snapshot & snapshot) const
inline

Convert metrics_snapshot to StatsD format.

Definition at line 572 of file metric_exporters.h.

572 {
573 std::vector<statsd_metric_data> statsd_metrics;
574
575 for (const auto& metric_val : snapshot.metrics) {
576 statsd_metric_data metric;
577 metric.name = sanitize_metric_name(metric_val.name);
578 metric.type = infer_metric_type(metric_val.name, metric_val.value);
579 metric.value = metric_val.value;
580 metric.sample_rate = 1.0;
581
582 // Add source as tag
583 if (!snapshot.source_id.empty()) {
584 metric.tags["source"] = snapshot.source_id;
585 }
586
587 // Add custom tags from config
588 for (const auto& [key, tag_value] : config_.labels) {
589 metric.tags[key] = tag_value;
590 }
591
592 // Add tags from metric
593 for (const auto& [key, tag_value] : metric_val.tags) {
594 metric.tags[key] = tag_value;
595 }
596
597 if (!config_.instance_id.empty()) {
598 metric.tags["instance"] = config_.instance_id;
599 }
600
601 statsd_metrics.push_back(std::move(metric));
602 }
603
604 return statsd_metrics;
605 }

References config_, infer_metric_type(), kcenon::monitoring::metric_export_config::instance_id, kcenon::monitoring::metric_export_config::labels, kcenon::monitoring::metrics_snapshot::metrics, kcenon::monitoring::metric::name, sanitize_metric_name(), kcenon::monitoring::metrics_snapshot::source_id, kcenon::monitoring::metric::tags, kcenon::monitoring::metric::type, and kcenon::monitoring::metric::value.

Referenced by export_snapshot(), and TEST_F().

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

◆ export_metrics()

common::VoidResult kcenon::monitoring::statsd_exporter::export_metrics ( const std::vector< monitoring_data > & metrics)
inlineoverridevirtual

Export a batch of metrics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 607 of file metric_exporters.h.

607 {
608 try {
609 std::vector<std::string> statsd_lines;
610
611 for (const auto& data : metrics) {
612 auto statsd_metrics = convert_monitoring_data(data);
613 for (const auto& metric : statsd_metrics) {
614 bool datadog_format = (config_.format == metric_export_format::statsd_datadog);
615 statsd_lines.push_back(metric.to_statsd_format(datadog_format));
616 }
617 }
618
619 // Send via UDP (simulated)
620 auto send_result = send_udp_batch(statsd_lines);
621 if (send_result.is_ok()) {
622 exported_metrics_ += metrics.size();
624 } else {
626 return send_result;
627 }
628
629 return common::ok();
630
631 } catch (const std::exception& e) {
633 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
634 "StatsD export failed: " + std::string(e.what()), "monitoring_system").to_common_error());
635 }
636 }
std::atomic< std::size_t > failed_exports_
std::atomic< std::size_t > sent_packets_
std::atomic< std::size_t > exported_metrics_
common::VoidResult send_udp_batch(const std::vector< std::string > &lines)
std::vector< statsd_metric_data > convert_monitoring_data(const monitoring_data &data) const
Convert monitoring_data to StatsD format.
@ statsd_datadog
StatsD DataDog extension format.

References config_, convert_monitoring_data(), exported_metrics_, failed_exports_, kcenon::monitoring::metric_export_config::format, kcenon::monitoring::operation_failed, send_udp_batch(), sent_packets_, kcenon::monitoring::statsd_datadog, and kcenon::monitoring::error_info::to_common_error().

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

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

◆ export_snapshot()

common::VoidResult kcenon::monitoring::statsd_exporter::export_snapshot ( const metrics_snapshot & snapshot)
inlineoverridevirtual

Export a single metrics snapshot.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 638 of file metric_exporters.h.

638 {
639 try {
640 auto statsd_metrics = convert_snapshot(snapshot);
641 std::vector<std::string> statsd_lines;
642
643 for (const auto& metric : statsd_metrics) {
644 bool datadog_format = (config_.format == metric_export_format::statsd_datadog);
645 statsd_lines.push_back(metric.to_statsd_format(datadog_format));
646 }
647
648 // Send via UDP (simulated)
649 auto send_result = send_udp_batch(statsd_lines);
650 if (send_result.is_ok()) {
653 } else {
655 return send_result;
656 }
657
658 return common::ok();
659
660 } catch (const std::exception& e) {
662 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
663 "StatsD snapshot export failed: " + std::string(e.what()), "monitoring_system").to_common_error());
664 }
665 }
std::vector< statsd_metric_data > convert_snapshot(const metrics_snapshot &snapshot) const
Convert metrics_snapshot to StatsD format.

References config_, convert_snapshot(), exported_metrics_, failed_exports_, kcenon::monitoring::metric_export_config::format, kcenon::monitoring::operation_failed, send_udp_batch(), sent_packets_, kcenon::monitoring::statsd_datadog, and kcenon::monitoring::error_info::to_common_error().

Referenced by TEST_F().

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

◆ flush()

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

Flush any pending metrics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 703 of file metric_exporters.h.

703 {
704 // StatsD is push-based and sends immediately, so flush is a no-op
705 return common::ok();
706 }

Referenced by TEST_F().

Here is the caller graph for this function:

◆ get_stats()

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

Get exporter statistics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 712 of file metric_exporters.h.

712 {
713 std::unordered_map<std::string, std::size_t> stats = {
714 {"exported_metrics", exported_metrics_.load()},
715 {"failed_exports", failed_exports_.load()},
716 {"sent_packets", sent_packets_.load()}
717 };
718
719 // Add transport statistics if available
720 if (transport_) {
721 auto transport_stats = transport_->get_statistics();
722 stats["transport_packets_sent"] = transport_stats.packets_sent;
723 stats["transport_bytes_sent"] = transport_stats.bytes_sent;
724 stats["transport_send_failures"] = transport_stats.send_failures;
725 }
726
727 return stats;
728 }

References exported_metrics_, failed_exports_, sent_packets_, and transport_.

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

Here is the caller graph for this function:

◆ infer_metric_type()

metric_type kcenon::monitoring::statsd_exporter::infer_metric_type ( const std::string & name,
double  ) const
inlineprivate

Definition at line 770 of file metric_exporters.h.

770 {
771 // Simple heuristics for StatsD metric type inference
772 std::string lower_name = name;
773 std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower);
774
775 if (lower_name.find("count") != std::string::npos ||
776 lower_name.find("total") != std::string::npos) {
778 } else if (lower_name.find("time") != std::string::npos ||
779 lower_name.find("duration") != std::string::npos ||
780 lower_name.find("latency") != std::string::npos) {
781 return metric_type::timer;
782 } else {
783 return metric_type::gauge; // Default to gauge
784 }
785 }
@ timer
StatsD-specific timer metric.
@ gauge
Instantaneous value that can go up and down.
@ counter
Monotonically increasing counter.

References kcenon::monitoring::counter, kcenon::monitoring::gauge, and kcenon::monitoring::timer.

Referenced by convert_monitoring_data(), and convert_snapshot().

Here is the caller graph for this function:

◆ sanitize_metric_name()

std::string kcenon::monitoring::statsd_exporter::sanitize_metric_name ( const std::string & name) const
inlineprivate

Definition at line 762 of file metric_exporters.h.

762 {
763 std::string sanitized = name;
764 // Replace dots and spaces with underscores for StatsD
765 std::regex invalid_chars("[.\\s]+");
766 sanitized = std::regex_replace(sanitized, invalid_chars, "_");
767 return sanitized;
768 }

Referenced by convert_monitoring_data(), and convert_snapshot().

Here is the caller graph for this function:

◆ send_udp_batch()

common::VoidResult kcenon::monitoring::statsd_exporter::send_udp_batch ( const std::vector< std::string > & lines)
inlineprivate

Definition at line 731 of file metric_exporters.h.

731 {
732 if (!transport_) {
733 return common::VoidResult::err(error_info(
735 "UDP transport not available",
736 "statsd_exporter"
737 ).to_common_error());
738 }
739
740 // Auto-connect if not already connected
741 if (!transport_->is_connected()) {
742 auto connect_result = transport_->connect(config_.endpoint, config_.port);
743 if (connect_result.is_err()) {
744 return connect_result;
745 }
746 }
747
748 // Combine lines into a single packet (newline-separated)
749 // StatsD typically accepts multiple metrics per packet
750 std::string batch;
751 for (const auto& line : lines) {
752 if (!batch.empty()) {
753 batch += '\n';
754 }
755 batch += line;
756 }
757
758 // Send the batch
759 return transport_->send(batch);
760 }
std::uint16_t port
Port number (for UDP/TCP)
std::string endpoint
Endpoint URL or address.

References config_, kcenon::monitoring::dependency_missing, kcenon::monitoring::metric_export_config::endpoint, kcenon::monitoring::metric_export_config::port, and transport_.

Referenced by export_metrics(), and export_snapshot().

Here is the caller graph for this function:

◆ shutdown()

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

Shutdown the exporter.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 708 of file metric_exporters.h.

708 {
709 return stop();
710 }
common::VoidResult stop() override
Stop the exporter.

References stop().

Referenced by TEST_F().

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

◆ start()

common::VoidResult kcenon::monitoring::statsd_exporter::start ( )
inlineoverridevirtual

Start the exporter (for pull-based systems)

Reimplemented from kcenon::monitoring::metric_exporter_interface.

Definition at line 667 of file metric_exporters.h.

667 {
668 if (started_) {
669 return common::ok();
670 }
671
672 if (!transport_) {
673 return common::VoidResult::err(error_info(
675 "UDP transport not available",
676 "statsd_exporter"
677 ).to_common_error());
678 }
679
680 // Connect to StatsD endpoint
681 auto connect_result = transport_->connect(config_.endpoint, config_.port);
682 if (connect_result.is_err()) {
683 return connect_result;
684 }
685
686 started_ = true;
687 return common::ok();
688 }

References config_, kcenon::monitoring::dependency_missing, kcenon::monitoring::metric_export_config::endpoint, kcenon::monitoring::metric_export_config::port, started_, and transport_.

Referenced by TEST_F().

Here is the caller graph for this function:

◆ stop()

common::VoidResult kcenon::monitoring::statsd_exporter::stop ( )
inlineoverridevirtual

Stop the exporter.

Reimplemented from kcenon::monitoring::metric_exporter_interface.

Definition at line 690 of file metric_exporters.h.

690 {
691 if (!started_) {
692 return common::ok();
693 }
694
695 if (transport_) {
696 transport_->disconnect();
697 }
698
699 started_ = false;
700 return common::ok();
701 }

References started_, and transport_.

Referenced by shutdown(), and TEST_F().

Here is the caller graph for this function:

Member Data Documentation

◆ config_

metric_export_config kcenon::monitoring::statsd_exporter::config_
private

◆ exported_metrics_

std::atomic<std::size_t> kcenon::monitoring::statsd_exporter::exported_metrics_ {0}
private

Definition at line 509 of file metric_exporters.h.

509{0};

Referenced by export_metrics(), export_snapshot(), and get_stats().

◆ failed_exports_

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

Definition at line 510 of file metric_exporters.h.

510{0};

Referenced by export_metrics(), export_snapshot(), and get_stats().

◆ sent_packets_

std::atomic<std::size_t> kcenon::monitoring::statsd_exporter::sent_packets_ {0}
private

Definition at line 511 of file metric_exporters.h.

511{0};

Referenced by export_metrics(), export_snapshot(), and get_stats().

◆ started_

bool kcenon::monitoring::statsd_exporter::started_ {false}
private

Definition at line 512 of file metric_exporters.h.

512{false};

Referenced by start(), and stop().

◆ transport_

std::unique_ptr<udp_transport> kcenon::monitoring::statsd_exporter::transport_
private

Definition at line 508 of file metric_exporters.h.

Referenced by get_stats(), send_udp_batch(), start(), and stop().


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