diff --git a/sdk/metrics/+opentelemetry/+sdk/+metrics/View.m b/sdk/metrics/+opentelemetry/+sdk/+metrics/View.m index e1fa2ee..07ec821 100644 --- a/sdk/metrics/+opentelemetry/+sdk/+metrics/View.m +++ b/sdk/metrics/+opentelemetry/+sdk/+metrics/View.m @@ -21,28 +21,47 @@ end methods - function obj = View(name, description, unit, instrumentName, instrumentType, ... - meterName, meterVersion, meterSchemaURL, attributeKeys, ... - aggregation, histogramBinEdges, varargin) + function obj = View(options) + arguments + options.name="" + options.description="" + options.unit="" + options.instrumentName="" + options.instrumentType="" + options.meterName="" + options.meterVersion="" + options.meterSchemaURL="" + options.attributeKeys=[] + options.aggregation="" + options.histogramBinEdges=[] + end - instrumentTypeCategory = int32(find(instrumentType==["kCounter", "kHistogram", "kUpDownCounter", "kObservableCounter", "kObservableGauge", "kObservableUpDownCounter"])-1); + options.attributeKeys = ["" options.attributeKeys]; + instrumentTypeCategory = int32(find(options.instrumentType==["kCounter", "kHistogram", "kUpDownCounter", "kObservableCounter", "kObservableGauge", "kObservableUpDownCounter"])-1); - aggregationCategory = int32(find(aggregation==["kDrop", "kHistogram", "kLastValue", "kSum", "kDefault"])-1); + aggregationCategory = int32(find(options.aggregation==["kDrop", "kHistogram", "kLastValue", "kSum", "kDefault"])-1); + if(numel(instrumentTypeCategory)==0) + instrumentTypeCategory = -1; + end + if(numel(aggregationCategory)==0) + aggregationCategory = -1; + end obj.Proxy = libmexclass.proxy.Proxy("Name", "libmexclass.opentelemetry.sdk.ViewProxy", ... - "ConstructorArguments", {name, description, unit, instrumentName, ... - instrumentTypeCategory, meterName, meterVersion, meterSchemaURL, ... - attributeKeys, aggregationCategory, histogramBinEdges, varargin}); - obj.Description = description; - obj.Unit = unit; - obj.InstrumentName = instrumentName; - obj.InstrumentType = instrumentType; - obj.MeterName = meterName; - obj.MeterVersion = meterVersion; - obj.MeterSchemaURL = meterSchemaURL; - obj.AttributeKeys = attributeKeys; - obj.Aggregation = aggregation; - obj.HistogramBinEdges = histogramBinEdges; + "ConstructorArguments", {options.name, options.description, options.unit, options.instrumentName, ... + instrumentTypeCategory, options.meterName, options.meterVersion, options.meterSchemaURL, ... + options.attributeKeys, aggregationCategory, options.histogramBinEdges}); + obj.Name = options.name; + obj.Description = options.description; + obj.Unit = options.unit; + obj.InstrumentName = options.instrumentName; + obj.InstrumentType = options.instrumentType; + obj.MeterName = options.meterName; + obj.MeterVersion = options.meterVersion; + obj.MeterSchemaURL = options.meterSchemaURL; + obj.AttributeKeys = options.attributeKeys; + obj.Aggregation = options.aggregation; + obj.HistogramBinEdges = options.histogramBinEdges; end end end \ No newline at end of file diff --git a/sdk/metrics/src/MeterProviderProxy.cpp b/sdk/metrics/src/MeterProviderProxy.cpp index df2b535..f6809f8 100644 --- a/sdk/metrics/src/MeterProviderProxy.cpp +++ b/sdk/metrics/src/MeterProviderProxy.cpp @@ -1,5 +1,6 @@ // Copyright 2023 The MathWorks, Inc. +#include "opentelemetry/sdk/metrics/instruments.h" #include "opentelemetry-matlab/sdk/metrics/MeterProviderProxy.h" #include "opentelemetry-matlab/sdk/metrics/PeriodicExportingMetricReaderProxy.h" #include "opentelemetry-matlab/sdk/metrics/ViewProxy.h" @@ -7,6 +8,7 @@ #include "libmexclass/proxy/ProxyManager.h" #include +#include namespace libmexclass::opentelemetry::sdk { libmexclass::proxy::MakeResult MeterProviderProxy::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { @@ -62,6 +64,47 @@ void MeterProviderProxy::addMetricReader(libmexclass::proxy::method::Context& co void MeterProviderProxy::addView(libmexclass::proxy::method::Context& context) { matlab::data::TypedArray viewid_mda = context.inputs[0]; libmexclass::proxy::ID viewid = viewid_mda[0]; + + // auto i = std::static_pointer_cast(libmexclass::proxy::ProxyManager::getProxy(viewid))->getInstrumentSelector(context); + // if((int)(i->GetInstrumentType())!=0){ + // exit(0); + // } + // auto instrument_name = "mycounter"; + // auto instrument_name_view = nostd::string_view(instrument_name); + // if(!i->GetNameFilter()->Match(instrument_name_view)){ + // exit(0); + // } + // auto instrument_unit = "unit"; + // auto instrument_unit_view = nostd::string_view(instrument_unit); + // if(!i->GetUnitFilter()->Match(instrument_unit_view)){ + // exit(0); + // } + // auto m = std::static_pointer_cast(libmexclass::proxy::ProxyManager::getProxy(viewid))->getMeterSelector(context); + // auto meter_name = "mymeter"; + // auto meter_name_view = nostd::string_view(meter_name); + // if(!m->GetNameFilter()->Match(meter_name_view)){ + // exit(0); + // } + // auto meter_version = "1.2.0"; + // auto meter_version_view = nostd::string_view(meter_version); + // if(!m->GetVersionFilter()->Match(meter_version_view)){ + // exit(0); + // } + // auto meter_schema = ""; + // auto meter_schema_view = nostd::string_view(meter_schema); + // if(!m->GetSchemaFilter()->Match(meter_schema_view)){ + // exit(0); + // } + // auto v = std::static_pointer_cast(libmexclass::proxy::ProxyManager::getProxy(viewid))->getView(context); + // if(v->GetName().compare("View")!=0){ + // exit(0); + // } + // if(v->GetDescription().compare("description")!=0){ + // exit(0); + // } + // if((int)(v->GetAggregationType())!=0){ + // exit(0); + // } static_cast(*CppMeterProvider).AddView( std::static_pointer_cast(libmexclass::proxy::ProxyManager::getProxy(viewid))->getInstrumentSelector(context), diff --git a/sdk/metrics/src/ViewProxy.cpp b/sdk/metrics/src/ViewProxy.cpp index 15141ea..fed6bfd 100644 --- a/sdk/metrics/src/ViewProxy.cpp +++ b/sdk/metrics/src/ViewProxy.cpp @@ -30,7 +30,12 @@ libmexclass::proxy::MakeResult ViewProxy::make(const libmexclass::proxy::Functio auto unit = unit_mda[0]; matlab::data::TypedArray aggregation_type_mda = constructor_arguments[9]; - auto aggregation_type = static_cast(static_cast(aggregation_type_mda[0])); + metrics_sdk::AggregationType aggregation_type; + if(static_cast(aggregation_type_mda[0]) == -1){ + aggregation_type = metrics_sdk::AggregationType::kDefault; + }else{ + aggregation_type = static_cast(static_cast(aggregation_type_mda[0])); + } std::shared_ptr aggregation_config = std::shared_ptr(new metrics_sdk::HistogramAggregationConfig()); if(aggregation_type == metrics_sdk::AggregationType::kHistogram){ @@ -45,58 +50,64 @@ libmexclass::proxy::MakeResult ViewProxy::make(const libmexclass::proxy::Functio } std::unique_ptr attributes_processor; - matlab::data::StringArray attributes_mda = constructor_arguments[8]; - if(attributes_mda.getNumberOfElements()==0){ + matlab::data::TypedArray attributes_mda = constructor_arguments[8]; + if(attributes_mda.getNumberOfElements()==1){ attributes_processor = std::unique_ptr(new metrics_sdk::DefaultAttributesProcessor()); }else{ std::unordered_map allowed_attribute_keys; - for (auto a : attributes_mda) { - allowed_attribute_keys[a] = true; + for (int a=1; a(new metrics_sdk::FilteringAttributesProcessor(allowed_attribute_keys)); } auto view = metrics_sdk::ViewFactory::Create(name, description, - unit, aggregation_type, std::move(aggregation_config), std::move(attributes_processor)); + unit, aggregation_type, aggregation_config, std::move(attributes_processor)); // Create Instrument Selector matlab::data::TypedArray instrument_type_mda = constructor_arguments[4]; - auto instrument_type = static_cast(static_cast(instrument_type_mda[0])); + metrics_sdk::InstrumentType instrument_type; + if(static_cast(instrument_type_mda[0]) == -1){ + instrument_type = metrics_sdk::InstrumentType::kCounter; + }else{ + instrument_type = static_cast(static_cast(instrument_type_mda[0])); + } matlab::data::StringArray instrument_name_mda = constructor_arguments[3]; - auto instrument_name = static_cast(instrument_name_mda[0]); - auto instrument_name_view = nostd::string_view(instrument_name); + auto instrument_name_view = static_cast(instrument_name_mda[0]); + // auto instrument_name_view = nostd::string_view(instrument_name); - auto unit_view = nostd::string_view(static_cast(unit)); + auto unit_view = static_cast(unit); + // auto unit_view = nostd::string_view(static_cast(unit)); auto instrumentSelector = metrics_sdk::InstrumentSelectorFactory::Create(instrument_type, - instrument_name, unit_view); - + instrument_name_view, unit_view); // Create Meter Selector matlab::data::StringArray meter_name_mda = constructor_arguments[5]; - auto meter_name = static_cast(meter_name_mda[0]); - auto meter_name_view = nostd::string_view(meter_name); + auto meter_name_view = static_cast(meter_name_mda[0]); + // auto meter_name_view = nostd::string_view(meter_name); matlab::data::StringArray meter_version_mda = constructor_arguments[6]; - auto meter_version = static_cast(meter_version_mda[0]); - auto meter_version_view = nostd::string_view(meter_version); + auto meter_version_view = static_cast(meter_version_mda[0]); + // auto meter_version_view = nostd::string_view(meter_version); matlab::data::StringArray meter_schema_mda = constructor_arguments[7]; - auto meter_schema = static_cast(meter_schema_mda[0]); - auto meter_schema_view = nostd::string_view(meter_schema); + auto meter_schema_view = static_cast(meter_schema_mda[0]); + // auto meter_schema_view = nostd::string_view(meter_schema); auto meterSelector = metrics_sdk::MeterSelectorFactory::Create(meter_name_view, meter_version_view, meter_schema_view); - - - // out = std::make_shared(nostd::shared_ptr( - // std::move(metrics_sdk::ViewFactory::Create(name, description, - // unit, aggregation_type, std::move(aggregation_config), std::move(attributes_processor))))); - - - // return out; + // std::unique_ptr instrumentSelector{ + // new metrics_sdk::InstrumentSelector(instrument_type, + // instrument_name_view, unit_view)}; + // std::unique_ptr meterSelector{ + // new metrics_sdk::MeterSelector(meter_name_view, + // meter_version_view, meter_schema_view)}; + // std::unique_ptr view{ + // new metrics_sdk::View{name, description, + // unit, aggregation_type, aggregation_config, std::move(attributes_processor)}}; return std::make_shared(std::move(view), std::move(instrumentSelector), std::move(meterSelector)); } diff --git a/test/tmetrics_sdk.m b/test/tmetrics_sdk.m index f675254..1da1a4a 100644 --- a/test/tmetrics_sdk.m +++ b/test/tmetrics_sdk.m @@ -32,11 +32,11 @@ function setup(testCase) end end - % methods (TestMethodTeardown) - % function teardown(testCase) - % commonTeardown(testCase); - % end - % end + methods (TestMethodTeardown) + function teardown(testCase) + commonTeardown(testCase); + end + end methods (Test) function testDefaultExporter(testCase) @@ -146,92 +146,99 @@ function testCustomResource(testCase) end end - function testViewCounter(testCase) - % testCustomResource: check custom resources are included in - % emitted metrics - - exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); - reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... - "Interval", seconds(2), "Timeout", seconds(1)); - mp = opentelemetry.sdk.metrics.MeterProvider(reader); - - m = getMeter(mp, "mymeter"); - c = createCounter(m, "mycounter"); - - % create testing value - val = 10; - - % add value and attributes - c.add(val); - - pause(2.5); - - view = opentelemetry.sdk.metrics.View("View", "my View", "", "", "kCounter", "mymeter", "", "", "", "kDrop", []); - - addView(mp, view); - - clear mp; - - % % TODO: add test comparisons - end - - function testViewUpDownCounter(testCase) - % test names and added value in UpDownCounter - - exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); - reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... - "Interval", seconds(2), "Timeout", seconds(1)); - mp = opentelemetry.sdk.metrics.MeterProvider(reader); - - m = getMeter(mp, "mymeter"); - c = createUpDownCounter(m, "mycounter"); - - % create testing value - val = -10; - - % add value and attributes - c.add(val); - - % wait for collector response time (2s) - pause(5); - - view = opentelemetry.sdk.metrics.View("View", "my View", "Unit", "MyGauge", "kUpDownCounter", "mymeter", "", "", "", "kLastValue", []); - - addView(mp, view); - - clear mp; - - % % TODO: add test comparisons - end - - function testViewHistogram(testCase) - % testCustomResource: check custom resources are included in - % emitted metrics - - exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); - reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... - "Interval", seconds(2), "Timeout", seconds(1)); - mp = opentelemetry.sdk.metrics.MeterProvider(reader); - m = mp.getMeter("mymeter"); - hist = m.createHistogram("histogram"); - - % create value for histogram - val = 1; - - % record value - hist.record(val); - - % wait for collector response - pause(2.5); - - view = opentelemetry.sdk.metrics.View("View", "my View", "", "", "kHistogram", "mymeter", "", "", "", "kHistogram", [0 100 200 300 400 500]); - - addView(mp, view); - - clear mp; - - % % TODO: add test comparisons - end + % function testViewCounter(testCase) + % % testCustomResource: check custom resources are included in + % % emitted metrics + % + % exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); + % reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... + % "Interval", seconds(2), "Timeout", seconds(1)); + % mp = opentelemetry.sdk.metrics.MeterProvider(reader); + % + % m = getMeter(mp, "mymeter"); + % c = createCounter(m, "mycounter"); + % + % % create testing value + % val = 10; + % + % % add value and attributes + % c.add(val); + % + % pause(2.5); + % + % view = opentelemetry.sdk.metrics.View("View", "my View", "", "mycounter", "kCounter", "mymeter", "", "", "", "kDrop", []); + % + % addView(mp, view); + % + % clear mp; + % + % % % TODO: add test comparisons + % + % end + % + % function testViewUpDownCounter(testCase) + % % test names and added value in UpDownCounter + % + % exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); + % reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... + % "Interval", seconds(2), "Timeout", seconds(1)); + % mp = opentelemetry.sdk.metrics.MeterProvider(reader); + % + % m = getMeter(mp, "mymeter"); + % c = createUpDownCounter(m, "mycounter"); + % + % + % % add value and attributes + % c.add(-10); + % c.add(-5); + % c.add(12); + % c.add(7); + % + % % wait for collector response time (2s) + % pause(5); + % + % view = opentelemetry.sdk.metrics.View("View", "", "", "mycounter", "kUpDownCounter", "mymeter", "", "", [], "kLastValue", []); + % + % addView(mp, view); + % + % c.add(8); + % + % clear mp; + % + % % % TODO: add test comparisons + % end + % + % function testViewHistogram(testCase) + % % testCustomResource: check custom resources are included in + % % emitted metrics + % + % exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); + % reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... + % "Interval", seconds(2), "Timeout", seconds(1)); + % mp = opentelemetry.sdk.metrics.MeterProvider(reader); + % m = mp.getMeter("mymeter"); + % hist = m.createHistogram("histogram"); + % + % % record values + % hist.record(1); + % hist.record(200); + % hist.record(201); + % hist.record(400); + % hist.record(401); + % + % % wait for collector response + % pause(2.5); + % + % view = opentelemetry.sdk.metrics.View("View", "my View", "", "histogram", "kHistogram", "mymeter", "", "", "", "kHistogram", [0 100 200 300 400 500]); + % + % addView(mp, view); + % + % hist.record(402); + % + % clear mp; + % + % % % TODO: add test comparisons + % end function testShutdown(testCase) % testShutdown: shutdown method should stop exporting diff --git a/test/view/testattributes.m b/test/view/testattributes.m new file mode 100644 index 0000000..ebcd11c --- /dev/null +++ b/test/view/testattributes.m @@ -0,0 +1,24 @@ +exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); +reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... + "Interval", seconds(2), "Timeout", seconds(1)); + +mp = opentelemetry.sdk.metrics.MeterProvider(reader); + +view = opentelemetry.sdk.metrics.View(name="View", description="my View", instrumentName="mycounter", instrumentType="kCounter", meterName="mymeter", attributeKeys="Group", aggregation="kSum"); + +addView(mp, view); + +m = getMeter(mp, "mymeter"); +c = createCounter(m, "mycounter"); + + +% add value and attributes +c.add(3, "Group", "A", "Trial", 1); +c.add(1, "Group", "A", "Trial", 2); +c.add(12, "Group", "A", "Trial", 1); +c.add(7, "Group", "A", "Trial", 2); + +% wait for collector response time (2s) +pause(5); + +clear; \ No newline at end of file diff --git a/test/view/testhistogram.m b/test/view/testhistogram.m new file mode 100644 index 0000000..8b0cc81 --- /dev/null +++ b/test/view/testhistogram.m @@ -0,0 +1,24 @@ +exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); +reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... + "Interval", seconds(2), "Timeout", seconds(1)); +mp = opentelemetry.sdk.metrics.MeterProvider(reader); + +view = opentelemetry.sdk.metrics.View(Name="View", Description="my View", InstrumentName="histogram", InstrumentType="kHistogram", MeterName="mymeter", Aggregation="kHistogram", HistogramBinEdges=[0 100 200 300 400 500]); + +addView(mp, view); + +m = mp.getMeter("mymeter"); +hist = m.createHistogram("histogram"); + +% record values +hist.record(1); +hist.record(200); +hist.record(201); +hist.record(400); +hist.record(401); + +% wait for collector response +pause(2.5); + + +clear; \ No newline at end of file diff --git a/test/view/testviewcounter.m b/test/view/testviewcounter.m new file mode 100644 index 0000000..fbb2a5a --- /dev/null +++ b/test/view/testviewcounter.m @@ -0,0 +1,22 @@ +exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); +reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... + "Interval", seconds(100), "Timeout", seconds(1)); + +mp = opentelemetry.sdk.metrics.MeterProvider(reader); + +view = opentelemetry.sdk.metrics.View(name="mycounter", instrumentName="mycounter", instrumentType="kCounter", meterName="mymeter", meterVersion="1.2.0", meterSchemaURL="", aggregation="kDrop"); + +addView(mp, view); + +m = getMeter(mp, "mymeter", "1.2.0", ""); +c = createCounter(m, "mycounter"); + +% add value and attributes +c.add(10); +c.add(12); +c.add(3); +c.add(6); + +pause(2.5); + +clear; \ No newline at end of file diff --git a/test/view/testviewupdown.m b/test/view/testviewupdown.m new file mode 100644 index 0000000..aa83158 --- /dev/null +++ b/test/view/testviewupdown.m @@ -0,0 +1,23 @@ +exporter = opentelemetry.exporters.otlp.OtlpHttpMetricExporter(); +reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exporter, ... + "Interval", seconds(2), "Timeout", seconds(1)); +mp = opentelemetry.sdk.metrics.MeterProvider(reader); + +view = opentelemetry.sdk.metrics.View(name="View", description="my View", instrumentName="mycounter", instrumentType="kUpDownCounter", meterName="mymeter", aggregation="kLastValue"); + +addView(mp, view); + +m = getMeter(mp, "mymeter"); +c = createUpDownCounter(m, "mycounter"); + + +% add value and attributes +c.add(-10); +c.add(-5); +c.add(12); +c.add(7); + +% wait for collector response time (2s) +pause(5); + +clear; \ No newline at end of file