Skip to content

Commit

Permalink
Merge pull request #61 from mathworks/metrics_merge
Browse files Browse the repository at this point in the history
refactor exporter code to enable more code sharing and remove duplications
  • Loading branch information
duncanpo authored Nov 16, 2023
2 parents 9185f37 + 1e27933 commit 65c04b4
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 123 deletions.
13 changes: 8 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -399,15 +399,18 @@ set(COMMON_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/common/+openteleme
set(TRACE_SDK_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sdk/trace/+opentelemetry)
set(METRICS_SDK_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sdk/metrics/+opentelemetry)
set(COMMON_SDK_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sdk/common/+opentelemetry)
set(DEFAULT_EXPORTER_MATLAB_SOURCES
set(EXPORTER_MATLAB_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/defaultSpanExporter.m
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/defaultMetricExporter.m)
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/defaultMetricExporter.m
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpValidator.m)
set(OTLP_HTTP_EXPORTER_MATLAB_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpSpanExporter.m
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpMetricExporter.m)
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpMetricExporter.m
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpValidator.m)
set(OTLP_GRPC_EXPORTER_MATLAB_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcSpanExporter.m
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcMetricExporter.m)
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcMetricExporter.m
${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcValidator.m)

set(OTLP_EXPORTERS_DIR +opentelemetry/+exporters/+otlp)

Expand All @@ -419,7 +422,7 @@ install(DIRECTORY ${COMMON_API_MATLAB_SOURCES} DESTINATION .)
install(DIRECTORY ${TRACE_SDK_MATLAB_SOURCES} DESTINATION .)
install(DIRECTORY ${METRICS_SDK_MATLAB_SOURCES} DESTINATION .)
install(DIRECTORY ${COMMON_SDK_MATLAB_SOURCES} DESTINATION .)
install(FILES ${DEFAULT_EXPORTER_MATLAB_SOURCES} DESTINATION ${OTLP_EXPORTERS_DIR})
install(FILES ${EXPORTER_MATLAB_SOURCES} DESTINATION ${OTLP_EXPORTERS_DIR})
if(WITH_OTLP_HTTP)
install(FILES ${OTLP_HTTP_EXPORTER_MATLAB_SOURCES} DESTINATION ${OTLP_EXPORTERS_DIR})
endif()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
CertificateString (1,1) string = "" % In-memory string representation of .pem file for SSL encryption
Timeout (1,1) duration = seconds(10) % Maximum time above which exports will abort
HttpHeaders (1,1) dictionary = dictionary(string.empty, string.empty) % Additional HTTP headers
PreferredAggregationTemporality (1,1) string = "cumulative" % Preferred Aggregation Temporality
end

properties (Constant)
Validator = opentelemetry.exporters.otlp.OtlpGrpcValidator
end

methods
Expand Down Expand Up @@ -60,66 +63,39 @@
end

function obj = set.Endpoint(obj, ep)
if ~(isStringScalar(ep) || (ischar(ep) && isrow(ep)))
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:EndpointNotScalarText", "Endpoint must be a scalar string.");
end
ep = string(ep);
ep = obj.Validator.validateEndpoint(ep);
obj.Proxy.setEndpoint(ep);
obj.Endpoint = ep;
end

function obj = set.UseCredentials(obj, uc)
if ~((islogical(uc) || isnumeric(uc)) && isscalar(uc))
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:UseCredentialsNotScalarLogical", "UseCredentials must be a scalar logical.")
end
uc = logical(uc);
uc = obj.Validator.validateUseCredentials(uc);
obj.Proxy.setUseCredentials(uc);
obj.UseCredentials = uc;
end

function obj = set.CertificatePath(obj, certpath)
if ~(isStringScalar(certpath) || (ischar(certpath) && isrow(certpath)))
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:CertificatePathNotScalarText", "CertificatePath must be a scalar string.");
end
certpath = string(certpath);
certpath = obj.Validator.validateCertificatePath(certpath);
obj.Proxy.setCertificatePath(certpath);
obj.CertificatePath = certpath;
end

function obj = set.CertificateString(obj, certstr)
if ~(isStringScalar(certstr) || (ischar(certstr) && isrow(certstr)))
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:CertificateStringNotScalarText", "CertificateString must be a scalar string.");
end
certstr = string(certstr);
certstr = obj.Validator.validateCertificateString(certstr);
obj.Proxy.setCertificateString(certstr);
obj.CertificateString = certstr;
end

function obj = set.Timeout(obj, timeout)
if ~(isduration(timeout) && isscalar(timeout))
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration.");
end
obj.Validator.validateTimeout(timeout);
obj.Proxy.setTimeout(milliseconds(timeout));
obj.Timeout = timeout;
end

function obj = set.HttpHeaders(obj, httpheaders)
if ~isa(httpheaders, "dictionary")
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary.");
end
headerkeys = keys(httpheaders);
headervalues = values(httpheaders);
if ~isstring(headervalues)
error("opentelemetry:exporters:otlp:OtlpGrpcMetricExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.")
end
[headerkeys, headervalues] = obj.Validator.validateHttpHeaders(httpheaders);
obj.Proxy.setHttpHeaders(headerkeys, headervalues);
obj.HttpHeaders = httpheaders;
end

function obj = set.PreferredAggregationTemporality(obj, temporality)
temporality = validatestring(temporality, ["cumulative", "delta"]);
obj.Proxy.setTemporality(temporality);
obj.PreferredAggregationTemporality = temporality;
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
HttpHeaders (1,1) dictionary = dictionary(string.empty, string.empty) % Additional HTTP headers
end

properties (Constant)
Validator = opentelemetry.exporters.otlp.OtlpGrpcValidator
end

methods
function obj = OtlpGrpcSpanExporter(optionnames, optionvalues)
% OtlpGrpcSpanExporter exports spans in OpenTelemetry Protocol format via gRPC.
Expand Down Expand Up @@ -56,58 +60,37 @@
end

function obj = set.Endpoint(obj, ep)
if ~(isStringScalar(ep) || (ischar(ep) && isrow(ep)))
error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:EndpointNotScalarText", "Endpoint must be a scalar string.");
end
ep = string(ep);
ep = obj.Validator.validateEndpoint(ep);
obj.Proxy.setEndpoint(ep);
obj.Endpoint = ep;
end

function obj = set.UseCredentials(obj, uc)
if ~((islogical(uc) || isnumeric(uc)) && isscalar(uc))
error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:UseCredentialsNotScalarLogical", "UseCredentials must be a scalar logical.")
end
uc = logical(uc);
uc = obj.Validator.validateUseCredentials(uc);
obj.Proxy.setUseCredentials(uc);
obj.UseCredentials = uc;
end

function obj = set.CertificatePath(obj, certpath)
if ~(isStringScalar(certpath) || (ischar(certpath) && isrow(certpath)))
error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:CertificatePathNotScalarText", "CertificatePath must be a scalar string.");
end
certpath = string(certpath);
certpath = obj.Validator.validateCertificatePath(certpath);
obj.Proxy.setCertificatePath(certpath);
obj.CertificatePath = certpath;
end

function obj = set.CertificateString(obj, certstr)
if ~(isStringScalar(certstr) || (ischar(certstr) && isrow(certstr)))
error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:CertificateStringNotScalarText", "CertificateString must be a scalar string.");
end
certstr = string(certstr);
certstr = obj.Validator.validateCertificateString(certstr);
obj.Proxy.setCertificateString(certstr);
obj.CertificateString = certstr;
end

function obj = set.Timeout(obj, timeout)
if ~(isduration(timeout) && isscalar(timeout))
error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration.");
end
obj.Validator.validateTimeout(timeout);
obj.Proxy.setTimeout(milliseconds(timeout));
obj.Timeout = timeout;
end

function obj = set.HttpHeaders(obj, httpheaders)
if ~isa(httpheaders, "dictionary")
error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary.");
end
headerkeys = keys(httpheaders);
headervalues = values(httpheaders);
if ~isstring(headervalues)
error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.")
end
[headerkeys, headervalues] = obj.Validator.validateHttpHeaders(httpheaders);
obj.Proxy.setHttpHeaders(headerkeys, headervalues);
obj.HttpHeaders = httpheaders;
end
Expand Down
32 changes: 32 additions & 0 deletions exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcValidator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
classdef OtlpGrpcValidator < opentelemetry.exporters.otlp.OtlpValidator
% OtlpGrpcValidator Validate options inputs for OtlpGrpcSpanExporter and
% OtlpGrpcMetricExporter

% Copyright 2023 The MathWorks, Inc.

methods (Static)
function uc = validateUseCredentials(uc)
if ~((islogical(uc) || isnumeric(uc)) && isscalar(uc))
error("opentelemetry:exporters:otlp:OtlpGrpcValidator:UseCredentialsNotScalarLogical", ...
"UseCredentials must be a scalar logical.")
end
uc = logical(uc);
end

function certpath = validateCertificatePath(certpath)
if ~(isStringScalar(certpath) || (ischar(certpath) && isrow(certpath)))
error("opentelemetry:exporters:otlp:OtlpGrpcValidator:CertificatePathNotScalarText", ...
"CertificatePath must be a scalar string.");
end
certpath = string(certpath);
end

function certstr = validateCertificateString(certstr)
if ~(isStringScalar(certstr) || (ischar(certstr) && isrow(certstr)))
error("opentelemetry:exporters:otlp:OtlpGrpcValidator:CertificateStringNotScalarText", ...
"CertificateString must be a scalar string.");
end
certstr = string(certstr);
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
UseJsonName (1,1) logical = false % Whether to use JSON name of protobuf field to set the key of JSON
Timeout (1,1) duration = seconds(10) % Maximum time above which exports will abort
HttpHeaders (1,1) dictionary = dictionary(string.empty, string.empty) % Additional HTTP headers
PreferredAggregationTemporality (1,1) string = "cumulative" % Preferred Aggregation Temporality
end

properties (Constant)
Validator = opentelemetry.exporters.otlp.OtlpHttpValidator
end

methods
Expand Down Expand Up @@ -60,60 +63,39 @@
end

function obj = set.Endpoint(obj, ep)
if ~(isStringScalar(ep) || (ischar(ep) && isrow(ep)))
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:EndpointNotScalarText", "Endpoint must be a scalar string.");
end
ep = string(ep);
ep = obj.Validator.validateEndpoint(ep);
obj.Proxy.setEndpoint(ep);
obj.Endpoint = ep;
end

function obj = set.Format(obj, newformat)
newformat = validatestring(newformat, ["JSON", "binary"]);
newformat = obj.Validator.validateFormat(newformat);
obj.Proxy.setFormat(newformat);
obj.Format = newformat;
end

function obj = set.JsonBytesMapping(obj, jbm)
jbm = validatestring(jbm, ["hex", "hexId", "base64"]);
jbm = obj.Validator.validateJsonBytesMapping(jbm);
obj.Proxy.setJsonBytesMapping(jbm);
obj.JsonBytesMapping = jbm;
end

function obj = set.UseJsonName(obj, ujn)
if ~((islogical(ujn) || isnumeric(ujn)) && isscalar(ujn))
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:UseJsonNameNotScalarLogical", "UseJsonName must be a scalar logical.")
end
ujn = logical(ujn);
ujn = obj.Validator.validateUseJsonName(ujn);
obj.Proxy.setUseJsonName(ujn);
obj.UseJsonName = ujn;
end

function obj = set.Timeout(obj, timeout)
if ~(isduration(timeout) && isscalar(timeout))
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration.");
end
obj.Validator.validateTimeout(timeout);
obj.Proxy.setTimeout(milliseconds(timeout));
obj.Timeout = timeout;
end

function obj = set.HttpHeaders(obj, httpheaders)
if ~isa(httpheaders, "dictionary")
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary.");
end
headerkeys = keys(httpheaders);
headervalues = values(httpheaders);
if ~isstring(headervalues)
error("opentelemetry:exporters:otlp:OtlpHttpMetricExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.")
end
[headerkeys, headervalues] = obj.Validator.validateHttpHeaders(httpheaders);
obj.Proxy.setHttpHeaders(headerkeys, headervalues);
obj.HttpHeaders = httpheaders;
end

function obj = set.PreferredAggregationTemporality(obj, temporality)
temporality = validatestring(temporality, ["cumulative", "delta"]);
obj.Proxy.setTemporality(temporality);
obj.PreferredAggregationTemporality = temporality;
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
HttpHeaders (1,1) dictionary = dictionary(string.empty, string.empty) % Additional HTTP headers
end

properties (Constant)
Validator = opentelemetry.exporters.otlp.OtlpHttpValidator
end

methods
function obj = OtlpHttpSpanExporter(optionnames, optionvalues)
% OtlpHttpSpanExporter exports spans in OpenTelemetry Protocol format via HTTP.
Expand Down Expand Up @@ -56,52 +60,37 @@
end

function obj = set.Endpoint(obj, ep)
if ~(isStringScalar(ep) || (ischar(ep) && isrow(ep)))
error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:EndpointNotScalarText", "Endpoint must be a scalar string.");
end
ep = string(ep);
ep = obj.Validator.validateEndpoint(ep);
obj.Proxy.setEndpoint(ep);
obj.Endpoint = ep;
end

function obj = set.Format(obj, newformat)
newformat = validatestring(newformat, ["JSON", "binary"]);
newformat = obj.Validator.validateFormat(newformat);
obj.Proxy.setFormat(newformat);
obj.Format = newformat;
end

function obj = set.JsonBytesMapping(obj, jbm)
jbm = validatestring(jbm, ["hex", "hexId", "base64"]);
jbm = obj.Validator.validateJsonBytesMapping(jbm);
obj.Proxy.setJsonBytesMapping(jbm);
obj.JsonBytesMapping = jbm;
end

function obj = set.UseJsonName(obj, ujn)
if ~((islogical(ujn) || isnumeric(ujn)) && isscalar(ujn))
error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:UseJsonNameNotScalarLogical", "UseJsonName must be a scalar logical.")
end
ujn = logical(ujn);
ujn = obj.Validator.validateUseJsonName(ujn);
obj.Proxy.setUseJsonName(ujn);
obj.UseJsonName = ujn;
end

function obj = set.Timeout(obj, timeout)
if ~(isduration(timeout) && isscalar(timeout))
error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration.");
end
obj.Validator.validateTimeout(timeout);
obj.Proxy.setTimeout(milliseconds(timeout));
obj.Timeout = timeout;
end

function obj = set.HttpHeaders(obj, httpheaders)
if ~isa(httpheaders, "dictionary")
error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary.");
end
headerkeys = keys(httpheaders);
headervalues = values(httpheaders);
if ~isstring(headervalues)
error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.")
end
[headerkeys, headervalues] = obj.Validator.validateHttpHeaders(httpheaders);
obj.Proxy.setHttpHeaders(headerkeys, headervalues);
obj.HttpHeaders = httpheaders;
end
Expand Down
23 changes: 23 additions & 0 deletions exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpValidator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
classdef OtlpHttpValidator < opentelemetry.exporters.otlp.OtlpValidator
% OtlpHttpValidator Validate options inputs for OtlpHttpSpanExporter and
% OtlpHttpMetricExporter

% Copyright 2023 The MathWorks, Inc.

methods (Static)
function newformat = validateFormat(newformat)
newformat = validatestring(newformat, ["JSON", "binary"]);
end

function jbm = validateJsonBytesMapping(jbm)
jbm = validatestring(jbm, ["hex", "hexId", "base64"]);
end

function ujn = validateUseJsonName(ujn)
if ~((islogical(ujn) || isnumeric(ujn)) && isscalar(ujn))
error("opentelemetry:exporters:otlp:OtlpHttpValidator:UseJsonNameNotScalarLogical", "UseJsonName must be a scalar logical.")
end
ujn = logical(ujn);
end
end
end
Loading

0 comments on commit 65c04b4

Please sign in to comment.