Skip to content

Commit

Permalink
Merge pull request #48 from mathworks/meter_provider_resource
Browse files Browse the repository at this point in the history
Adding Resource Property to MeterProvider
  • Loading branch information
dnarula-mw authored Nov 2, 2023
2 parents 2628bd7 + ac97746 commit b7bb9cf
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 9 deletions.
38 changes: 34 additions & 4 deletions sdk/metrics/+opentelemetry/+sdk/+metrics/MeterProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@

properties (Access=public)
MetricReader
Resource
end

methods
function obj = MeterProvider(reader)
% SDK implementation of tracer provider
function obj = MeterProvider(reader, optionnames, optionvalues)
% SDK implementation of meter provider
% MP = OPENTELEMETRY.SDK.METRICS.METERPROVIDER creates a meter
% provider that uses a periodic exporting metric reader and default configurations.
%
Expand All @@ -38,6 +39,11 @@
opentelemetry.sdk.metrics.PeriodicExportingMetricReader()
end

arguments (Repeating)
optionnames (1,:) {mustBeTextScalar}
optionvalues
end

% explicit call to superclass constructor to make it a no-op
[email protected]("skip");

Expand All @@ -49,13 +55,37 @@
assert(mpproxy.Name == "libmexclass.opentelemetry.MeterProviderProxy");
obj.Proxy = libmexclass.proxy.Proxy("Name", ...
"libmexclass.opentelemetry.sdk.MeterProviderProxy", ...
"ConstructorArguments", {mpproxy.ID, true});
"ConstructorArguments", {mpproxy.ID});
% leave other properties unassigned, they won't be used
else
validnames = ["Resource"];
resourcekeys = string.empty();
resourcevalues = {};
resource = dictionary(resourcekeys, resourcevalues);
for i = 1:length(optionnames)
namei = validatestring(optionnames{i}, validnames);
valuei = optionvalues{i};
if strcmp(namei, "Resource")
if ~isa(valuei, "dictionary")
error("opentelemetry:sdk:metrics:MeterProvider:InvalidResourceType", ...
"Resource input must be a dictionary.");
end
resource = valuei;
resourcekeys = keys(valuei);
resourcevalues = values(valuei,"cell");
% collapse one level of cells, as this may be due to
% a behavior of dictionary.values
if all(cellfun(@iscell, resourcevalues))
resourcevalues = [resourcevalues{:}];
end
end
end

obj.Proxy = libmexclass.proxy.Proxy("Name", ...
"libmexclass.opentelemetry.sdk.MeterProviderProxy", ...
"ConstructorArguments", {reader.Proxy.ID, false});
"ConstructorArguments", {reader.Proxy.ID, resourcekeys, resourcevalues});
obj.MetricReader = reader;
obj.Resource = resource;
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include "opentelemetry/sdk/metrics/meter_provider_factory.h"
#include "opentelemetry/sdk/metrics/push_metric_exporter.h"
#include "opentelemetry/sdk/resource/resource.h"
#include "opentelemetry/sdk/metrics/view/view_registry.h"
#include "opentelemetry/sdk/metrics/view/view_registry_factory.h"


#include "opentelemetry-matlab/metrics/MeterProxy.h"
#include "opentelemetry-matlab/metrics/MeterProviderProxy.h"
#include "opentelemetry-matlab/sdk/common/resource.h"

namespace metrics_api = opentelemetry::metrics;
namespace nostd = opentelemetry::nostd;
Expand Down
17 changes: 12 additions & 5 deletions sdk/metrics/src/MeterProviderProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ namespace libmexclass::opentelemetry::sdk {
libmexclass::proxy::MakeResult MeterProviderProxy::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) {

libmexclass::proxy::MakeResult out;
matlab::data::TypedArray<bool> is_api = constructor_arguments[1];
if (is_api[0]) {
// if argument is 1, assume it is an API Meter Provider to support type conversion
if (constructor_arguments.getNumberOfElements() == 1) {
// if only one input, assume it is an API Meter Provider to support type conversion
matlab::data::TypedArray<uint64_t> mpid_mda = constructor_arguments[0];
libmexclass::proxy::ID mpid = mpid_mda[0];
auto mp = std::static_pointer_cast<libmexclass::opentelemetry::MeterProviderProxy>(
Expand All @@ -29,12 +28,20 @@ libmexclass::proxy::MakeResult MeterProviderProxy::make(const libmexclass::proxy
matlab::data::TypedArray<uint64_t> readerid_mda = constructor_arguments[0];
libmexclass::proxy::ID readerid = readerid_mda[0];

matlab::data::StringArray resourcenames_mda = constructor_arguments[1];
size_t nresourceattrs = resourcenames_mda.getNumberOfElements();
matlab::data::CellArray resourcevalues_mda = constructor_arguments[2];

auto resource_custom = createResource(resourcenames_mda, resourcevalues_mda);

auto reader = std::static_pointer_cast<PeriodicExportingMetricReaderProxy>(
libmexclass::proxy::ProxyManager::getProxy(readerid))->getInstance();
auto p = metrics_sdk::MeterProviderFactory::Create();

auto view = metrics_sdk::ViewRegistryFactory::Create();
auto p = metrics_sdk::MeterProviderFactory::Create(std::move(view), resource_custom);
auto *p_sdk = static_cast<metrics_sdk::MeterProvider *>(p.get());
p_sdk->AddMetricReader(std::move(reader));

auto p_out = nostd::shared_ptr<metrics_api::MeterProvider>(std::move(p));
out = std::make_shared<MeterProviderProxy>(p_out);
}
Expand Down
69 changes: 69 additions & 0 deletions test/tmetrics_sdk.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
classdef tmetrics_sdk < matlab.unittest.TestCase
% tests for metrics SDK

% Copyright 2023 The MathWorks, Inc.

properties
OtelConfigFile
JsonFile
PidFile
OtelcolName
Otelcol
ListPid
ReadPidList
ExtractPid
Sigint
Sigterm
end

methods (TestClassSetup)
function setupOnce(testCase)
commonSetupOnce(testCase);
end
end

methods (TestMethodTeardown)
function teardown(testCase)
commonTeardown(testCase);
end
end

methods (Test)
function testCustomResource(testCase)
% testCustomResource: check custom resources are included in
% emitted metrics
commonSetup(testCase)

customkeys = ["foo" "bar"];
customvalues = [1 5];
exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter();
reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ...
"Interval", seconds(2), "Timeout", seconds(1));
mp = opentelemetry.sdk.metrics.MeterProvider(reader, ...
"Resource", dictionary(customkeys, customvalues));

m = getMeter(mp, "mymeter");
c = createCounter(m, "mycounter");

% create testing value
val = 10;

% add value and attributes
c.add(val);

pause(2.5);

% perform test comparisons
results = readJsonResults(testCase);
results = results{1};

resourcekeys = string({results.resourceMetrics.resource.attributes.key});
for i = length(customkeys)
idx = find(resourcekeys == customkeys(i));
verifyNotEmpty(testCase, idx);
verifyEqual(testCase, results.resourceMetrics.resource.attributes(idx).value.doubleValue, customvalues(i));
end
end

end
end

0 comments on commit b7bb9cf

Please sign in to comment.