Skip to content

Commit

Permalink
Merge pull request #164 from mathworks/autotrace
Browse files Browse the repository at this point in the history
enable specifying folders in AutoTrace options, closes #163
  • Loading branch information
duncanpo authored Oct 29, 2024
2 parents 5b3cff0 + 961c824 commit b012253
Show file tree
Hide file tree
Showing 12 changed files with 266 additions and 46 deletions.
53 changes: 38 additions & 15 deletions auto-instrumentation/+opentelemetry/+autoinstrument/AutoTrace.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,15 @@
options.AdditionalFiles {mustBeText}
options.AutoDetectFiles (1,1) {mustBeNumericOrLogical} = true
end
% check for anonymous function
fs = functions(startfun);
if fs.type == "anonymous"
error("opentelemetry:autoinstrument:AutoTrace:AnonymousFunction", ...
"Anonymous functions are not supported.");
end
obj.StartFunction = startfun;
startfunname = func2str(startfun);
processFileInput(startfunname); % validate startfun
startfunname = processFileInput(startfunname); % validate startfun
if options.AutoDetectFiles
if isdeployed
% matlab.codetools.requiredFilesAndProducts is not
Expand All @@ -76,15 +82,16 @@
end
else
% only include the input file, not its dependencies
files = string(which(startfunname));
files = startfunname;
end
% add extra files, this is intended for files
% matlab.codetools.requiredFilesAndProducts somehow missed
if isfield(options, "AdditionalFiles")
incfiles = string(options.AdditionalFiles);
for i = 1:numel(incfiles)
incfiles(i) = which(incfiles(i)); % get the full path
processFileInput(incfiles(i)); % validate additional file
incinput = string(options.AdditionalFiles);
incfiles = [];
for i = 1:numel(incinput)
% validate additional file
incfiles = [incfiles; processFileOrFolderInput(incinput(i))]; %#ok<AGROW>
end
files = union(files, incfiles);
end
Expand All @@ -94,9 +101,11 @@

% filter out excluded files
if isfield(options, "ExcludeFiles")
excfiles = string(options.ExcludeFiles);
for i = 1:numel(excfiles)
excfiles(i) = which(excfiles(i)); % get the full path
excinput = string(options.ExcludeFiles);
excfiles = [];
for i = 1:numel(excinput)
% validate exclude file
excfiles = [excfiles; processFileOrFolderInput(excinput(i))]; %#ok<AGROW>
end
files = setdiff(files, excfiles);
end
Expand Down Expand Up @@ -155,15 +164,13 @@ function handleError(obj, ME)
end

% check input file is valid
function processFileInput(f)
function f = processFileInput(f)
f = string(f); % force into a string
if startsWith(f, '@') % check for anonymous function
error("opentelemetry:autoinstrument:AutoTrace:AnonymousFunction", ...
replace(f, "\", "\\") + " is an anonymous function and is not supported.");
end
[~,~,fext] = fileparts(f); % check file extension
filetype = exist(f, "file"); % check file type
if ~(filetype == 2 && ismember(fext, ["" ".m" ".mlx"]))
if filetype == 2 && ismember(fext, ["" ".m" ".mlx"])
f = string(which(f));
else
if exist(f, "builtin")
error("opentelemetry:autoinstrument:AutoTrace:BuiltinFunction", ...
replace(f, "\", "\\") + " is a builtin function and is not supported.");
Expand All @@ -172,4 +179,20 @@ function processFileInput(f)
replace(f, "\", "\\") + " is not found or is not a valid MATLAB file with a .m or .mlx extension.");
end
end
end

% check input file or folder is valid
function f = processFileOrFolderInput(f)
f = string(f); % force into a string
if isfolder(f)
% expand the directory
mfileinfo = dir(fullfile(f, "*.m"));
mfiles = fullfile(string({mfileinfo.folder}), string({mfileinfo.name}));
mlxfileinfo = dir(fullfile(f, "*.mlx"));
mlxfiles = fullfile(string({mlxfileinfo.folder}), string({mlxfileinfo.name}));
f = [mfiles; mlxfiles];
else
% file
f = processFileInput(f);
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function yf = best_fit_line(x, y)
% example code for testing auto instrumentation
% Fit a straight line on input data

% Copyright 2024 The MathWorks, Inc.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
function [x, y] = generate_data(n)
% example code for testing auto instrumentation
% Generate random data with n data points

% Copyright 2024 The MathWorks, Inc.

% check input is valid
if ~(isnumeric(n) && isscalar(n))
error("autotrace_examples:example1:generate_data:InvalidN", ...
error("autotrace_examples:linearfit_example:generate_data:InvalidN", ...
"Input must be a numeric scalar");
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function yf = example1(n)
% example code for testing auto instrumentation. Input n is the number of
function yf = linearfit_example(n)
% Example code for testing auto instrumentation. Input n is the number of
% data points.

% Copyright 2024 The MathWorks, Inc.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function yf = example1_trycatch(at, n)
% example code for testing auto instrumentation. This example should not
function yf = linearfit_example_trycatch(at, n)
% Example code for testing auto instrumentation. This example should not
% use beginTrace method and instead should be called directly.

% Copyright 2024 The MathWorks, Inc.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function yf = best_fit_line(x, y)
% Fit a straight line on input data and manually start and end two spans.

% Copyright 2024 The MathWorks, Inc.

tr = opentelemetry.trace.getTracer("ManualInstrument");

sp1 = startSpan(tr, "polyfit");
coefs = polyfit(x, y, 1);
endSpan(sp1);

sp2 = startSpan(tr, "polyval");
yf = polyval(coefs , x);
endSpan(sp2);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function [x, y] = generate_data(n)
% Generate random data with n data points and manually start and end a span.

% Copyright 2024 The MathWorks, Inc.

% check input is valid
if ~(isnumeric(n) && isscalar(n))
error("autotrace_examples:linearfit_example:generate_data:InvalidN", ...
"Input must be a numeric scalar");
end

% generate some random data
a = 1.5;
b = 0.8;
sigma = 5;
x = 1:n;

% start a span
tr = opentelemetry.trace.getTracer("ManualInstrument");
sp = startSpan(tr, "compute_y");
y = a * x + b + sigma * randn(1, n);
endSpan(sp);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function yf = manual_instrumented_example(n)
% Example code for testing auto and manual instrumentation together.
% Input n is the number of data points.

% Copyright 2024 The MathWorks, Inc.

[x, y] = generate_data(n);
yf = best_fit_line(x,y);
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function x = subfolder_helper1(x)
% example code for testing auto instrumentation, helper function

% Copyright 2024 The MathWorks, Inc.

x = x * 2;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function x = subfolder_helper2(x)
% example code for testing auto instrumentation, helper function

% Copyright 2024 The MathWorks, Inc.

x = x * 3;
10 changes: 10 additions & 0 deletions test/autotrace_examples/subfolder_example/subfolder_example.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function x = subfolder_example
% Example code for testing auto instrumentation, with some helper functions
% in a subfolder

% Copyright 2024 The MathWorks, Inc.

x = 10;
x = subfolder_helper1(x);
x = subfolder_helper2(x);

Loading

0 comments on commit b012253

Please sign in to comment.