Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an AutoTrace example #174

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading