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

OpenTelemetry Protocol (OTLP) metrics exporter implementation. More...

#include <metric_exporters.h>

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

Public Member Functions

 otlp_metrics_exporter (const metric_export_config &config, const otel_resource &resource)
 Construct OTLP exporter with default transports.
 
 otlp_metrics_exporter (const metric_export_config &config, const otel_resource &resource, std::unique_ptr< http_transport > http_transport, std::unique_ptr< grpc_transport > grpc_transport)
 Construct OTLP exporter with custom transports.
 
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

bool is_grpc_protocol () const
 
bool is_http_protocol () const
 
std::string get_content_type () const
 
common::VoidResult send_otlp_batch (const std::vector< otel_metric_data > &metrics)
 
common::VoidResult send_via_http (const std::vector< otel_metric_data > &metrics)
 
common::VoidResult send_via_grpc (const std::vector< otel_metric_data > &metrics)
 
std::vector< uint8_t > serialize_metrics (const std::vector< otel_metric_data > &metrics) const
 

Private Attributes

metric_export_config config_
 
std::unique_ptr< opentelemetry_metrics_adapterotel_adapter_
 
std::unique_ptr< http_transporthttp_transport_
 
std::unique_ptr< grpc_transportgrpc_transport_
 
std::atomic< std::size_t > exported_metrics_ {0}
 
std::atomic< std::size_t > failed_exports_ {0}
 
bool started_ {false}
 

Detailed Description

OpenTelemetry Protocol (OTLP) metrics exporter implementation.

Exports metrics to OTLP-compatible backends via gRPC or HTTP. Supports OTLP/gRPC, OTLP/HTTP JSON, and OTLP/HTTP Protobuf formats.

Definition at line 795 of file metric_exporters.h.

Constructor & Destructor Documentation

◆ otlp_metrics_exporter() [1/2]

kcenon::monitoring::otlp_metrics_exporter::otlp_metrics_exporter ( const metric_export_config & config,
const otel_resource & resource )
inlineexplicit

Construct OTLP exporter with default transports.

Parameters
configExport configuration with endpoint and protocol
resourceOpenTelemetry resource attributes

Definition at line 811 of file metric_exporters.h.

812 : config_(config)
813 , otel_adapter_(std::make_unique<opentelemetry_metrics_adapter>(resource))
std::unique_ptr< grpc_transport > grpc_transport_
std::unique_ptr< opentelemetry_metrics_adapter > otel_adapter_
std::unique_ptr< http_transport > http_transport_
std::unique_ptr< grpc_transport > create_default_grpc_transport()
Create default gRPC transport.
std::unique_ptr< http_transport > create_default_transport()
Create default HTTP transport.

◆ otlp_metrics_exporter() [2/2]

kcenon::monitoring::otlp_metrics_exporter::otlp_metrics_exporter ( const metric_export_config & config,
const otel_resource & resource,
std::unique_ptr< http_transport > http_transport,
std::unique_ptr< grpc_transport > grpc_transport )
inline

Construct OTLP exporter with custom transports.

Parameters
configExport configuration
resourceOpenTelemetry resource attributes
http_transportCustom HTTP transport (for OTLP/HTTP)
grpc_transportCustom gRPC transport (for OTLP/gRPC)

Definition at line 824 of file metric_exporters.h.

828 : config_(config)
829 , otel_adapter_(std::make_unique<opentelemetry_metrics_adapter>(resource))
830 , http_transport_(std::move(http_transport))
831 , grpc_transport_(std::move(grpc_transport)) {}

Member Function Documentation

◆ export_metrics()

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

Export a batch of metrics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 833 of file metric_exporters.h.

833 {
834 try {
835 for (const auto& data : metrics) {
836 // Convert to OpenTelemetry format
837 auto otel_result = otel_adapter_->convert_monitoring_data(data);
838 if (otel_result.is_err()) {
840 return common::VoidResult::err(error_info(monitoring_error_code::processing_failed,
841 "Failed to convert metrics to OTEL format: " + otel_result.error().message, "monitoring_system").to_common_error());
842 }
843
844 const auto& otel_metrics = otel_result.value();
845
846 // Send via appropriate OTLP protocol
847 auto send_result = send_otlp_batch(otel_metrics);
848 if (send_result.is_err()) {
850 return send_result;
851 }
852 }
853
854 exported_metrics_ += metrics.size();
855 return common::ok();
856
857 } catch (const std::exception& e) {
859 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
860 "OTLP metrics export failed: " + std::string(e.what()), "monitoring_system").to_common_error());
861 }
862 }
std::atomic< std::size_t > exported_metrics_
common::VoidResult send_otlp_batch(const std::vector< otel_metric_data > &metrics)

References exported_metrics_, failed_exports_, kcenon::monitoring::operation_failed, otel_adapter_, kcenon::monitoring::processing_failed, send_otlp_batch(), and kcenon::monitoring::error_info::to_common_error().

Referenced by 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::otlp_metrics_exporter::export_snapshot ( const metrics_snapshot & snapshot)
inlineoverridevirtual

Export a single metrics snapshot.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 864 of file metric_exporters.h.

864 {
865 try {
866 // Convert to OpenTelemetry format
867 auto otel_result = otel_adapter_->convert_metrics(snapshot);
868 if (otel_result.is_err()) {
870 return common::VoidResult::err(error_info(monitoring_error_code::processing_failed,
871 "Failed to convert snapshot to OTEL format: " + otel_result.error().message, "monitoring_system").to_common_error());
872 }
873
874 const auto& otel_metrics = otel_result.value();
875
876 // Send via appropriate OTLP protocol
877 auto send_result = send_otlp_batch(otel_metrics);
878 if (send_result.is_err()) {
880 return send_result;
881 }
882
884 return common::ok();
885
886 } catch (const std::exception& e) {
888 return common::VoidResult::err(error_info(monitoring_error_code::operation_failed,
889 "OTLP snapshot export failed: " + std::string(e.what()), "monitoring_system").to_common_error());
890 }
891 }

References exported_metrics_, failed_exports_, kcenon::monitoring::operation_failed, otel_adapter_, kcenon::monitoring::processing_failed, send_otlp_batch(), 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::otlp_metrics_exporter::flush ( )
inlineoverridevirtual

Flush any pending metrics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 917 of file metric_exporters.h.

917 {
918 // OTLP exporter typically sends immediately, so flush is a no-op
919 return common::ok();
920 }

Referenced by TEST_F().

Here is the caller graph for this function:

◆ get_content_type()

std::string kcenon::monitoring::otlp_metrics_exporter::get_content_type ( ) const
inlineprivate

Definition at line 953 of file metric_exporters.h.

953 {
954 switch (config_.format) {
956 return "application/json";
958 return "application/x-protobuf";
959 default:
960 return "application/json";
961 }
962 }
@ otlp_http_json
OTLP HTTP JSON metrics protocol.
@ otlp_http_protobuf
OTLP HTTP Protocol Buffers metrics.

References config_, kcenon::monitoring::metric_export_config::format, kcenon::monitoring::otlp_http_json, and kcenon::monitoring::otlp_http_protobuf.

Referenced by send_via_http().

Here is the caller graph for this function:

◆ get_stats()

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

Get exporter statistics.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 926 of file metric_exporters.h.

926 {
927 std::unordered_map<std::string, std::size_t> stats = {
928 {"exported_metrics", exported_metrics_.load()},
929 {"failed_exports", failed_exports_.load()}
930 };
931
932 // Add transport statistics based on protocol
934 auto transport_stats = grpc_transport_->get_statistics();
935 stats["transport_requests_sent"] = transport_stats.requests_sent;
936 stats["transport_bytes_sent"] = transport_stats.bytes_sent;
937 stats["transport_send_failures"] = transport_stats.send_failures;
938 }
939
940 return stats;
941 }

References exported_metrics_, failed_exports_, grpc_transport_, and is_grpc_protocol().

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

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

◆ is_grpc_protocol()

bool kcenon::monitoring::otlp_metrics_exporter::is_grpc_protocol ( ) const
inlineprivate

Definition at line 944 of file metric_exporters.h.

944 {
946 }
@ otlp_grpc
OTLP gRPC metrics protocol.

References config_, kcenon::monitoring::metric_export_config::format, and kcenon::monitoring::otlp_grpc.

Referenced by get_stats(), and send_otlp_batch().

Here is the caller graph for this function:

◆ is_http_protocol()

bool kcenon::monitoring::otlp_metrics_exporter::is_http_protocol ( ) const
inlineprivate

◆ send_otlp_batch()

common::VoidResult kcenon::monitoring::otlp_metrics_exporter::send_otlp_batch ( const std::vector< otel_metric_data > & metrics)
inlineprivate

Definition at line 964 of file metric_exporters.h.

964 {
965 if (is_grpc_protocol()) {
966 return send_via_grpc(metrics);
967 } else {
968 return send_via_http(metrics);
969 }
970 }
common::VoidResult send_via_http(const std::vector< otel_metric_data > &metrics)
common::VoidResult send_via_grpc(const std::vector< otel_metric_data > &metrics)

References is_grpc_protocol(), send_via_grpc(), and send_via_http().

Referenced by export_metrics(), and export_snapshot().

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

◆ send_via_grpc()

common::VoidResult kcenon::monitoring::otlp_metrics_exporter::send_via_grpc ( const std::vector< otel_metric_data > & metrics)
inlineprivate

Definition at line 1024 of file metric_exporters.h.

1024 {
1025 if (!grpc_transport_) {
1026 return common::VoidResult::err(error_info(
1028 "gRPC transport not available",
1029 "otlp_metrics_exporter"
1030 ).to_common_error());
1031 }
1032
1033 // Connect if not already connected
1034 if (!grpc_transport_->is_connected()) {
1035 auto connect_result = grpc_transport_->connect(config_.endpoint, config_.port);
1036 if (connect_result.is_err()) {
1037 return connect_result;
1038 }
1039 }
1040
1041 // Serialize metrics to protobuf
1042 std::vector<uint8_t> body = serialize_metrics(metrics);
1043
1044 grpc_request request;
1045 request.service = "opentelemetry.proto.collector.metrics.v1.MetricsService";
1046 request.method = "Export";
1047 request.body = std::move(body);
1048 request.timeout = config_.timeout;
1049
1050 auto result = grpc_transport_->send(request);
1051 if (result.is_err()) {
1052 return common::VoidResult::err(error_info(
1054 "gRPC send failed: " + result.error().message,
1055 "otlp_metrics_exporter"
1056 ).to_common_error());
1057 }
1058
1059 const auto& response = result.value();
1060 if (response.status_code != 0) { // gRPC OK is 0
1061 return common::VoidResult::err(error_info(
1063 "OTLP gRPC request failed: " + response.status_message,
1064 "otlp_metrics_exporter"
1065 ).to_common_error());
1066 }
1067
1068 return common::ok();
1069 }
std::vector< uint8_t > serialize_metrics(const std::vector< otel_metric_data > &metrics) const
std::uint16_t port
Port number (for UDP/TCP)
std::string endpoint
Endpoint URL or address.
std::chrono::milliseconds timeout
Request timeout.

References kcenon::monitoring::grpc_request::body, config_, kcenon::monitoring::dependency_missing, kcenon::monitoring::metric_export_config::endpoint, grpc_transport_, kcenon::monitoring::grpc_request::method, kcenon::monitoring::network_error, kcenon::monitoring::operation_failed, kcenon::monitoring::metric_export_config::port, serialize_metrics(), kcenon::monitoring::grpc_request::service, kcenon::monitoring::grpc_request::timeout, kcenon::monitoring::metric_export_config::timeout, and kcenon::monitoring::error_info::to_common_error().

Referenced by send_otlp_batch().

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

◆ send_via_http()

common::VoidResult kcenon::monitoring::otlp_metrics_exporter::send_via_http ( const std::vector< otel_metric_data > & metrics)
inlineprivate

Definition at line 972 of file metric_exporters.h.

972 {
973 if (!http_transport_) {
974 return common::VoidResult::err(error_info(
976 "HTTP transport not available",
977 "otlp_metrics_exporter"
978 ).to_common_error());
979 }
980
981 // Build OTLP HTTP endpoint
982 std::string endpoint = config_.endpoint;
983 if (config_.port != 0) {
984 endpoint += ":" + std::to_string(config_.port);
985 }
986 endpoint += "/v1/metrics";
987
988 // Serialize metrics to JSON or Protobuf
989 std::vector<uint8_t> body = serialize_metrics(metrics);
990
991 http_request request;
992 request.url = endpoint;
993 request.method = "POST";
994 request.headers["Content-Type"] = get_content_type();
995 request.body = std::move(body);
996 request.timeout = config_.timeout;
997
998 // Add custom headers
999 for (const auto& [key, value] : config_.headers) {
1000 request.headers[key] = value;
1001 }
1002
1003 auto result = http_transport_->send(request);
1004 if (result.is_err()) {
1005 return common::VoidResult::err(error_info(
1007 "HTTP send failed: " + result.error().message,
1008 "otlp_metrics_exporter"
1009 ).to_common_error());
1010 }
1011
1012 const auto& response = result.value();
1013 if (response.status_code < 200 || response.status_code >= 300) {
1014 return common::VoidResult::err(error_info(
1016 "OTLP HTTP request failed with status " + std::to_string(response.status_code),
1017 "otlp_metrics_exporter"
1018 ).to_common_error());
1019 }
1020
1021 return common::ok();
1022 }
std::unordered_map< std::string, std::string > headers
Custom HTTP headers.

References kcenon::monitoring::http_request::body, config_, kcenon::monitoring::dependency_missing, kcenon::monitoring::metric_export_config::endpoint, get_content_type(), kcenon::monitoring::http_request::headers, kcenon::monitoring::metric_export_config::headers, http_transport_, kcenon::monitoring::http_request::method, kcenon::monitoring::network_error, kcenon::monitoring::operation_failed, kcenon::monitoring::metric_export_config::port, serialize_metrics(), kcenon::monitoring::http_request::timeout, kcenon::monitoring::metric_export_config::timeout, kcenon::monitoring::error_info::to_common_error(), and kcenon::monitoring::http_request::url.

Referenced by send_otlp_batch().

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

◆ serialize_metrics()

std::vector< uint8_t > kcenon::monitoring::otlp_metrics_exporter::serialize_metrics ( const std::vector< otel_metric_data > & metrics) const
inlineprivate

Definition at line 1071 of file metric_exporters.h.

1071 {
1072 // Serialize metrics based on format
1073 // For JSON format, convert to JSON string
1074 // For protobuf format, serialize to protobuf bytes
1075 // This is a simplified implementation
1076 std::string json = "{\"resourceMetrics\":[";
1077
1078 bool first = true;
1079 for (const auto& metric : metrics) {
1080 if (!first) json += ",";
1081 first = false;
1082
1083 json += "{\"resource\":{},\"scopeMetrics\":[{\"metrics\":[{";
1084 json += "\"name\":\"" + metric.name + "\",";
1085 json += "\"gauge\":{\"dataPoints\":[{\"asDouble\":" +
1086 std::to_string(metric.value) + "}]}";
1087 json += "}]}]}";
1088 }
1089
1090 json += "]}";
1091
1092 return std::vector<uint8_t>(json.begin(), json.end());
1093 }

References kcenon::monitoring::metric::name, and kcenon::monitoring::metric::value.

Referenced by send_via_grpc(), and send_via_http().

Here is the caller graph for this function:

◆ shutdown()

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

Shutdown the exporter.

Implements kcenon::monitoring::metric_exporter_interface.

Definition at line 922 of file metric_exporters.h.

922 {
923 return stop();
924 }
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::otlp_metrics_exporter::start ( )
inlineoverridevirtual

Start the exporter (for pull-based systems)

Reimplemented from kcenon::monitoring::metric_exporter_interface.

Definition at line 893 of file metric_exporters.h.

893 {
894 if (started_) {
895 return common::ok();
896 }
897
898 // gRPC transport connection is managed per-request
899 // HTTP transport is stateless
900 started_ = true;
901 return common::ok();
902 }

References started_.

Referenced by TEST_F().

Here is the caller graph for this function:

◆ stop()

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

Stop the exporter.

Reimplemented from kcenon::monitoring::metric_exporter_interface.

Definition at line 904 of file metric_exporters.h.

904 {
905 if (!started_) {
906 return common::ok();
907 }
908
909 if (grpc_transport_) {
910 grpc_transport_->disconnect();
911 }
912
913 started_ = false;
914 return common::ok();
915 }

References grpc_transport_, and started_.

Referenced by shutdown(), and TEST_F().

Here is the caller graph for this function:

Member Data Documentation

◆ config_

metric_export_config kcenon::monitoring::otlp_metrics_exporter::config_
private

◆ exported_metrics_

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

Definition at line 801 of file metric_exporters.h.

801{0};

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

◆ failed_exports_

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

Definition at line 802 of file metric_exporters.h.

802{0};

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

◆ grpc_transport_

std::unique_ptr<grpc_transport> kcenon::monitoring::otlp_metrics_exporter::grpc_transport_
private

Definition at line 800 of file metric_exporters.h.

Referenced by get_stats(), send_via_grpc(), and stop().

◆ http_transport_

std::unique_ptr<http_transport> kcenon::monitoring::otlp_metrics_exporter::http_transport_
private

Definition at line 799 of file metric_exporters.h.

Referenced by send_via_http().

◆ otel_adapter_

std::unique_ptr<opentelemetry_metrics_adapter> kcenon::monitoring::otlp_metrics_exporter::otel_adapter_
private

Definition at line 798 of file metric_exporters.h.

Referenced by export_metrics(), and export_snapshot().

◆ started_

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

Definition at line 803 of file metric_exporters.h.

803{false};

Referenced by start(), and stop().


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