6#include <gtest/gtest.h>
34 data.
add_metric(
"http_requests_total", 1500.0);
35 data.
add_metric(
"http_request_duration_seconds", 0.250);
36 data.
add_metric(
"memory_usage_bytes", 1024000.0);
39 data.
add_tag(
"environment",
"production");
40 data.
add_tag(
"region",
"us-west-2");
41 data.
add_tag(
"version",
"1.2.3");
49 snapshot.
capture_time = std::chrono::system_clock::now();
53 snapshot.
add_metric(
"disk_usage_percent", 68.3);
54 snapshot.
add_metric(
"network_bytes_in", 987654.0);
55 snapshot.
add_metric(
"network_bytes_out", 654321.0);
58 snapshot.
metrics[0].tags[
"host"] =
"server01";
59 snapshot.
metrics[1].tags[
"host"] =
"server01";
60 snapshot.
metrics[2].tags[
"mount"] =
"/var";
61 snapshot.
metrics[3].tags[
"interface"] =
"eth0";
62 snapshot.
metrics[4].tags[
"interface"] =
"eth0";
75 valid_config.
endpoint =
"http://prometheus:9090";
76 valid_config.
format = metric_export_format::prometheus_text;
77 valid_config.
push_interval = std::chrono::milliseconds(15000);
81 auto validation = valid_config.
validate();
82 EXPECT_TRUE(validation.is_ok());
86 port_config.
port = 8125;
87 port_config.
format = metric_export_format::statsd_plain;
88 auto port_validation = port_config.
validate();
89 EXPECT_TRUE(port_validation.is_ok());
93 invalid_config.
format = metric_export_format::prometheus_text;
94 auto invalid_validation = invalid_config.
validate();
95 EXPECT_TRUE(invalid_validation.is_err());
102 EXPECT_TRUE(interval_validation.is_err());
106 invalid_batch.
endpoint =
"http://test";
108 auto batch_validation = invalid_batch.
validate();
109 EXPECT_FALSE(batch_validation.is_ok());
113 invalid_queue.
endpoint =
"http://test";
116 auto queue_validation = invalid_queue.
validate();
117 EXPECT_FALSE(queue_validation.is_ok());
122 config.
endpoint =
"http://prometheus:9090";
123 config.
format = metric_export_format::prometheus_text;
125 config.
labels[
"datacenter"] =
"dc1";
131 EXPECT_EQ(prom_metrics.size(), 4);
134 auto it = std::find_if(prom_metrics.begin(), prom_metrics.end(),
136 ASSERT_NE(it, prom_metrics.end());
138 const auto& requests_metric = *it;
139 EXPECT_EQ(requests_metric.name,
"http_requests_total");
140 EXPECT_EQ(requests_metric.type, metric_type::counter);
141 EXPECT_EQ(requests_metric.value, 1500.0);
142 EXPECT_EQ(requests_metric.labels.at(
"component"),
"web_server");
143 EXPECT_EQ(requests_metric.labels.at(
"environment"),
"production");
144 EXPECT_EQ(requests_metric.labels.at(
"datacenter"),
"dc1");
145 EXPECT_EQ(requests_metric.labels.at(
"instance"),
"test_instance");
149 EXPECT_EQ(snapshot_metrics.size(), 5);
152 const auto& load_metric = snapshot_metrics[0];
153 EXPECT_EQ(load_metric.name,
"system_load_1m");
154 EXPECT_EQ(load_metric.type, metric_type::gauge);
155 EXPECT_EQ(load_metric.value, 2.1);
156 EXPECT_EQ(load_metric.labels.at(
"source"),
"system_monitor");
157 EXPECT_EQ(load_metric.labels.at(
"host"),
"server01");
165 metric.help_text =
"Total number of HTTP requests";
166 metric.labels[
"method"] =
"GET";
167 metric.labels[
"status"] =
"200";
173 EXPECT_NE(
prometheus_text.find(
"# HELP http_requests_total Total number of HTTP requests"), std::string::npos);
174 EXPECT_NE(
prometheus_text.find(
"# TYPE http_requests_total counter"), std::string::npos);
175 EXPECT_NE(
prometheus_text.find(
"http_requests_total{"), std::string::npos);
183 config.
endpoint =
"http://prometheus:9090";
184 config.
format = metric_export_format::prometheus_text;
189 std::vector<monitoring_data> data_batch = {test_data_};
191 EXPECT_TRUE(export_result.is_ok());
195 EXPECT_TRUE(snapshot_result.is_ok());
199 EXPECT_FALSE(metrics_text.empty());
200 EXPECT_NE(metrics_text.find(
"http_requests_total"), std::string::npos);
201 EXPECT_NE(metrics_text.find(
"system_load_1m"), std::string::npos);
205 EXPECT_EQ(stats[
"exported_metrics"], 2);
206 EXPECT_EQ(stats[
"failed_exports"], 0);
207 EXPECT_EQ(stats[
"scrape_requests"], 1);
210 auto flush_result = exporter.
flush();
211 EXPECT_TRUE(flush_result.is_ok());
213 auto shutdown_result = exporter.
shutdown();
214 EXPECT_TRUE(shutdown_result.is_ok());
219 config.
endpoint =
"statsd.example.com";
221 config.
format = metric_export_format::statsd_datadog;
223 config.
labels[
"datacenter"] =
"dc1";
229 EXPECT_EQ(statsd_metrics.size(), 4);
232 auto it = std::find_if(statsd_metrics.begin(), statsd_metrics.end(),
234 ASSERT_NE(it, statsd_metrics.end());
236 const auto& requests_metric = *it;
237 EXPECT_EQ(requests_metric.name,
"http_requests_total");
238 EXPECT_EQ(requests_metric.type, metric_type::counter);
239 EXPECT_EQ(requests_metric.value, 1500.0);
240 EXPECT_EQ(requests_metric.sample_rate, 1.0);
241 EXPECT_EQ(requests_metric.tags.at(
"component"),
"web_server");
242 EXPECT_EQ(requests_metric.tags.at(
"environment"),
"production");
243 EXPECT_EQ(requests_metric.tags.at(
"datacenter"),
"dc1");
247 EXPECT_EQ(snapshot_metrics.size(), 5);
252 counter_metric.
name =
"http_requests_total";
253 counter_metric.
type = metric_type::counter;
254 counter_metric.
value = 1500.0;
256 counter_metric.
tags[
"method"] =
"GET";
257 counter_metric.
tags[
"status"] =
"200";
261 EXPECT_EQ(plain_statsd,
"http_requests_total:1500|c");
265 EXPECT_NE(datadog_statsd.find(
"http_requests_total:1500|c|#"), std::string::npos);
266 EXPECT_NE(datadog_statsd.find(
"method:GET"), std::string::npos);
267 EXPECT_NE(datadog_statsd.find(
"status:200"), std::string::npos);
271 timer_metric.
name =
"request_duration";
272 timer_metric.
type = metric_type::timer;
273 timer_metric.
value = 250.0;
277 EXPECT_EQ(timer_statsd,
"request_duration:250|ms|@0.1");
282 config.
endpoint =
"statsd.example.com";
284 config.
format = metric_export_format::statsd_plain;
289 std::vector<monitoring_data> data_batch = {test_data_};
291 EXPECT_TRUE(export_result.is_ok());
295 EXPECT_TRUE(snapshot_result.is_ok());
299 EXPECT_EQ(stats[
"exported_metrics"], 2);
300 EXPECT_EQ(stats[
"failed_exports"], 0);
301 EXPECT_EQ(stats[
"sent_packets"], 2);
304 auto flush_result = exporter.
flush();
305 EXPECT_TRUE(flush_result.is_ok());
307 auto shutdown_result = exporter.
shutdown();
308 EXPECT_TRUE(shutdown_result.is_ok());
313 config.
endpoint =
"http://otlp-collector:4317";
314 config.
format = metric_export_format::otlp_grpc;
319 std::vector<monitoring_data> data_batch = {test_data_};
321 EXPECT_TRUE(export_result.is_ok());
325 EXPECT_TRUE(snapshot_result.is_ok());
329 EXPECT_EQ(stats[
"exported_metrics"], 2);
330 EXPECT_EQ(stats[
"failed_exports"], 0);
333 auto flush_result = exporter.
flush();
334 EXPECT_TRUE(flush_result.is_ok());
336 auto shutdown_result = exporter.
shutdown();
337 EXPECT_TRUE(shutdown_result.is_ok());
343 prometheus_config.
endpoint =
"http://prometheus:9090";
344 prometheus_config.
format = metric_export_format::prometheus_text;
351 statsd_config.
endpoint =
"statsd.example.com";
352 statsd_config.
port = 8125;
353 statsd_config.
format = metric_export_format::statsd_datadog;
360 otlp_config.
endpoint =
"http://otlp-collector:4317";
361 otlp_config.
format = metric_export_format::otlp_http_json;
368 invalid_config.
endpoint =
"http://test";
372 EXPECT_FALSE(invalid_exporter);
377 EXPECT_EQ(prometheus_formats.size(), 2);
378 EXPECT_TRUE(std::find(prometheus_formats.begin(), prometheus_formats.end(),
379 metric_export_format::prometheus_text) != prometheus_formats.end());
380 EXPECT_TRUE(std::find(prometheus_formats.begin(), prometheus_formats.end(),
381 metric_export_format::prometheus_protobuf) != prometheus_formats.end());
384 EXPECT_EQ(statsd_formats.size(), 2);
385 EXPECT_TRUE(std::find(statsd_formats.begin(), statsd_formats.end(),
386 metric_export_format::statsd_plain) != statsd_formats.end());
387 EXPECT_TRUE(std::find(statsd_formats.begin(), statsd_formats.end(),
388 metric_export_format::statsd_datadog) != statsd_formats.end());
391 EXPECT_EQ(otlp_formats.size(), 3);
392 EXPECT_TRUE(std::find(otlp_formats.begin(), otlp_formats.end(),
393 metric_export_format::otlp_grpc) != otlp_formats.end());
396 EXPECT_EQ(unknown_formats.size(), 0);
410 metric_export_format::otlp_http_json);
415 std::vector<monitoring_data> empty_data;
419 config.
endpoint =
"http://test:1234";
420 config.
format = metric_export_format::prometheus_text;
425 EXPECT_TRUE(data_result.is_ok());
428 EXPECT_TRUE(snapshot_result.is_ok());
431 EXPECT_EQ(stats[
"exported_metrics"], 1);
432 EXPECT_EQ(stats[
"failed_exports"], 0);
437 std::vector<monitoring_data> large_batch;
438 for (
int i = 0; i < 100; ++i) {
442 data.
add_tag(
"instance", std::to_string(i));
443 large_batch.push_back(data);
447 config.
endpoint =
"http://test:1234";
448 config.
format = metric_export_format::statsd_plain;
453 EXPECT_TRUE(result.is_ok());
456 EXPECT_EQ(stats[
"exported_metrics"], 100);
461 config.
endpoint =
"http://prometheus:9090";
462 config.
format = metric_export_format::prometheus_text;
468 data.
add_metric(
"http.requests-total", 100.0);
470 data.
add_metric(
"special@chars#metric", 75.0);
473 EXPECT_EQ(prom_metrics.size(), 3);
476 std::vector<std::string> expected_names = {
"http_requests_total",
"_123_invalid_start",
"special_chars_metric"};
477 std::vector<std::string> actual_names;
478 for (
const auto&
metric : prom_metrics) {
482 for (
const auto& expected_name : expected_names) {
483 EXPECT_NE(std::find(actual_names.begin(), actual_names.end(), expected_name), actual_names.end())
484 <<
"Expected metric name '" << expected_name <<
"' not found";
490 config.
endpoint =
"statsd.example.com";
492 config.
format = metric_export_format::statsd_plain;
508 auto it = std::find_if(statsd_metrics.begin(), statsd_metrics.end(),
510 return (it != statsd_metrics.end()) ? &(*it) :
nullptr;
513 EXPECT_EQ(find_metric(
"requests_count")->type, metric_type::counter);
514 EXPECT_EQ(find_metric(
"requests_total")->type, metric_type::counter);
515 EXPECT_EQ(find_metric(
"response_time_ms")->type, metric_type::timer);
516 EXPECT_EQ(find_metric(
"request_duration")->type, metric_type::timer);
517 EXPECT_EQ(find_metric(
"cpu_usage")->type, metric_type::gauge);
518 EXPECT_EQ(find_metric(
"memory_available")->type, metric_type::gauge);
525TEST(UdpTransportTest, StubTransportBasicFunctionality) {
527 ASSERT_TRUE(transport);
528 EXPECT_TRUE(transport->is_available());
529 EXPECT_EQ(transport->name(),
"stub");
530 EXPECT_FALSE(transport->is_connected());
533 auto connect_result = transport->connect(
"localhost", 8125);
534 EXPECT_TRUE(connect_result.is_ok());
535 EXPECT_TRUE(transport->is_connected());
536 EXPECT_EQ(transport->get_host(),
"localhost");
537 EXPECT_EQ(transport->get_port(), 8125);
540 std::string
metric =
"test_metric:100|c";
541 auto send_result = transport->send(
metric);
542 EXPECT_TRUE(send_result.is_ok());
545 auto stats = transport->get_statistics();
546 EXPECT_EQ(stats.packets_sent, 1);
547 EXPECT_EQ(stats.bytes_sent,
metric.size());
548 EXPECT_EQ(stats.send_failures, 0);
551 transport->disconnect();
552 EXPECT_FALSE(transport->is_connected());
555 auto fail_result = transport->send(
metric);
556 EXPECT_TRUE(fail_result.is_err());
558 auto stats_after = transport->get_statistics();
559 EXPECT_EQ(stats_after.send_failures, 1);
562TEST(UdpTransportTest, StubTransportSimulateFailure) {
564 transport->set_simulate_success(
false);
567 auto connect_result = transport->connect(
"localhost", 8125);
568 EXPECT_TRUE(connect_result.is_err());
569 EXPECT_FALSE(transport->is_connected());
572 transport->set_simulate_success(
true);
573 auto retry_result = transport->connect(
"localhost", 8125);
574 EXPECT_TRUE(retry_result.is_ok());
577 transport->set_simulate_success(
false);
578 auto send_result = transport->send(
"test:1|c");
579 EXPECT_TRUE(send_result.is_err());
582TEST(UdpTransportTest, StubTransportStatisticsReset) {
584 transport->connect(
"localhost", 8125);
585 transport->send(
"metric1:1|c");
586 transport->send(
"metric2:2|c");
587 transport->send(
"metric3:3|c");
589 auto stats = transport->get_statistics();
590 EXPECT_EQ(stats.packets_sent, 3);
591 EXPECT_GT(stats.bytes_sent, 0);
593 transport->reset_statistics();
594 auto reset_stats = transport->get_statistics();
595 EXPECT_EQ(reset_stats.packets_sent, 0);
596 EXPECT_EQ(reset_stats.bytes_sent, 0);
597 EXPECT_EQ(reset_stats.send_failures, 0);
600TEST(UdpTransportTest, DefaultTransportCreation) {
602 ASSERT_TRUE(transport);
603 EXPECT_TRUE(transport->is_available());
611TEST(GrpcTransportTest, StubTransportBasicFunctionality) {
613 ASSERT_TRUE(transport);
614 EXPECT_TRUE(transport->is_available());
615 EXPECT_EQ(transport->name(),
"stub");
616 EXPECT_FALSE(transport->is_connected());
619 auto connect_result = transport->connect(
"localhost", 4317);
620 EXPECT_TRUE(connect_result.is_ok());
621 EXPECT_TRUE(transport->is_connected());
622 EXPECT_EQ(transport->get_host(),
"localhost");
623 EXPECT_EQ(transport->get_port(), 4317);
627 request.
service =
"test.Service";
628 request.
method =
"TestMethod";
629 request.
body = {0x01, 0x02, 0x03, 0x04};
630 request.
timeout = std::chrono::milliseconds(5000);
632 auto send_result = transport->send(request);
633 EXPECT_TRUE(send_result.is_ok());
635 const auto& response = send_result.value();
636 EXPECT_EQ(response.status_code, 0);
637 EXPECT_EQ(response.status_message,
"OK");
640 auto stats = transport->get_statistics();
641 EXPECT_EQ(stats.requests_sent, 1);
642 EXPECT_EQ(stats.bytes_sent, 4);
643 EXPECT_EQ(stats.send_failures, 0);
646 transport->disconnect();
647 EXPECT_FALSE(transport->is_connected());
650TEST(GrpcTransportTest, StubTransportCustomResponseHandler) {
652 transport->connect(
"localhost", 4317);
655 transport->set_response_handler([](
const grpc_request& req) {
659 response.
body = {0xAB, 0xCD};
664 request.
method =
"CustomMethod";
665 request.
body = {0x01};
667 auto result = transport->send(request);
668 EXPECT_TRUE(result.is_ok());
669 EXPECT_EQ(result.value().status_message,
"Custom response for CustomMethod");
670 EXPECT_EQ(result.value().body.size(), 2);
673TEST(GrpcTransportTest, StubTransportSimulateFailure) {
675 transport->set_simulate_success(
false);
678 auto connect_result = transport->connect(
"localhost", 4317);
679 EXPECT_TRUE(connect_result.is_err());
682 transport->set_simulate_success(
true);
683 transport->connect(
"localhost", 4317);
686 transport->set_simulate_success(
false);
688 request.
body = {0x01};
689 auto send_result = transport->send(request);
690 EXPECT_TRUE(send_result.is_err());
692 auto stats = transport->get_statistics();
693 EXPECT_EQ(stats.send_failures, 1);
696TEST(GrpcTransportTest, DefaultTransportCreation) {
698 ASSERT_TRUE(transport);
699 EXPECT_TRUE(transport->is_available());
708 auto* transport_ptr = stub_transport.get();
711 config.
endpoint =
"statsd.example.com";
713 config.
format = metric_export_format::statsd_datadog;
718 auto start_result = exporter.
start();
719 EXPECT_TRUE(start_result.is_ok());
722 std::vector<monitoring_data> data_batch = {test_data_};
724 EXPECT_TRUE(export_result.is_ok());
727 auto transport_stats = transport_ptr->get_statistics();
728 EXPECT_GT(transport_stats.packets_sent, 0);
729 EXPECT_GT(transport_stats.bytes_sent, 0);
733 EXPECT_GT(stats[
"transport_packets_sent"], 0);
734 EXPECT_GT(stats[
"transport_bytes_sent"], 0);
737 auto stop_result = exporter.
stop();
738 EXPECT_TRUE(stop_result.is_ok());
743 stub_transport->set_simulate_success(
false);
746 config.
endpoint =
"statsd.example.com";
748 config.
format = metric_export_format::statsd_plain;
753 std::vector<monitoring_data> data_batch = {test_data_};
755 EXPECT_TRUE(export_result.is_err());
758 EXPECT_EQ(stats[
"failed_exports"], 1);
770 config.
endpoint =
"http://otlp-collector";
772 config.
format = metric_export_format::otlp_http_json;
775 std::move(stub_http), std::move(stub_grpc));
778 auto start_result = exporter.
start();
779 EXPECT_TRUE(start_result.is_ok());
781 std::vector<monitoring_data> data_batch = {test_data_};
783 EXPECT_TRUE(export_result.is_ok());
786 EXPECT_EQ(stats[
"exported_metrics"], 1);
788 auto stop_result = exporter.
stop();
789 EXPECT_TRUE(stop_result.is_ok());
796TEST(HttpTransportTest, SimpleHttpClientValidUrls) {
801 req.
url =
"http://example.com/api/v1/traces";
802 auto result =
client.send(req);
803 EXPECT_TRUE(result.is_err());
805 req.
url =
"https://collector.example.com:4318/v1/metrics";
806 result =
client.send(req);
807 EXPECT_TRUE(result.is_err());
809 req.
url =
"http://localhost:9090";
810 result =
client.send(req);
811 EXPECT_TRUE(result.is_err());
813 req.
url =
"http://prometheus";
814 result =
client.send(req);
815 EXPECT_TRUE(result.is_err());
818TEST(HttpTransportTest, SimpleHttpClientInvalidUrls) {
823 req.
url =
"example.com/api";
824 auto result =
client.send(req);
825 EXPECT_TRUE(result.is_err());
829 result =
client.send(req);
830 EXPECT_TRUE(result.is_err());
834 result =
client.send(req);
835 EXPECT_TRUE(result.is_err());
838TEST(HttpTransportTest, SimpleHttpClientPortDefaults) {
843 req.
url =
"http://example.com/path";
844 auto result =
client.send(req);
845 EXPECT_TRUE(result.is_err());
847 req.
url =
"https://example.com/path";
848 result =
client.send(req);
849 EXPECT_TRUE(result.is_err());
852TEST(HttpTransportTest, SimpleHttpClientNameAndAvailability) {
854 EXPECT_EQ(
client.name(),
"stub");
855 EXPECT_FALSE(
client.is_available());
862TEST(HttpTransportTest, StubHttpTransportIsAvailableAndName) {
864 ASSERT_TRUE(transport);
865 EXPECT_TRUE(transport->is_available());
866 EXPECT_EQ(transport->name(),
"stub");
873TEST(GrpcTransportTest, StubTransportResetStatistics) {
875 transport->connect(
"localhost", 4317);
878 request.
body = {0x01, 0x02, 0x03};
879 transport->send(request);
880 transport->send(request);
882 auto stats = transport->get_statistics();
883 EXPECT_EQ(stats.requests_sent, 2);
884 EXPECT_EQ(stats.bytes_sent, 6);
886 transport->reset_statistics();
887 auto reset_stats = transport->get_statistics();
888 EXPECT_EQ(reset_stats.requests_sent, 0);
889 EXPECT_EQ(reset_stats.bytes_sent, 0);
890 EXPECT_EQ(reset_stats.send_failures, 0);
893TEST(GrpcTransportTest, StubTransportDisconnectedState) {
895 transport->connect(
"localhost", 4317);
896 EXPECT_TRUE(transport->is_connected());
898 transport->disconnect();
899 EXPECT_FALSE(transport->is_connected());
903 request.
body = {0x01};
904 auto result = transport->send(request);
905 EXPECT_TRUE(result.is_err());
907 auto stats = transport->get_statistics();
908 EXPECT_EQ(stats.send_failures, 1);
915TEST(UdpTransportTest, StubTransportStringSendDelegation) {
917 transport->connect(
"localhost", 8125);
920 std::string metric_line =
"test.metric:42|g";
921 auto result = transport->send(metric_line);
922 EXPECT_TRUE(result.is_ok());
924 auto stats = transport->get_statistics();
925 EXPECT_EQ(stats.packets_sent, 1);
926 EXPECT_EQ(stats.bytes_sent, metric_line.size());
936 auto* grpc_ptr = stub_grpc.get();
941 config.
format = metric_export_format::otlp_grpc;
944 std::move(stub_http), std::move(stub_grpc));
946 std::vector<monitoring_data> data_batch = {test_data_};
948 EXPECT_TRUE(export_result.is_ok());
951 auto transport_stats = grpc_ptr->get_statistics();
952 EXPECT_GT(transport_stats.requests_sent, 0);
955 EXPECT_GT(stats[
"transport_requests_sent"], 0);
otel_resource otel_resource_
monitoring_data test_data_
metrics_snapshot create_test_snapshot()
metrics_snapshot test_snapshot_
monitoring_data create_test_monitoring_data()
static std::vector< metric_export_format > get_supported_formats(const std::string &backend)
Get supported formats for a specific backend.
static std::unique_ptr< metric_exporter_interface > create_exporter(const metric_export_config &config, const otel_resource &resource=create_service_resource("monitoring_system", "2.0.0"))
Create a metric exporter based on format.
OpenTelemetry Protocol (OTLP) trace exporter implementation.
OpenTelemetry Protocol (OTLP) metrics exporter implementation.
std::unordered_map< std::string, std::size_t > get_stats() const override
Get exporter statistics.
common::VoidResult export_metrics(const std::vector< monitoring_data > &metrics) override
Export a batch of metrics.
common::VoidResult start() override
Start the exporter (for pull-based systems)
common::VoidResult export_snapshot(const metrics_snapshot &snapshot) override
Export a single metrics snapshot.
common::VoidResult shutdown() override
Shutdown the exporter.
common::VoidResult stop() override
Stop the exporter.
common::VoidResult flush() override
Flush any pending metrics.
Prometheus metric exporter implementation.
common::VoidResult flush() override
Flush any pending metrics.
std::string get_metrics_text() const
Get current metrics in Prometheus format (for HTTP endpoint)
std::unordered_map< std::string, std::size_t > get_stats() const override
Get exporter statistics.
std::vector< prometheus_metric_data > convert_snapshot(const metrics_snapshot &snapshot) const
Convert metrics_snapshot to Prometheus format.
common::VoidResult shutdown() override
Shutdown the exporter.
common::VoidResult export_snapshot(const metrics_snapshot &snapshot) override
Export a single metrics snapshot.
std::vector< prometheus_metric_data > convert_monitoring_data(const monitoring_data &data) const
Convert monitoring_data to Prometheus format.
common::VoidResult export_metrics(const std::vector< monitoring_data > &metrics) override
Export a batch of metrics.
Simple HTTP client using basic socket operations.
StatsD metric exporter implementation.
std::unordered_map< std::string, std::size_t > get_stats() const override
Get exporter statistics.
common::VoidResult shutdown() override
Shutdown the exporter.
common::VoidResult stop() override
Stop the exporter.
std::vector< statsd_metric_data > convert_snapshot(const metrics_snapshot &snapshot) const
Convert metrics_snapshot to StatsD format.
common::VoidResult start() override
Start the exporter (for pull-based systems)
common::VoidResult export_snapshot(const metrics_snapshot &snapshot) override
Export a single metrics snapshot.
common::VoidResult flush() override
Flush any pending metrics.
common::VoidResult export_metrics(const std::vector< monitoring_data > &metrics) override
Export a batch of metrics.
std::vector< statsd_metric_data > convert_monitoring_data(const monitoring_data &data) const
Convert monitoring_data to StatsD format.
gRPC transport layer for OTLP exporters
HTTP transport layer for trace exporters.
Metric data exporters for various monitoring and observability systems.
Interface for components that expose monitoring metrics.
Core monitoring system interface definitions.
metric_export_format
Supported metric export formats.
@ prometheus_text
Prometheus text exposition format.
std::unique_ptr< grpc_transport > create_default_grpc_transport()
Create default gRPC transport.
std::unique_ptr< stub_grpc_transport > create_stub_grpc_transport()
Create stub gRPC transport for testing.
std::unique_ptr< prometheus_exporter > create_prometheus_exporter(std::uint16_t port=9090, const std::string &job_name="monitoring_system")
Helper function to create a Prometheus exporter.
std::unique_ptr< stub_udp_transport > create_stub_udp_transport()
Create stub UDP transport for testing.
std::unique_ptr< udp_transport > create_default_udp_transport()
Create default UDP transport.
otel_resource create_service_resource(const std::string &service_name, const std::string &service_version="1.0.0", const std::string &service_namespace="")
Create OpenTelemetry resource with service information.
std::unique_ptr< otlp_metrics_exporter > create_otlp_metrics_exporter(const std::string &endpoint, const otel_resource &resource, metric_export_format format=metric_export_format::otlp_grpc)
Helper function to create an OTLP metrics exporter.
std::unique_ptr< stub_http_transport > create_stub_transport()
Create stub HTTP transport for testing.
std::unique_ptr< statsd_exporter > create_statsd_exporter(const std::string &host="localhost", std::uint16_t port=8125, bool datadog_format=false)
Helper function to create a StatsD exporter.
OpenTelemetry compatibility layer for monitoring system integration.
gRPC request configuration
std::chrono::milliseconds timeout
std::vector< uint8_t > body
std::vector< uint8_t > body
std::string status_message
HTTP request configuration.
Configuration for metric exporters.
std::unordered_map< std::string, std::string > labels
Default labels/tags.
std::size_t max_batch_size
Maximum metrics per batch.
std::chrono::milliseconds push_interval
Push interval for push-based systems.
std::string instance_id
Instance identifier.
std::uint16_t port
Port number (for UDP/TCP)
std::size_t max_queue_size
Maximum queued metrics.
metric_export_format format
std::string endpoint
Endpoint URL or address.
common::VoidResult validate() const
Validate export configuration.
Basic metric structure for interface compatibility.
std::chrono::system_clock::time_point timestamp
std::variant< double, int64_t, std::string > value
Complete snapshot of metrics at a point in time.
std::chrono::system_clock::time_point capture_time
std::vector< metric_value > metrics
void add_metric(const std::string &name, double value)
Add a metric to the snapshot.
Container for monitoring metrics from a component.
void add_metric(const std::string &key, double value)
Add a numeric metric.
void add_tag(const std::string &key, const std::string &value)
Add a tag (string metadata)
OpenTelemetry resource representation.
Prometheus-specific metric representation.
StatsD-specific metric representation.
std::unordered_map< std::string, std::string > tags
std::string to_statsd_format(bool datadog_format=false) const
Convert to StatsD format.
TEST(UdpTransportTest, StubTransportBasicFunctionality)
TEST_F(MetricExportersTest, MetricExportConfigValidation)
UDP transport layer for metric exporters.