diff --git a/sdk/metrics/+opentelemetry/+sdk/+metrics/View.m b/sdk/metrics/+opentelemetry/+sdk/+metrics/View.m index 837ce13..8b6af34 100644 --- a/sdk/metrics/+opentelemetry/+sdk/+metrics/View.m +++ b/sdk/metrics/+opentelemetry/+sdk/+metrics/View.m @@ -13,18 +13,18 @@ Proxy % Proxy object to interface C++ code end - properties (SetAccess=immutable) - Name (1,1) string % View name - Description (1,1) string % Description of view - InstrumentName (1,1) string % Name of the instrument this view applies to - InstrumentType (1,1) string % Type of instrument this view applies to - InstrumentUnit (1,1) string % Unit of instrument this view applies to - MeterName (1,1) string % Name of the meter this view applies to - MeterVersion (1,1) string % Version of the meter this view applies to - MeterSchema (1,1) string % Schema URL of the meter this view applies to - AllowedAttributes (1,:) string % List of attribute keys that are kept. All other attributes are ignored. - Aggregation (1,1) string % Customized aggregation type - HistogramBinEdges (1,:) double % Vector of customized bin edges for histogram + properties + Name (1,1) string = "" % View name + Description (1,1) string = "" % Description of view + InstrumentName (1,1) string % Name of the instrument this view applies to + InstrumentType (1,1) string % Type of instrument this view applies to + InstrumentUnit (1,1) string = "" % Unit of instrument this view applies to + MeterName (1,1) string = "" % Name of the meter this view applies to + MeterVersion (1,1) string = "" % Version of the meter this view applies to + MeterSchema (1,1) string = "" % Schema URL of the meter this view applies to + AllowedAttributes (1,:) string % List of attribute keys that are kept. All other attributes are ignored. + Aggregation (1,1) string % Customized aggregation type + HistogramBinEdges (1,:) double = zeros(1,0) % Vector of customized bin edges for histogram end methods @@ -33,7 +33,7 @@ % V = OPENTELEMETRY.SDK.METRICS.VIEW(PARAM1, VALUE1, PARAM2, % VALUE2, ...) creates a view object and specifies its % behavior using parameter name/value pairs. Parameters are: - % "Name" - Name of view. Any metric this view + % "Name" - Name of view. Any metric this view % applies to will be renamed to this name. % "Description" - Description of view. % "InstrumentName" - Specifies an instrument name. This @@ -42,7 +42,7 @@ % this name. % "InstrumentType" - Specifies an instrument type. This % view will be applied to all metrics - % generated from all instruments of + % generated from all instruments of % this type. % "InstrumentUnit" - Specifies an instrument unit. This % view will be applied to all metrics @@ -61,10 +61,10 @@ % generated from all instruments created % by meters with this schema URL. % "AllowedAttributes" - Specifies a list of attributes - % that will be kept. All other + % that will be kept. All other % attributes will be dropped. % "Aggregation" - Change instruments to use a - % different aggregation beahvior. + % different aggregation beahvior. % "HistogramBinEdges" - Use a different set of bins % in all histograms this view % applies to @@ -83,50 +83,160 @@ % % See also OPENTELEMETRY.SDK.METRICS.METERPROVIDER arguments - options.Name {mustBeTextScalar} = "" - options.Description {mustBeTextScalar} = "" + options.Name {mustBeTextScalar} + options.Description {mustBeTextScalar} options.InstrumentName {mustBeTextScalar} = "*" options.InstrumentType {mustBeTextScalar} = "counter" - options.InstrumentUnit {mustBeTextScalar} = "" - options.MeterName {mustBeTextScalar} = "" - options.MeterVersion {mustBeTextScalar} = "" - options.MeterSchema {mustBeTextScalar} = "" - options.AllowedAttributes {mustBeText, mustBeVector} % no default here + options.InstrumentUnit {mustBeTextScalar} + options.MeterName {mustBeTextScalar} + options.MeterVersion {mustBeTextScalar} + options.MeterSchema {mustBeTextScalar} + options.AllowedAttributes {mustBeText, mustBeVector} = "*" options.Aggregation {mustBeTextScalar} = "default" - options.HistogramBinEdges {mustBeNumeric, mustBeVector} = zeros(1,0) + options.HistogramBinEdges {mustBeNumeric, mustBeVector} end + obj.Proxy = libmexclass.proxy.Proxy("Name", "libmexclass.opentelemetry.sdk.ViewProxy", ... + "ConstructorArguments", {}); + + if isfield(options, "Name") + obj.Name = options.Name; + end + if isfield(options, "Description") + obj.Description = options.Description; + end + obj.InstrumentName = options.InstrumentName; + obj.InstrumentType = options.InstrumentType; + if isfield(options, "InstrumentUnit") + obj.InstrumentUnit = options.InstrumentUnit; + end + if isfield(options, "MeterName") + obj.MeterName = options.MeterName; + end + if isfield(options, "MeterVersion") + obj.MeterVersion = options.MeterVersion; + end + if isfield(options, "MeterSchema") + obj.MeterSchema = options.MeterSchema; + end + obj.AllowedAttributes = options.AllowedAttributes; + obj.Aggregation = options.Aggregation; + if isfield(options, "HistogramBinEdges") + obj.HistogramBinEdges = options.HistogramBinEdges; + end + end + + function obj = set.Name(obj, name) + arguments + obj + name {mustBeTextScalar} + end + name = string(name); + obj.Proxy.setName(name); %#ok<*MCSUP> + obj.Name = name; + end + + function obj = set.Description(obj, desc) + arguments + obj + desc {mustBeTextScalar} + end + desc = string(desc); + obj.Proxy.setDescription(desc); + obj.Description = desc; + end + + function obj = set.InstrumentName(obj, instname) + arguments + obj + instname {mustBeTextScalar} + end + instname = string(instname); + obj.Proxy.setInstrumentName(instname); + obj.InstrumentName = instname; + end + + function obj = set.InstrumentType(obj, insttype) + arguments + obj + insttype {mustBeTextScalar} + end instrument_types = ["counter", "histogram", "updowncounter", ... "observablecounter", "observableupdowncounter", "observablegauge"]; - instrument_type = validatestring(options.InstrumentType, instrument_types); + insttype = validatestring(insttype, instrument_types); + obj.Proxy.setInstrumentType(insttype); + obj.InstrumentType = insttype; + end - aggregation_types = ["drop", "histogram", "lastvalue", "sum", "default"]; - aggregation_type = validatestring(options.Aggregation, aggregation_types); - - % check whether AllowedAttributes is defined - filter_attributes = isfield(options, "AllowedAttributes"); - if ~filter_attributes - % put some defaults here, which will be ignored since filter_attributes is false - options.AllowedAttributes = strings(1,0); + function obj = set.InstrumentUnit(obj, instunit) + arguments + obj + instunit {mustBeTextScalar} end + instunit = string(instunit); + obj.Proxy.setInstrumentUnit(instunit); + obj.InstrumentUnit = instunit; + end - obj.Proxy = libmexclass.proxy.Proxy("Name", "libmexclass.opentelemetry.sdk.ViewProxy", ... - "ConstructorArguments", {options.Name, options.Description, options.InstrumentName, ... - instrument_type, options.InstrumentUnit, options.MeterName, ... - options.MeterVersion, options.MeterSchema, filter_attributes,... - options.AllowedAttributes, aggregation_type, options.HistogramBinEdges}); - - obj.Name = string(options.Name); - obj.Description = string(options.Description); - obj.InstrumentName = string(options.InstrumentName); - obj.InstrumentType = instrument_type; - obj.InstrumentUnit = string(options.InstrumentUnit); - obj.MeterName = string(options.MeterName); - obj.MeterVersion = string(options.MeterVersion); - obj.MeterSchema = string(options.MeterSchema); - obj.AllowedAttributes = reshape(string(options.AllowedAttributes),1,[]); - obj.Aggregation = aggregation_type; - obj.HistogramBinEdges = reshape(double(options.HistogramBinEdges),1,[]); + function obj = set.MeterName(obj, metername) + arguments + obj + metername {mustBeTextScalar} + end + metername = string(metername); + obj.Proxy.setMeterName(metername) + obj.MeterName = metername; + end + + function obj = set.MeterVersion(obj, meterversion) + arguments + obj + meterversion {mustBeTextScalar} + end + meterversion = string(meterversion); + obj.Proxy.setMeterVersion(meterversion); + obj.MeterVersion = meterversion; + end + + function obj = set.MeterSchema(obj, meterschema) + arguments + obj + meterschema {mustBeTextScalar} + end + meterschema = string(meterschema); + obj.Proxy.setMeterSchema(meterschema); + obj.MeterSchema = meterschema; + end + + function obj = set.AllowedAttributes(obj, attrs) + arguments + obj + attrs {mustBeText, mustBeVector} + end + attrs = reshape(string(attrs),1,[]); + obj.Proxy.setAllowedAttributes(attrs); + obj.AllowedAttributes = attrs; + end + + function obj = set.Aggregation(obj, agg) + arguments + obj + agg {mustBeTextScalar} + end + aggregation_types = ["drop", "histogram", "lastvalue", "sum", "default"]; + agg = validatestring(agg, aggregation_types); + obj.Proxy.setAggregation(agg); + obj.Aggregation = agg; + end + + function obj = set.HistogramBinEdges(obj, binedges) + arguments + obj + binedges {mustBeNumeric, mustBeVector} + end + binedges = reshape(double(binedges),1,[]); + obj.Proxy.setHistogramBinEdges(binedges); + obj.HistogramBinEdges = binedges; end end end \ No newline at end of file diff --git a/sdk/metrics/include/opentelemetry-matlab/sdk/metrics/ViewProxy.h b/sdk/metrics/include/opentelemetry-matlab/sdk/metrics/ViewProxy.h index bbde3af..8f928fe 100644 --- a/sdk/metrics/include/opentelemetry-matlab/sdk/metrics/ViewProxy.h +++ b/sdk/metrics/include/opentelemetry-matlab/sdk/metrics/ViewProxy.h @@ -1,4 +1,4 @@ -// Copyright 2023 The MathWorks, Inc. +// Copyright 2023-2024 The MathWorks, Inc. #pragma once @@ -28,16 +28,46 @@ namespace nostd = opentelemetry::nostd; namespace libmexclass::opentelemetry::sdk { class ViewProxy : public libmexclass::proxy::Proxy { public: - ViewProxy(std::string name, std::string description, std::string instrumentName, - metrics_sdk::InstrumentType instrumentType, std::string instrumentUnit, std::string meterName, - std::string meterVersion, std::string meterSchema, std::unordered_map allowedAttributes, - bool filterAttributes, metrics_sdk::AggregationType aggregationType, std::vector histogramBinEdges) - : Name(std::move(name)), Description(std::move(description)), InstrumentName(std::move(instrumentName)), InstrumentType(instrumentType), - InstrumentUnit(std::move(instrumentUnit)), MeterName(std::move(meterName)), MeterVersion(std::move(meterVersion)), MeterSchema(std::move(meterSchema)), - AllowedAttributes(std::move(allowedAttributes)), FilterAttributes(filterAttributes), Aggregation(aggregationType), HistogramBinEdges(std::move(histogramBinEdges)) {} + ViewProxy() + : FilterAttributes(false) { + REGISTER_METHOD(ViewProxy, setName); + REGISTER_METHOD(ViewProxy, setDescription); + REGISTER_METHOD(ViewProxy, setInstrumentName); + REGISTER_METHOD(ViewProxy, setInstrumentType); + REGISTER_METHOD(ViewProxy, setInstrumentUnit); + REGISTER_METHOD(ViewProxy, setMeterName); + REGISTER_METHOD(ViewProxy, setMeterVersion); + REGISTER_METHOD(ViewProxy, setMeterSchema); + REGISTER_METHOD(ViewProxy, setAllowedAttributes); + REGISTER_METHOD(ViewProxy, setAggregation); + REGISTER_METHOD(ViewProxy, setHistogramBinEdges); + } + static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + void setName(libmexclass::proxy::method::Context& context); + + void setDescription(libmexclass::proxy::method::Context& context); + + void setInstrumentName(libmexclass::proxy::method::Context& context); + + void setInstrumentType(libmexclass::proxy::method::Context& context); + + void setInstrumentUnit(libmexclass::proxy::method::Context& context); + + void setMeterName(libmexclass::proxy::method::Context& context); + + void setMeterVersion(libmexclass::proxy::method::Context& context); + + void setMeterSchema(libmexclass::proxy::method::Context& context); + + void setAllowedAttributes(libmexclass::proxy::method::Context& context); + + void setAggregation(libmexclass::proxy::method::Context& context); + + void setHistogramBinEdges(libmexclass::proxy::method::Context& context); + std::unique_ptr getView(); std::unique_ptr getInstrumentSelector(); @@ -45,10 +75,6 @@ class ViewProxy : public libmexclass::proxy::Proxy { std::unique_ptr getMeterSelector(); private: - std::unique_ptr View; - - std::unique_ptr InstrumentSelector; - std::string InstrumentName; metrics_sdk::InstrumentType InstrumentType; std::string InstrumentUnit; diff --git a/sdk/metrics/src/ViewProxy.cpp b/sdk/metrics/src/ViewProxy.cpp index c3ec4b4..d14d6b7 100644 --- a/sdk/metrics/src/ViewProxy.cpp +++ b/sdk/metrics/src/ViewProxy.cpp @@ -6,104 +6,105 @@ namespace libmexclass::opentelemetry::sdk { libmexclass::proxy::MakeResult ViewProxy::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - libmexclass::proxy::MakeResult out; + return std::make_shared(); +} - // Name - matlab::data::StringArray name_mda = constructor_arguments[0]; - std::string name = static_cast(name_mda[0]); +// Setters for properties +void ViewProxy::setName(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray name_mda = context.inputs[0]; + Name = static_cast(name_mda[0]); +} - // Description - matlab::data::StringArray description_mda = constructor_arguments[1]; - std::string description = static_cast(description_mda[0]); - - // InstrumentName - matlab::data::StringArray instrument_name_mda = constructor_arguments[2]; - auto instrument_name = static_cast(instrument_name_mda[0]); - - // InstrumentType - matlab::data::StringArray instrument_type_mda = constructor_arguments[3]; - matlab::data::String instrument_type_str = instrument_type_mda[0]; - metrics_sdk::InstrumentType instrument_type; +void ViewProxy::setDescription(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray description_mda = context.inputs[0]; + Description = static_cast(description_mda[0]); +} + +void ViewProxy::setInstrumentName(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray instrumentname_mda = context.inputs[0]; + InstrumentName = static_cast(instrumentname_mda[0]); +} + +void ViewProxy::setInstrumentType(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray instrumenttype_mda = context.inputs[0]; + matlab::data::String instrument_type_str = instrumenttype_mda[0]; if (instrument_type_str.compare(u"counter") == 0) { - instrument_type = metrics_sdk::InstrumentType::kCounter; + InstrumentType = metrics_sdk::InstrumentType::kCounter; } else if (instrument_type_str.compare(u"updowncounter") == 0) { - instrument_type = metrics_sdk::InstrumentType::kUpDownCounter; + InstrumentType = metrics_sdk::InstrumentType::kUpDownCounter; } else if (instrument_type_str.compare(u"histogram") == 0) { - instrument_type = metrics_sdk::InstrumentType::kHistogram; + InstrumentType = metrics_sdk::InstrumentType::kHistogram; } else if (instrument_type_str.compare(u"observablecounter") == 0) { - instrument_type = metrics_sdk::InstrumentType::kObservableCounter; + InstrumentType = metrics_sdk::InstrumentType::kObservableCounter; } else if (instrument_type_str.compare(u"observableupdowncounter") == 0) { - instrument_type = metrics_sdk::InstrumentType::kObservableUpDownCounter; + InstrumentType = metrics_sdk::InstrumentType::kObservableUpDownCounter; } else { assert(instrument_type_str.compare(u"observablegauge") == 0); - instrument_type = metrics_sdk::InstrumentType::kObservableGauge; + InstrumentType = metrics_sdk::InstrumentType::kObservableGauge; } +} - // InstrumentUnit - matlab::data::StringArray unit_mda = constructor_arguments[4]; - auto instrument_unit = static_cast(unit_mda[0]); - - - // MeterName - matlab::data::StringArray meter_name_mda = constructor_arguments[5]; - auto meter_name = static_cast(meter_name_mda[0]); +void ViewProxy::setInstrumentUnit(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray instrumentunit_mda = context.inputs[0]; + InstrumentUnit = static_cast(instrumentunit_mda[0]); +} - // MeterVersion - matlab::data::StringArray meter_version_mda = constructor_arguments[6]; - auto meter_version = static_cast(meter_version_mda[0]); +void ViewProxy::setMeterName(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray metername_mda = context.inputs[0]; + MeterName = static_cast(metername_mda[0]); +} - // MeterSchema - matlab::data::StringArray meter_schema_mda = constructor_arguments[7]; - auto meter_schema = static_cast(meter_schema_mda[0]); +void ViewProxy::setMeterVersion(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray meterversion_mda = context.inputs[0]; + MeterVersion = static_cast(meterversion_mda[0]); +} - // FilterAttributes (a boolean indicating whether AllowedAttributes has been specified) - matlab::data::TypedArray filter_attributes_mda = constructor_arguments[8]; - bool filter_attributes = filter_attributes_mda[0]; +void ViewProxy::setMeterSchema(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray meterschema_mda = context.inputs[0]; + MeterSchema = static_cast(meterschema_mda[0]); +} - // AllowedAttributes - std::unique_ptr attributes_processor; - matlab::data::StringArray attributes_mda = constructor_arguments[9]; - std::unordered_map allowed_attribute_keys; - for (size_t a=0; a(attributes_mda[a]); - if (!attr.empty()) { - allowed_attribute_keys[attr] = true; - } +void ViewProxy::setAllowedAttributes(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray attributes_mda = context.inputs[0]; + if (attributes_mda.getNumberOfElements() == 1 && static_cast(attributes_mda[0]).compare(u"*") == 0) { + FilterAttributes = false; + } else { + FilterAttributes = true; + AllowedAttributes.clear(); // clear all previous entries + for (size_t a=0; a(attributes_mda[a]); + if (!attr.empty()) { + AllowedAttributes[attr] = true; + } + } } +} - // Aggregation - matlab::data::StringArray aggregation_type_mda = constructor_arguments[10]; +void ViewProxy::setAggregation(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray aggregation_type_mda = context.inputs[0]; matlab::data::String aggregation_type_str = aggregation_type_mda[0]; - metrics_sdk::AggregationType aggregation_type; if (aggregation_type_str.compare(u"sum") == 0) { - aggregation_type = metrics_sdk::AggregationType::kSum; + Aggregation = metrics_sdk::AggregationType::kSum; } else if (aggregation_type_str.compare(u"drop") == 0) { - aggregation_type = metrics_sdk::AggregationType::kDrop; + Aggregation = metrics_sdk::AggregationType::kDrop; } else if (aggregation_type_str.compare(u"lastvalue") == 0) { - aggregation_type = metrics_sdk::AggregationType::kLastValue; + Aggregation = metrics_sdk::AggregationType::kLastValue; } else if (aggregation_type_str.compare(u"histogram") == 0) { - aggregation_type = metrics_sdk::AggregationType::kHistogram; + Aggregation = metrics_sdk::AggregationType::kHistogram; } else { assert(aggregation_type_str.compare(u"default") == 0); - aggregation_type = metrics_sdk::AggregationType::kDefault; + Aggregation = metrics_sdk::AggregationType::kDefault; } +} - // HistogramBinEdges - std::vector histogramBinEdges; - if(aggregation_type == metrics_sdk::AggregationType::kHistogram || - (aggregation_type == metrics_sdk::AggregationType::kDefault && instrument_type == metrics_sdk::InstrumentType::kHistogram)){ - matlab::data::TypedArray histogramBinEdges_mda = constructor_arguments[11]; - for (auto h : histogramBinEdges_mda) { - histogramBinEdges.push_back(h); - } +void ViewProxy::setHistogramBinEdges(libmexclass::proxy::method::Context& context) { + matlab::data::TypedArray histogramBinEdges_mda = context.inputs[0]; + for (auto h : histogramBinEdges_mda) { + HistogramBinEdges.push_back(h); } - - // Call View Proxy Constructor - return std::make_shared(std::move(name), std::move(description), std::move(instrument_name), instrument_type, - std::move(instrument_unit), std::move(meter_name), std::move(meter_version), std::move(meter_schema), - std::move(allowed_attribute_keys), filter_attributes, aggregation_type, std::move(histogramBinEdges)); } - + +// Methods to generate input objects for MeterProvider.addView std::unique_ptr ViewProxy::getView(){ // AttributesProcessor std::unique_ptr attributes_processor; diff --git a/test/tmetrics_sdk.m b/test/tmetrics_sdk.m index b716392..e908b65 100644 --- a/test/tmetrics_sdk.m +++ b/test/tmetrics_sdk.m @@ -317,8 +317,10 @@ function testViewAttributes(testCase) % testViewAttributes: filter out attributes metername = "foo"; countername = "bar"; - view = opentelemetry.sdk.metrics.View(InstrumentType="Counter", ... - InstrumentName=countername, AllowedAttributes="Building"); + view = opentelemetry.sdk.metrics.View; + view.InstrumentType = "Counter"; + view.InstrumentName = countername; + view.AllowedAttributes= "Building"; mp = opentelemetry.sdk.metrics.MeterProvider(... testCase.ShortIntervalReader, View=view); @@ -349,6 +351,57 @@ function testViewAttributes(testCase) verifyEqual(testCase, dp.attributes(1).value.doubleValue, 1); end + function testViewAllowAllAttributes(testCase) + % testViewAllowAllAttributes: Specify AllowedAttributes to + % allow all + metername = "foo"; + countername = "bar"; + buildingattr = "Building"; + roomattr = "Room"; + view = opentelemetry.sdk.metrics.View; + view.InstrumentType = "Counter"; + view.InstrumentName = countername; + view.AllowedAttributes= "*"; % allow all attributes + mp = opentelemetry.sdk.metrics.MeterProvider(... + testCase.ShortIntervalReader, View=view); + + m = getMeter(mp, metername); + c = createCounter(m, countername); + + % add values + values1 = [10 50]; + values2 = [20 60]; + add(c, values1(1), buildingattr, 1, roomattr, 1); + add(c, values2(1), buildingattr, 1, roomattr, 2); + add(c, values1(2), buildingattr, 1, roomattr, 1); + add(c, values2(2), buildingattr, 1, roomattr, 2); + + pause(testCase.WaitTime); + + clear mp; + results = readJsonResults(testCase); + results = results{end}; + + % verify counter name + verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.metrics.name), countername); + + % verify all attributes are included + dp = results.resourceMetrics.scopeMetrics.metrics.sum.dataPoints; + verifyLength(testCase, dp, 2); + verifyLength(testCase, dp(1).attributes, 2); + attrkeys = string({dp(1).attributes.key}); + buildingidx = find(attrkeys == buildingattr); + roomidx = find(attrkeys == roomattr); + verifyNotEmpty(testCase, buildingidx); + verifyNotEmpty(testCase, roomidx); + + % verify counts are correct + roomidx = [dp(1).attributes(roomidx).value.doubleValue ... + dp(2).attributes(roomidx).value.doubleValue]; + verifyEqual(testCase, dp(roomidx==1).asDouble, sum(values1)); + verifyEqual(testCase, dp(roomidx==2).asDouble, sum(values2)); + end + function testMultipleViews(testCase) % testMultipleView: Applying multiple views to a meter provider @@ -359,8 +412,10 @@ function testMultipleViews(testCase) % match meter name metermatch_name = "match_meter_name"; - metermatch = opentelemetry.sdk.metrics.View(Name=metermatch_name, .... - InstrumentType="Counter", MeterName = "abc"); + metermatch = opentelemetry.sdk.metrics.View; + metermatch.Name = metermatch_name; + metermatch.InstrumentType = "Counter"; + metermatch.MeterName = "abc"; mp = opentelemetry.sdk.metrics.MeterProvider(... testCase.ShortIntervalReader, View=instmatch); addView(mp, metermatch);