Skip to content

Commit 68a6960

Browse files
committed
refactor startSpan in TracerProxy to improve performance
1 parent 3b0a82a commit 68a6960

File tree

5 files changed

+235
-115
lines changed

5 files changed

+235
-115
lines changed

api/trace/+opentelemetry/+trace/Span.m

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,15 @@ function endSpan(obj, endtime)
4545
%
4646
% See also OPENTELEMETRY.TRACE.TRACER.STARTSPAN
4747
if nargin < 2
48-
endposixtime = NaN;
48+
obj.Proxy.endSpan();
4949
else
5050
if ~(isdatetime(endtime) && isscalar(endtime) && ~isnat(endtime))
5151
% invalid end time, ignore
52-
endposixtime = NaN;
52+
obj.Proxy.endSpan();
5353
else
54-
endposixtime = posixtime(endtime);
54+
obj.Proxy.endSpan(posixtime(endtime));
5555
end
5656
end
57-
obj.Proxy.endSpan(endposixtime);
5857
obj.Ended = true;
5958
end
6059

api/trace/+opentelemetry/+trace/Tracer.m

Lines changed: 88 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
classdef Tracer < handle
22
% A tracer that is used to create spans.
33

4-
% Copyright 2023 The MathWorks, Inc.
4+
% Copyright 2023-2024 The MathWorks, Inc.
55

66
properties (SetAccess=immutable)
77
Name (1,1) string % Tracer name
@@ -42,77 +42,108 @@
4242
% a dictionary.
4343
% "Links" - Link objects that specifies relationships
4444
% with other spans.
45-
%
45+
%
4646
% See also OPENTELEMETRY.TRACE.SPAN,
4747
% OPENTELEMETRY.TRACE.LINK, OPENTELEMETRY.CONTEXT.CONTEXT
48-
arguments
49-
obj
50-
spname
48+
arguments
49+
obj
50+
spname
5151
end
5252
arguments (Repeating)
5353
trailingnames
5454
trailingvalues
5555
end
56+
5657
import opentelemetry.common.processAttributes
57-
% validate the trailing names and values
58-
optionnames = ["Context", "SpanKind", "StartTime", "Attributes", "Links"];
59-
% define default values
60-
contextid = intmax("uint64"); % default value which means no context supplied
61-
spankind = "internal";
62-
starttime = NaN;
63-
attributekeys = string.empty();
64-
attributevalues = {};
65-
links = {};
66-
% Loop through Name-Value pairs
67-
for i = 1:length(trailingnames)
68-
try
69-
namei = validatestring(trailingnames{i}, optionnames);
70-
catch
71-
% invalid option, ignore
72-
continue
73-
end
74-
if strcmp(namei, "Context")
75-
context = trailingvalues{i};
76-
if isa(context, "opentelemetry.context.Context")
77-
contextid = context.Proxy.ID;
78-
end
79-
elseif strcmp(namei, "SpanKind")
58+
59+
if nargin == 2
60+
spname = opentelemetry.common.mustBeScalarString(spname);
61+
id = obj.Proxy.startSpanWithNameOnly(spname);
62+
spanproxy = libmexclass.proxy.Proxy("Name", ...
63+
"libmexclass.opentelemetry.SpanProxy", "ID", id);
64+
span = opentelemetry.trace.Span(spanproxy, spname);
65+
else
66+
67+
% validate the trailing names and values
68+
optionnames = ["Context", "SpanKind", "StartTime", "Attributes", "Links"];
69+
% define default values
70+
contextid = intmax("uint64"); % default value which means no context supplied
71+
spankind = "internal";
72+
starttime = NaN;
73+
attributekeys = string.empty();
74+
attributevalues = {};
75+
links = {};
76+
% variables to keep track of which proxy function to call
77+
specifyoptions = false;
78+
specifyattributes = false;
79+
80+
% Loop through Name-Value pairs
81+
for i = 1:length(trailingnames)
8082
try
81-
spankind = validatestring(trailingvalues{i}, ...
82-
["internal", "server", "client", "producer", "consumer"]);
83+
namei = validatestring(trailingnames{i}, optionnames);
8384
catch
84-
% invalid span kind. Ignore
85+
% invalid option, ignore
86+
continue
8587
end
86-
elseif strcmp(namei, "StartTime")
87-
valuei = trailingvalues{i};
88-
if isdatetime(valuei) && isscalar(valuei) && ~isnat(valuei)
89-
starttime = posixtime(valuei);
90-
end
91-
elseif strcmp(namei, "Attributes")
92-
[attributekeys, attributevalues] = processAttributes(trailingvalues{i}, true);
93-
elseif strcmp(namei, "Links")
94-
valuei = trailingvalues{i};
95-
if isa(valuei, "opentelemetry.trace.Link")
96-
nlinks = numel(valuei);
97-
links = cell(3,nlinks);
98-
for li = 1:nlinks
99-
links{1,li} = valuei(li).Target.Proxy.ID;
100-
linkattrs = valuei(li).Attributes;
101-
[linkattrkeys, linkattrvalues] = processAttributes(linkattrs, true);
102-
links{2,li} = linkattrkeys;
103-
links{3,li} = linkattrvalues;
88+
if strcmp(namei, "Context")
89+
context = trailingvalues{i};
90+
if isa(context, "opentelemetry.context.Context")
91+
contextid = context.Proxy.ID;
92+
specifyoptions = true;
10493
end
105-
links = reshape(links,1,[]); % flatten into a row vector
94+
elseif strcmp(namei, "SpanKind")
95+
try
96+
spankind = validatestring(trailingvalues{i}, ...
97+
["internal", "server", "client", "producer", "consumer"]);
98+
specifyoptions = true;
99+
catch
100+
% invalid span kind. Ignore
101+
end
102+
elseif strcmp(namei, "StartTime")
103+
valuei = trailingvalues{i};
104+
if isdatetime(valuei) && isscalar(valuei) && ~isnat(valuei)
105+
starttime = posixtime(valuei);
106+
specifyoptions = true;
107+
end
108+
elseif strcmp(namei, "Attributes")
109+
[attributekeys, attributevalues] = processAttributes(trailingvalues{i}, true);
110+
specifyattributes = true;
111+
elseif strcmp(namei, "Links")
112+
valuei = trailingvalues{i};
113+
if isa(valuei, "opentelemetry.trace.Link")
114+
nlinks = numel(valuei);
115+
links = cell(3,nlinks);
116+
for li = 1:nlinks
117+
links{1,li} = valuei(li).Target.Proxy.ID;
118+
linkattrs = valuei(li).Attributes;
119+
[linkattrkeys, linkattrvalues] = processAttributes(linkattrs, true);
120+
links{2,li} = linkattrkeys;
121+
links{3,li} = linkattrvalues;
122+
end
123+
links = reshape(links,1,[]); % flatten into a row vector
124+
specifyattributes = true;
125+
end
126+
106127
end
107-
108128
end
129+
spname = opentelemetry.common.mustBeScalarString(spname);
130+
if ~specifyoptions && ~specifyattributes
131+
id = obj.Proxy.startSpanWithNameOnly(spname);
132+
elseif specifyoptions && ~specifyattributes
133+
id = obj.Proxy.startSpanWithNameAndOptions(spname, ...
134+
contextid, spankind, starttime);
135+
elseif ~specifyoptions && specifyattributes
136+
id = obj.Proxy.startSpanWithNameAndAttributes(spname, ...
137+
attributekeys, attributevalues, links{:});
138+
else % specifyoptions && specifyattributes
139+
id = obj.Proxy.startSpanWithNameOptionsAttributes(spname, ...
140+
contextid, spankind, starttime, attributekeys, attributevalues, links{:});
141+
end
142+
143+
spanproxy = libmexclass.proxy.Proxy("Name", ...
144+
"libmexclass.opentelemetry.SpanProxy", "ID", id);
145+
span = opentelemetry.trace.Span(spanproxy, spname);
109146
end
110-
spname = opentelemetry.common.mustBeScalarString(spname);
111-
id = obj.Proxy.startSpan(spname, contextid, spankind, starttime, ...
112-
attributekeys, attributevalues, links{:});
113-
spanproxy = libmexclass.proxy.Proxy("Name", ...
114-
"libmexclass.opentelemetry.SpanProxy", "ID", id);
115-
span = opentelemetry.trace.Span(spanproxy, spname);
116147
end
117148
end
118149

api/trace/include/opentelemetry-matlab/trace/TracerProxy.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2023 The MathWorks, Inc.
1+
// Copyright 2023-2024 The MathWorks, Inc.
22

33
#pragma once
44

@@ -14,10 +14,19 @@ namespace libmexclass::opentelemetry {
1414
class TracerProxy : public libmexclass::proxy::Proxy {
1515
public:
1616
TracerProxy(nostd::shared_ptr<trace_api::Tracer> tr) : CppTracer(tr) {
17-
REGISTER_METHOD(TracerProxy, startSpan);
17+
REGISTER_METHOD(TracerProxy, startSpanWithNameOnly);
18+
REGISTER_METHOD(TracerProxy, startSpanWithNameAndOptions);
19+
REGISTER_METHOD(TracerProxy, startSpanWithNameAndAttributes);
20+
REGISTER_METHOD(TracerProxy, startSpanWithNameOptionsAttributes);
1821
}
1922

20-
void startSpan(libmexclass::proxy::method::Context& context);
23+
void startSpanWithNameOnly(libmexclass::proxy::method::Context& context);
24+
25+
void startSpanWithNameAndOptions(libmexclass::proxy::method::Context& context);
26+
27+
void startSpanWithNameAndAttributes(libmexclass::proxy::method::Context& context);
28+
29+
void startSpanWithNameOptionsAttributes(libmexclass::proxy::method::Context& context);
2130

2231
private:
2332

api/trace/src/SpanProxy.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2023 The MathWorks, Inc.
1+
// Copyright 2023-2024 The MathWorks, Inc.
22

33
#include "opentelemetry-matlab/trace/SpanProxy.h"
44
#include "opentelemetry-matlab/trace/ScopeProxy.h"
@@ -34,9 +34,9 @@ libmexclass::proxy::MakeResult SpanProxy::make(const libmexclass::proxy::Functio
3434
}
3535

3636
void SpanProxy::endSpan(libmexclass::proxy::method::Context& context) {
37-
matlab::data::TypedArray<double> endtime_mda = context.inputs[0];
38-
double endtime = endtime_mda[0]; // number of seconds since 1/1/1970 (i.e. POSIX time)
39-
if (endtime==endtime) { // not NaN. NaN means not specified
37+
if (context.inputs.getNumberOfElements() > 0) {
38+
matlab::data::TypedArray<double> endtime_mda = context.inputs[0];
39+
double endtime = endtime_mda[0]; // number of seconds since 1/1/1970 (i.e. POSIX time)
4040
trace_api::EndSpanOptions options;
4141
// conversion between system_time and steady_time
4242
common::SystemTimestamp end_system_time{std::chrono::duration<double>(endtime)};
@@ -87,7 +87,7 @@ void SpanProxy::addEvent(libmexclass::proxy::method::Context& context) {
8787
std::string eventname = static_cast<std::string>(eventname_mda[0]);
8888
matlab::data::TypedArray<double> eventtime_mda = context.inputs[1];
8989
common::SystemTimestamp eventtime{std::chrono::duration<double>{eventtime_mda[0]}};
90-
size_t nin = context.inputs.getNumberOfElements();
90+
const size_t nin = context.inputs.getNumberOfElements();
9191
// attributes
9292
ProcessedAttributes eventattrs;
9393
for (size_t i = 2, count = 0; i < nin; i += 2, ++count) {
@@ -106,17 +106,17 @@ void SpanProxy::addEvent(libmexclass::proxy::method::Context& context) {
106106

107107
void SpanProxy::setStatus(libmexclass::proxy::method::Context& context) {
108108
matlab::data::StringArray status_mda = context.inputs[0];
109-
std::string status = static_cast<std::string>(status_mda[0]);
109+
matlab::data::MATLABString status = status_mda[0];
110110
matlab::data::StringArray descr_mda = context.inputs[1];
111111
std::string descr = static_cast<std::string>(descr_mda[0]);
112112

113113
trace_api::StatusCode code;
114-
if (status.compare("Unset")==0) {
114+
if (status->compare(u"Unset")==0) {
115115
code = trace_api::StatusCode::kUnset;
116-
} else if (status.compare("Ok")==0) {
116+
} else if (status->compare(u"Ok")==0) {
117117
code = trace_api::StatusCode::kOk;
118118
} else {
119-
assert(status.compare("Error")==0);
119+
assert(status->compare(u"Error")==0);
120120
code = trace_api::StatusCode::kError;
121121
}
122122
CppSpan->SetStatus(code, descr);

0 commit comments

Comments
 (0)