Skip to content

Commit

Permalink
Change sdk class constructors to accept N-V pairs without first argum…
Browse files Browse the repository at this point in the history
…ent, closes #22
  • Loading branch information
duncanpo committed Sep 4, 2024
1 parent 52c6af2 commit e1b8944
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 220 deletions.
42 changes: 27 additions & 15 deletions sdk/logs/+opentelemetry/+sdk/+logs/BatchLogRecordProcessor.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
end

methods
function obj = BatchLogRecordProcessor(exporter, optionnames, optionvalues)
function obj = BatchLogRecordProcessor(varargin)
% Batch log record processor creates batches of log records and passes them to an exporter.
% BLP = OPENTELEMETRY.SDK.LOGS.BATCHLOGRECORDPROCESSOR creates a
% batch log record processor that uses an OTLP HTTP exporter, which
Expand All @@ -20,7 +20,7 @@
% the log record exporter. Supported log record exporters are OTLP HTTP
% exporter and OTLP gRPC exporter.
%
% BLP = OPENTELEMETRY.SDK.LOGS.BATCHLOGRECORDPROCESSOR(EXP, PARAM1,
% BLP = OPENTELEMETRY.SDK.LOGS.BATCHLOGRECORDPROCESSOR(..., PARAM1,
% VALUE1, PARAM2, VALUE2, ...) specifies optional parameter
% name/value pairs. Parameters are:
% "MaximumQueueSize" - Maximum queue size. After queue
Expand All @@ -35,24 +35,18 @@
% OPENTELEMETRY.EXPORTERS.OTLP.OTLPHTTPLOGRECORDEXPORTER,
% OPENTELEMETRY.EXPORTERS.OTLP.OTLPGRPCLOGRECORDEXPORTER,
% OPENTELEMETRY.SDK.LOGS.LOGGERPROVIDER
arguments
exporter {mustBeA(exporter, "opentelemetry.sdk.logs.LogRecordExporter")} = ...
opentelemetry.exporters.otlp.defaultLogRecordExporter()
end
arguments (Repeating)
optionnames (1,:) {mustBeTextScalar}
optionvalues

if nargin == 0 || ~isa(varargin{1}, "opentelemetry.sdk.logs.LogRecordExporter")
exporter = opentelemetry.exporters.otlp.defaultLogRecordExporter;
else % isa(varargin{1}, "opentelemetry.sdk.logs.LogRecordExporter")
exporter = varargin{1};
varargin(1) = [];
end

obj = [email protected](exporter, ...
"libmexclass.opentelemetry.sdk.BatchLogRecordProcessorProxy");

validnames = ["MaximumQueueSize", "ScheduledDelay", "MaximumExportBatchSize"];
for i = 1:length(optionnames)
namei = validatestring(optionnames{i}, validnames);
valuei = optionvalues{i};
obj.(namei) = valuei;
end
obj = obj.processOptions(varargin{:});
end

function obj = set.MaximumQueueSize(obj, maxqsz)
Expand Down Expand Up @@ -86,4 +80,22 @@
obj.MaximumExportBatchSize = maxbatch;
end
end

methods(Access=private)
function obj = processOptions(obj, optionnames, optionvalues)
arguments
obj
end
arguments (Repeating)
optionnames (1,:) {mustBeTextScalar}
optionvalues
end
validnames = ["MaximumQueueSize", "ScheduledDelay", "MaximumExportBatchSize"];
for i = 1:length(optionnames)
namei = validatestring(optionnames{i}, validnames);
valuei = optionvalues{i};
obj.(namei) = valuei;
end
end
end
end
98 changes: 55 additions & 43 deletions sdk/logs/+opentelemetry/+sdk/+logs/LoggerProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
end

methods
function obj = LoggerProvider(processor, optionnames, optionvalues)
function obj = LoggerProvider(varargin)
% SDK implementation of logger provider
% LP = OPENTELEMETRY.SDK.LOGS.LOGGERPROVIDER creates a logger
% provider that uses a simple log record processor and default configurations.
%
% LP = OPENTELEMETRY.SDK.LOGS.LOGGERPROVIDER(P) uses log record
% processor P. P can be a simple or batched log record processor.
%
% LP = OPENTELEMETRY.SDK.LOGS.LOGGERPROVIDER(R, PARAM1, VALUE1,
% LP = OPENTELEMETRY.SDK.LOGS.LOGGERPROVIDER(..., PARAM1, VALUE1,
% PARAM2, VALUE2, ...) specifies optional parameter name/value pairs.
% Parameters are:
% "Resource" - Additional resource attributes.
Expand All @@ -31,60 +31,28 @@
% See also OPENTELEMETRY.SDK.LOGS.SIMPLELOGRECORDPROCESSOR,
% OPENTELEMETRY.SDK.LOGS.BATCHLOGRECORDPROCESSOR

arguments
processor {mustBeA(processor, ["opentelemetry.sdk.logs.LogRecordProcessor", ...
"libmexclass.proxy.Proxy"])} = ...
opentelemetry.sdk.logs.SimpleLogRecordProcessor()
end
arguments (Repeating)
optionnames (1,:) {mustBeTextScalar}
optionvalues
end

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

if isa(processor, "libmexclass.proxy.Proxy")
if nargin == 1 && isa(varargin{1}, "libmexclass.proxy.Proxy")
% This code branch is used to support conversion from API
% LoggerProvider to SDK equivalent, needed internally by
% opentelemetry.sdk.logs.Cleanup
lpproxy = processor; % rename the variable
lpproxy = varargin{1};
assert(lpproxy.Name == "libmexclass.opentelemetry.LoggerProviderProxy");
obj.Proxy = libmexclass.proxy.Proxy("Name", ...
"libmexclass.opentelemetry.sdk.LoggerProviderProxy", ...
"ConstructorArguments", {lpproxy.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:logs:LoggerProvider: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
if nargin == 0 || ~isa(varargin{1}, "opentelemetry.sdk.logs.LogRecordProcessor")
processor = opentelemetry.sdk.logs.SimpleLogRecordProcessor(); % default processor
else
processor = varargin{1};
varargin(1) = [];
end

obj.Proxy = libmexclass.proxy.Proxy("Name", ...
"libmexclass.opentelemetry.sdk.LoggerProviderProxy", ...
"ConstructorArguments", {processor.Proxy.ID, resourcekeys, ...
resourcevalues});
obj.LogRecordProcessor = processor;
obj.Resource = resource;
obj.processOptions(processor, varargin{:});

end
end

Expand Down Expand Up @@ -139,4 +107,48 @@ function addLogRecordProcessor(obj, processor)
end
end
end

methods(Access=private)
function processOptions(obj, processor, optionnames, optionvalues)
arguments
obj
processor
end
arguments (Repeating)
optionnames (1,:) {mustBeTextScalar}
optionvalues
end

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:logs:LoggerProvider: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.LoggerProviderProxy", ...
"ConstructorArguments", {processor.Proxy.ID, resourcekeys, ...
resourcevalues});
obj.LogRecordProcessor = processor;
obj.Resource = resource;
end
end
end
124 changes: 67 additions & 57 deletions sdk/metrics/+opentelemetry/+sdk/+metrics/MeterProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
% An SDK implementation of meter provider, which stores a set of configurations used
% in a metrics system.

% Copyright 2023 The MathWorks, Inc.
% Copyright 2023-2024 The MathWorks, Inc.

properties(Access=private)
isShutdown (1,1) logical = false
Expand All @@ -15,7 +15,7 @@
end

methods
function obj = MeterProvider(reader, optionnames, optionvalues)
function obj = MeterProvider(varargin)
% 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 @@ -24,7 +24,7 @@
% reader R. Currently, the only supported metric reader is the periodic
% exporting metric reader.
%
% TP = OPENTELEMETRY.SDK.METRICS.METERPROVIDER(R, PARAM1, VALUE1,
% TP = OPENTELEMETRY.SDK.METRICS.METERPROVIDER(..., PARAM1, VALUE1,
% PARAM2, VALUE2, ...) specifies optional parameter name/value pairs.
% Parameters are:
% "View" - View object used to customize collected metrics.
Expand All @@ -34,73 +34,27 @@
% See also OPENTELEMETRY.SDK.METRICS.PERIODICEXPORTINGMETRICREADER
% OPENTELEMETRY.SDK.METRICS.VIEW

arguments
reader {mustBeA(reader, ["opentelemetry.sdk.metrics.PeriodicExportingMetricReader", ...
"libmexclass.proxy.Proxy"])} = ...
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");

if isa(reader, "libmexclass.proxy.Proxy")
if nargin == 1 && isa(varargin{1}, "libmexclass.proxy.Proxy")
% This code branch is used to support conversion from API
% MeterProvider to SDK equivalent, needed internally by
% opentelemetry.sdk.metrics.Cleanup
mpproxy = reader; % rename the variable
mpproxy = varargin{1};
assert(mpproxy.Name == "libmexclass.opentelemetry.MeterProviderProxy");
obj.Proxy = libmexclass.proxy.Proxy("Name", ...
"libmexclass.opentelemetry.sdk.MeterProviderProxy", ...
"ConstructorArguments", {mpproxy.ID});
% leave other properties unassigned, they won't be used
else
validnames = ["Resource", "View"];
resourcekeys = string.empty();
resourcevalues = {};
resource = dictionary(resourcekeys, resourcevalues);
suppliedview = false;
viewid = 0;
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
elseif strcmp(namei, "View")
suppliedview = true;
view = valuei;
if ~isa(view, "opentelemetry.sdk.metrics.View")
error("opentelemetry:sdk:metrics:MeterProvider:InvalidViewType", ...
"View input must be a opentelemetry.sdk.metrics.View object.");
end
viewid = view.Proxy.ID;
end
end

obj.Proxy = libmexclass.proxy.Proxy("Name", ...
"libmexclass.opentelemetry.sdk.MeterProviderProxy", ...
"ConstructorArguments", {reader.Proxy.ID, resourcekeys, ...
resourcevalues, suppliedview, viewid});
obj.MetricReader = reader;
obj.Resource = resource;
if suppliedview
obj.View = view;
if nargin == 0 || ~isa(varargin{1}, "opentelemetry.sdk.metrics.PeriodicExportingMetricReader")
reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(); % default metric reader
else
reader = varargin{1};
varargin(1) = [];
end
obj.processOptions(reader, varargin{:});
end
end

Expand Down Expand Up @@ -167,4 +121,60 @@ function addView(obj, view)
end

end

methods(Access=private)
function processOptions(obj, reader, optionnames, optionvalues)
arguments
obj
reader
end
arguments (Repeating)
optionnames (1,:) {mustBeTextScalar}
optionvalues
end

validnames = ["Resource", "View"];
resourcekeys = string.empty();
resourcevalues = {};
resource = dictionary(resourcekeys, resourcevalues);
suppliedview = false;
viewid = 0;
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
elseif strcmp(namei, "View")
suppliedview = true;
view = valuei;
if ~isa(view, "opentelemetry.sdk.metrics.View")
error("opentelemetry:sdk:metrics:MeterProvider:InvalidViewType", ...
"View input must be a opentelemetry.sdk.metrics.View object.");
end
viewid = view.Proxy.ID;
end
end

obj.Proxy = libmexclass.proxy.Proxy("Name", ...
"libmexclass.opentelemetry.sdk.MeterProviderProxy", ...
"ConstructorArguments", {reader.Proxy.ID, resourcekeys, ...
resourcevalues, suppliedview, viewid});
obj.MetricReader = reader;
obj.Resource = resource;
if suppliedview
obj.View = view;
end
end
end
end
Loading

0 comments on commit e1b8944

Please sign in to comment.