Skip to content

Commit

Permalink
Merge pull request #174 from mathworks/autotrace
Browse files Browse the repository at this point in the history
Add an AutoTrace example
  • Loading branch information
duncanpo authored Nov 19, 2024
2 parents 6faf264 + 2852b29 commit 140bf85
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 12 deletions.
9 changes: 9 additions & 0 deletions examples/autotrace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# AutoTrace Example
This example shows how to use AutoTrace to automatically instrument MATLAB code. The instrumented code in *autotrace_example.m* fits a line through a cluster of data points. Notice that it does not include any instrumentation code.
The function *run_example.m* first configures a tracer provider. This step only needs to be done once in a MATLAB session. Then it creates an AutoTrace object and runs it. The AutoTrace object gets cleaned up at the end.

## Running the Example
1. Start an instance of [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector).
2. Start MATLAB.
3. Ensure the installation directory of OpenTelemetry-matlab is on the MATLAB path.
4. Run `run_example`.
25 changes: 25 additions & 0 deletions examples/autotrace/autotrace_example.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function yf = autotrace_example
% This example shows some simple MATLAB code that fits a line through a
% cluster of data points. It does not include any instrumentation code.

% Copyright 2024 The MathWorks, Inc.

[x, y] = generate_data();
yf = best_fit_line(x,y);
end

function [x, y] = generate_data
% generate some random data
a = 1.5;
b = 0.8;
sigma = 5;
x = 1:100;
y = a * x + b + sigma * randn(1, 100);
end

function yf = best_fit_line(x, y)
% fit a line through points defined by inputs x and y
coefs = polyfit(x, y, 1);
yf = polyval(coefs , x);
end

16 changes: 16 additions & 0 deletions examples/autotrace/run_example.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function yf = run_example
% Use AutoTrace to automatically instrument an example to produce a trace.

% Copyright 2024 The MathWorks, Inc.

% configure tracer provider
resource = dictionary("service.name", "OpenTelemetry-Matlab_examples");
tp = opentelemetry.sdk.trace.TracerProvider(Resource=resource);
setTracerProvider(tp);

% create AutoTrace object
at = opentelemetry.autoinstrument.AutoTrace(@autotrace_example, ...
TracerName="autotrace_example");

% run the example
yf = beginTrace(at);
3 changes: 1 addition & 2 deletions examples/context_propagation/matlab/mymagic.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@
function initTracer
% set up global TracerProvider
resource = dictionary("service.name", "OpenTelemetry-Matlab_examples");
tp = opentelemetry.sdk.trace.TracerProvider(...
opentelemetry.sdk.trace.SimpleSpanProcessor, Resource=resource);
tp = opentelemetry.sdk.trace.TracerProvider(Resource=resource);
setTracerProvider(tp);

% set up global propagator
Expand Down
3 changes: 1 addition & 2 deletions examples/logs/logs_example.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@
function initLogger
% set up global LoggerProvider
resource = dictionary("service.name", "OpenTelemetry-Matlab_examples");
lp = opentelemetry.sdk.logs.LoggerProvider(...
opentelemetry.sdk.logs.SimpleLogRecordProcessor, Resource=resource);
lp = opentelemetry.sdk.logs.LoggerProvider(Resource=resource);
setLoggerProvider(lp);
end

Expand Down
3 changes: 1 addition & 2 deletions examples/metrics/metrics_example.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ function metrics_example(iterations)

function initMetrics
% set up global MeterProvider
exp = opentelemetry.exporters.otlp.defaultMetricExporter();
reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(exp, ...
reader = opentelemetry.sdk.metrics.PeriodicExportingMetricReader(...
"Interval", seconds(5), "Timeout", seconds(2.5)); % exports every 5 seconds
% Use custom histogram bins
v = opentelemetry.sdk.metrics.View(InstrumentType="histogram", HistogramBinEdges=0:10:100);
Expand Down
3 changes: 1 addition & 2 deletions examples/parallel/parfor_example.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@
function initTracer
% set up global TracerProvider
resource = dictionary("service.name", "OpenTelemetry-Matlab_examples");
tp = opentelemetry.sdk.trace.TracerProvider(...
opentelemetry.sdk.trace.SimpleSpanProcessor, Resource=resource);
tp = opentelemetry.sdk.trace.TracerProvider(Resource=resource);
setTracerProvider(tp);

% set up global propagator
Expand Down
3 changes: 1 addition & 2 deletions examples/trace/trace_example.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@
function initTracer
% set up global TracerProvider
resource = dictionary("service.name", "OpenTelemetry-Matlab_examples");
tp = opentelemetry.sdk.trace.TracerProvider(...
opentelemetry.sdk.trace.SimpleSpanProcessor, Resource=resource);
tp = opentelemetry.sdk.trace.TracerProvider(Resource=resource);
setTracerProvider(tp);
end

Expand Down
3 changes: 1 addition & 2 deletions examples/webread/matlab/webread_example.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
function initTracer
% set up global TracerProvider
resource = dictionary("service.name", "OpenTelemetry-Matlab_examples");
tp = opentelemetry.sdk.trace.TracerProvider(...
opentelemetry.sdk.trace.SimpleSpanProcessor, Resource=resource);
tp = opentelemetry.sdk.trace.TracerProvider(Resource=resource);
setTracerProvider(tp);

% set up global propagator
Expand Down
58 changes: 58 additions & 0 deletions test/texamples.m
Original file line number Diff line number Diff line change
Expand Up @@ -370,5 +370,63 @@ function testParallel(testCase)
verifyLessThanOrEqual(testCase, str2double(worker2.resourceSpans.scopeSpans.spans.endTimeUnixNano), ...
str2double(toplevel.resourceSpans.scopeSpans.spans.endTimeUnixNano));
end

function testAutoTrace(testCase)
% testAutoTrace: AutoTrace example in examples/autotrace folder

% add the example folder to the path
examplefolder = fullfile(fileparts(mfilename('fullpath')), "..", "examples", "autotrace");
testCase.applyFixture(matlab.unittest.fixtures.PathFixture(examplefolder));

% run the example
run_example;

% perform test comparisons
results = readJsonResults(testCase);
verifyNumElements(testCase, results, 3);

% check generate_data span
gendata = results{1};
verifyEqual(testCase, gendata.resourceSpans.scopeSpans.scope.name, 'autotrace_example');
verifyEqual(testCase, gendata.resourceSpans.scopeSpans.spans.name, 'generate_data');
verifyEqual(testCase, gendata.resourceSpans.scopeSpans.spans.kind, 1);
service_name_idx = find(string({gendata.resourceSpans.resource.attributes.key}) == "service.name");
verifyNotEmpty(testCase, service_name_idx);
verifyEqual(testCase, gendata.resourceSpans.resource.attributes(service_name_idx).value.stringValue, ...
'OpenTelemetry-Matlab_examples');

% check best_fit_line span
bestfitline = results{2};
verifyEqual(testCase, bestfitline.resourceSpans.scopeSpans.scope.name, 'autotrace_example');
verifyEqual(testCase, bestfitline.resourceSpans.scopeSpans.spans.name, 'best_fit_line');
verifyEqual(testCase, bestfitline.resourceSpans.scopeSpans.spans.kind, 1);

% check top level function span
toplevel = results{3};
verifyEqual(testCase, toplevel.resourceSpans.scopeSpans.scope.name, 'autotrace_example');
verifyEqual(testCase, toplevel.resourceSpans.scopeSpans.spans.name, 'autotrace_example');
verifyEqual(testCase, toplevel.resourceSpans.scopeSpans.spans.kind, 1);

% check parent child relationships
verifyEqual(testCase, gendata.resourceSpans.scopeSpans.spans.parentSpanId, ...
toplevel.resourceSpans.scopeSpans.spans.spanId);
verifyEqual(testCase, bestfitline.resourceSpans.scopeSpans.spans.parentSpanId, ...
toplevel.resourceSpans.scopeSpans.spans.spanId);
verifyEmpty(testCase, toplevel.resourceSpans.scopeSpans.spans.parentSpanId);

% check all spans belong to the same trace
verifyEqual(testCase, gendata.resourceSpans.scopeSpans.spans.traceId, ...
toplevel.resourceSpans.scopeSpans.spans.traceId);
verifyEqual(testCase, bestfitline.resourceSpans.scopeSpans.spans.traceId, ...
toplevel.resourceSpans.scopeSpans.spans.traceId);

% check for expected timing
verifyLessThanOrEqual(testCase, str2double(toplevel.resourceSpans.scopeSpans.spans.startTimeUnixNano), ...
str2double(gendata.resourceSpans.scopeSpans.spans.startTimeUnixNano));
verifyLessThanOrEqual(testCase, str2double(gendata.resourceSpans.scopeSpans.spans.endTimeUnixNano), ...
str2double(bestfitline.resourceSpans.scopeSpans.spans.startTimeUnixNano));
verifyLessThanOrEqual(testCase, str2double(bestfitline.resourceSpans.scopeSpans.spans.endTimeUnixNano), ...
str2double(toplevel.resourceSpans.scopeSpans.spans.endTimeUnixNano));
end
end
end

0 comments on commit 140bf85

Please sign in to comment.