Skip to content

Commit f6a1c55

Browse files
committed
feat: metric_exporter, metric_reader
draft version of metric reader and exporter
1 parent f59aa11 commit f6a1c55

File tree

12 files changed

+561
-0
lines changed

12 files changed

+561
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
classdef OtlpGrpcMetricExporter < opentelemetry.sdk.metrics.MetricExporter
2+
% OtlpGrpcMetricExporter exports Metrics in OpenTelemetry Protocol format via
3+
% gRPC. By default, it exports to the default address of the OpenTelemetry
4+
% Collector.
5+
6+
% Copyright 2023 The MathWorks, Inc.
7+
8+
properties (SetAccess=immutable)
9+
Endpoint (1,1) string % Export destination
10+
UseCredentials (1,1) logical % Whether to use SSL credentials
11+
CertificatePath (1,1) string % Path to .pem file for SSL encryption
12+
CertificateString (1,1) string % In-memory string representation of .pem file for SSL encryption
13+
Timeout (1,1) duration % Maximum time above which exports will abort
14+
HttpHeaders (1,1) dictionary % Additional HTTP headers
15+
end
16+
17+
methods
18+
function obj = OtlpGrpcMetricExporter(optionnames, optionvalues)
19+
% OtlpGrpcMetricExporter exports Metrics in OpenTelemetry Protocol format via gRPC.
20+
% EXP = OPENTELEMETRY.EXPORTERS.OTLP.OTLPGRPCMetricEXPORTER
21+
% creates an exporter that uses default configurations.
22+
%
23+
% EXP =
24+
% OPENTELEMETRY.EXPORTERS.OTLP.OTLPGRPCMetricEXPORTER(PARAM1,
25+
% VALUE1, PARAM2, VALUE2, ...) specifies optional parameter
26+
% name/value pairs. Parameters are:
27+
% "Endpoint" - Endpoint to export to
28+
% "UseCredentials" - Whether to use SSL credentials.
29+
% Default is false. If true, use
30+
% .pem file specified in
31+
% "CertificatePath" or
32+
% "CertificateString".
33+
% "CertificatePath" - Path to .pem file for SSL encryption
34+
% "CertificateString" - .pem file specified in memory as
35+
% a string
36+
% "Timeout" - Maximum time above which exports
37+
% will abort
38+
% "HTTPHeaders" - Additional HTTP Headers
39+
%
40+
% See also OPENTELEMETRY.EXPORTERS.OTLP.OTLPHTTPMetricEXPORTER
41+
arguments (Repeating)
42+
optionnames (1,:) {mustBeTextScalar}
43+
optionvalues
44+
end
45+
46+
validnames = ["Endpoint", "UseCredentials ", "CertificatePath", ...
47+
"CertificateString", "Timeout", "HttpHeaders"];
48+
% set default values to empty or negative
49+
endpoint = "";
50+
usessl = false;
51+
certificatepath = "";
52+
certificatestring = "";
53+
timeout_millis = -1;
54+
headerkeys = string.empty();
55+
headervalues = string.empty();
56+
for i = 1:length(optionnames)
57+
namei = validatestring(optionnames{i}, validnames);
58+
valuei = optionvalues{i};
59+
if strcmp(namei, "Endpoint")
60+
if ~(isStringScalar(valuei) || (ischar(valuei) && isrow(valuei)))
61+
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:EndpointNotScalarText", "Endpoint must be a scalar string.");
62+
end
63+
endpoint = string(valuei);
64+
elseif strcmp(namei, "UseCredentials ")
65+
if ~((islogical(valuei) || isnumeric(valuei)) && isscalar(valuei))
66+
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:UseCredentialsNotScalarLogical", "UseCredentials must be a scalar logical.")
67+
end
68+
usessl = logical(valuei);
69+
elseif strcmp(namei, "CertificatePath")
70+
if ~(isStringScalar(valuei) || (ischar(valuei) && isrow(valuei)))
71+
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:CertificatePathNotScalarText", "CertificatePath must be a scalar string.");
72+
end
73+
certificatepath = string(valuei);
74+
elseif strcmp(namei, "CertificateString")
75+
if ~(isStringScalar(valuei) || (ischar(valuei) && isrow(valuei)))
76+
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:CertificateStringNotScalarText", "CertificateString must be a scalar string.");
77+
end
78+
certificatestring = string(valuei);
79+
elseif strcmp(namei, "Timeout")
80+
if ~(isduration(valuei) && isscalar(valuei))
81+
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration.");
82+
end
83+
timeout = valuei;
84+
timeout_millis = milliseconds(timeout);
85+
else % HttpHeaders
86+
if ~isa(valuei, "dictionary")
87+
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary.");
88+
end
89+
httpheaders = valuei;
90+
headerkeys = keys(valuei);
91+
headervalues = values(valuei);
92+
if ~isstring(headervalues)
93+
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.")
94+
end
95+
end
96+
end
97+
98+
99+
"libmexclass.opentelemetry.exporters.OtlpGrpcMetricExporterProxy", ...
100+
endpoint, usessl, certificatepath, certificatestring, ...
101+
timeout_millis, headerkeys, headervalues);
102+
103+
% populate immutable properties
104+
[defaultendpoint, defaultcertpath, defaultcertstring, defaultmillis] = ...
105+
getDefaultOptionValues(obj);
106+
if endpoint == "" % not specified, use default value
107+
obj.Endpoint = defaultendpoint;
108+
else
109+
obj.Endpoint = endpoint;
110+
end
111+
obj.UseCredentials = usessl;
112+
if certificatepath == "" % not specified, use default value
113+
obj.CertificatePath = defaultcertpath;
114+
else
115+
obj.CertificatePath = certificatepath;
116+
end
117+
if certificatestring == "" % not specified, use default value
118+
obj.CertificateString = defaultcertstring;
119+
else
120+
obj.CertificateString = certificatestring;
121+
end
122+
if timeout_millis < 0 % not specified, use default value
123+
obj.Timeout = milliseconds(defaultmillis);
124+
else
125+
obj.Timeout = timeout;
126+
end
127+
if isempty(headerkeys) % not specified, return empty dictionary
128+
obj.HttpHeaders = dictionary(headerkeys, headervalues);
129+
else
130+
obj.HttpHeaders = httpheaders;
131+
end
132+
133+
end
134+
end
135+
end
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
classdef OtlpHttpMetricExporter < opentelemetry.sdk.metrics.MetricExporter
2+
% OtlpHttpMetricExporter exports Metrics in OpenTelemetry Protocol format via
3+
% HTTP. By default, it exports to the default address of the OpenTelemetry
4+
% Collector.
5+
6+
% Copyright 2023 The MathWorks, Inc.
7+
8+
properties (SetAccess=immutable)
9+
Endpoint (1,1) string % Export destination
10+
Format (1,1) string % Data format, JSON or binary
11+
JsonBytesMapping (1,1) string % What to convert JSON bytes to
12+
UseJsonName (1,1) logical % Whether to use JSON name of protobuf field to set the key of JSON
13+
Timeout (1,1) duration % Maximum time above which exports will abort
14+
HttpHeaders (1,1) dictionary % Additional HTTP headers
15+
end
16+
17+
methods
18+
function obj = OtlpHttpMetricExporter(optionnames, optionvalues)
19+
% OtlpHttpMetricExporter exports Metrics in OpenTelemetry Protocol format via HTTP.
20+
% EXP = OPENTELEMETRY.EXPORTERS.OTLP.OTLPHTTPMetricEXPORTER
21+
% creates an exporter that uses default configurations.
22+
%
23+
% EXP =
24+
% OPENTELEMETRY.EXPORTERS.OTLP.OTLPHTTPMetricEXPORTER(PARAM1,
25+
% VALUE1, PARAM2, VALUE2, ...) specifies optional parameter
26+
% name/value pairs. Parameters are:
27+
% "Endpoint" - Endpoint to export to
28+
% "Format" - Data format: "JSON" (default) or "binary"
29+
% "JsonBytesMapping" - What to convert JSON bytes to. Supported
30+
% values are "hex", "hexId" (default), and
31+
% "base64". Default "hexId"
32+
% converts to base 64 except for IDs
33+
% which are converted to hexadecimals.
34+
% "UseJsonName" - Whether to use JSON name of protobuf
35+
% field to set the key of JSON
36+
% "Timeout" - Maximum time above which exports
37+
% will abort
38+
% "HTTPHeaders" - Additional HTTP Headers
39+
%
40+
% See also OPENTELEMETRY.EXPORTERS.OTLP.OTLPGRPCMetricEXPORTER
41+
arguments (Repeating)
42+
optionnames (1,:) {mustBeTextScalar}
43+
optionvalues
44+
end
45+
46+
validnames = ["Endpoint", "Format", "JsonBytesMapping", ...
47+
"UseJsonName", "Timeout", "HttpHeaders"];
48+
% set default values to empty or negative
49+
endpoint = "";
50+
dataformat = "";
51+
jsonbytesmapping = "";
52+
usejsonname = false;
53+
timeout_millis = -1;
54+
headerkeys = string.empty();
55+
headervalues = string.empty();
56+
for i = 1:length(optionnames)
57+
namei = validatestring(optionnames{i}, validnames);
58+
valuei = optionvalues{i};
59+
if strcmp(namei, "Endpoint")
60+
if ~(isStringScalar(valuei) || (ischar(valuei) && isrow(valuei)))
61+
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:EndpointNotScalarText", "Endpoint must be a scalar string.");
62+
end
63+
endpoint = string(valuei);
64+
elseif strcmp(namei, "Format")
65+
dataformat = validatestring(valuei, ["JSON", "binary"]);
66+
elseif strcmp(namei, "JsonBytesMapping")
67+
jsonbytesmapping = validatestring(valuei, ["hex", "hexId", "base64"]);
68+
elseif strcmp(namei, "UseJsonName")
69+
if ~((islogical(valuei) || isnumeric(valuei)) && isscalar(valuei))
70+
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:UseJsonNameNotScalarLogical", "UseJsonName must be a scalar logical.")
71+
end
72+
usejsonname = logical(valuei);
73+
elseif strcmp(namei, "Timeout")
74+
if ~(isduration(valuei) && isscalar(valuei))
75+
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration.");
76+
end
77+
timeout = valuei;
78+
timeout_millis = milliseconds(timeout);
79+
else % HttpHeaders
80+
if ~isa(valuei, "dictionary")
81+
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary.");
82+
end
83+
httpheaders = valuei;
84+
headerkeys = keys(valuei);
85+
headervalues = values(valuei);
86+
if ~isstring(headervalues)
87+
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.")
88+
end
89+
end
90+
end
91+
92+
93+
"libmexclass.opentelemetry.exporters.OtlpHttpMetricExporterProxy", ...
94+
endpoint, dataformat, jsonbytesmapping, usejsonname, ...
95+
timeout_millis, headerkeys, headervalues);
96+
97+
% populate immutable properties
98+
if endpoint == "" || dataformat == "" || jsonbytesmapping == "" || ...
99+
timeout_millis < 0
100+
[defaultendpoint, defaultformat, defaultmapping, defaultmillis] = ...
101+
getDefaultOptionValues(obj);
102+
end
103+
if endpoint == "" % not specified, use default value
104+
obj.Endpoint = defaultendpoint;
105+
else
106+
obj.Endpoint = endpoint;
107+
end
108+
if dataformat == "" % not specified, use default value
109+
obj.Format = defaultformat;
110+
else
111+
obj.Format = dataformat;
112+
end
113+
if jsonbytesmapping == "" % not specified, use default value
114+
obj.JsonBytesMapping = defaultmapping;
115+
else
116+
obj.JsonBytesMapping = jsonbytesmapping;
117+
end
118+
obj.UseJsonName = usejsonname;
119+
if timeout_millis < 0 % not specified, use default value
120+
obj.Timeout = milliseconds(defaultmillis);
121+
else
122+
obj.Timeout = timeout;
123+
end
124+
if isempty(headerkeys) % not specified, return empty dictionary
125+
obj.HttpHeaders = dictionary(headerkeys, headervalues);
126+
else
127+
obj.HttpHeaders = httpheaders;
128+
end
129+
end
130+
end
131+
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function dexp = defaultMetricExporter
2+
% Get the default Metric exporter depending on installation
3+
% EXP = OPENTELEMETRY.EXPORTERS.OTLP.DEFAULTMetricEXPORTER returns the
4+
% default Metric exporter. OtlpHttpMetricExporter is the default if it is
5+
% installed. Otherwise, OtlpGrpcMetricExporter is the default.
6+
%
7+
% See also OPENTELEMETRY.EXPORTERS.OTLP.OTLPHTTPMetricEXPORTER,
8+
% OPENTELEMETRY.EXPORTERS.OTLP.OTLPGRPCMetricEXPORTER
9+
10+
% Copyright 2023 The MathWorks, Inc.
11+
12+
if exist("opentelemetry.exporters.otlp.OtlpHttpMetricExporter", "class")
13+
dexp = opentelemetry.exporters.otlp.OtlpHttpMetricExporter;
14+
else
15+
dexp = opentelemetry.exporters.otlp.OtlpGrpcMetricExporter;
16+
end
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2023 The MathWorks, Inc.
2+
3+
#pragma once
4+
5+
#include "opentelemetry-matlab/sdk/metrics/MetricExporterProxy.h"
6+
7+
#include "libmexclass/proxy/Proxy.h"
8+
#include "libmexclass/proxy/method/Context.h"
9+
10+
#include "opentelemetry/sdk/metrics/push_metric_exporter.h"
11+
#include "opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h"
12+
13+
namespace metric_sdk = opentelemetry::sdk::metric;
14+
namespace otlp_exporter = opentelemetry::exporter::otlp;
15+
16+
namespace libmexclass::opentelemetry::exporters {
17+
class OtlpGrpcMetricExporterProxy: public libmexclass::opentelemetry::sdk::MetricExporterProxy {
18+
public:
19+
OtlpGrpcMetricExporterProxy(otlp_exporter::OtlpGrpcExporterOptions options) : CppOptions(options) {
20+
REGISTER_METHOD(OtlpGrpcMetricExporterProxy, getDefaultOptionValues);
21+
}
22+
23+
static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments);
24+
25+
std::unique_ptr<metric_sdk::MetricExporter> getInstance() override;
26+
27+
void getDefaultOptionValues(libmexclass::proxy::method::Context& context);
28+
29+
private:
30+
otlp_exporter::OtlpGrpcExporterOptions CppOptions;
31+
};
32+
} // namespace libmexclass::opentelemetry
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2023 The MathWorks, Inc.
2+
3+
#pragma once
4+
5+
#include "opentelemetry-matlab/sdk/metrics/MetricExporterProxy.h"
6+
7+
#include "libmexclass/proxy/Proxy.h"
8+
#include "libmexclass/proxy/method/Context.h"
9+
10+
#include "opentelemetry/sdk/metrics/push_metric_exporter.h"
11+
#include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h"
12+
13+
namespace metric_sdk = opentelemetry::sdk::metrics;
14+
namespace otlp_exporter = opentelemetry::exporter::otlp;
15+
16+
namespace libmexclass::opentelemetry::exporters {
17+
class OtlpHttpMetricExporterProxy: public libmexclass::opentelemetry::sdk::MetricExporterProxy {
18+
public:
19+
OtlpHttpMetricExporterProxy(otlp_exporter::OtlpHttpExporterOptions options) : CppOptions(options) {
20+
REGISTER_METHOD(OtlpHttpMetricExporterProxy, getDefaultOptionValues);
21+
}
22+
23+
static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments);
24+
25+
std::unique_ptr<metric_sdk::PushMetricExporter> getInstance() override;
26+
27+
void getDefaultOptionValues(libmexclass::proxy::method::Context& context);
28+
29+
private:
30+
otlp_exporter::OtlpHttpExporterOptions CppOptions;
31+
};
32+
} // namespace libmexclass::opentelemetry

0 commit comments

Comments
 (0)
close