diff --git a/auto-instrumentation/+opentelemetry/+autoinstrument/AutoTrace.m b/auto-instrumentation/+opentelemetry/+autoinstrument/AutoTrace.m index 7bb6353..e724cf8 100644 --- a/auto-instrumentation/+opentelemetry/+autoinstrument/AutoTrace.m +++ b/auto-instrumentation/+opentelemetry/+autoinstrument/AutoTrace.m @@ -1,7 +1,7 @@ classdef AutoTrace < handle % Automatic instrumentation with OpenTelemetry tracing. - % Copyright 2024 The MathWorks, Inc. + % Copyright 2024-2025 The MathWorks, Inc. properties (SetAccess=private) StartFunction function_handle % entry function @@ -71,7 +71,8 @@ if isdeployed % matlab.codetools.requiredFilesAndProducts is not % deployable. Instead instrument all files under CTFROOT - fileinfo = dir(fullfile(ctfroot, "**", "*.m")); + fileinfo = [reshape(dir(fullfile(ctfroot, "**", "*.m")), [], 1); ... + reshape(dir(fullfile(ctfroot, "**", "*.mlx")), [], 1)]; files = fullfile(string({fileinfo.folder}), string({fileinfo.name})); % filter out internal files in the toolbox directory @@ -79,6 +80,10 @@ else %#exclude matlab.codetools.requiredFilesAndProducts files = string(matlab.codetools.requiredFilesAndProducts(startfunname)); + + % keep only .m and .mlx files. Filter out everything else + [~,~,fext] = fileparts(files); + files = files(ismember(fext, [".m" ".mlx"])); end else % only include the input file, not its dependencies @@ -190,7 +195,7 @@ function handleError(obj, ME) mfiles = fullfile(string({mfileinfo.folder}), string({mfileinfo.name})); mlxfileinfo = dir(fullfile(f, "*.mlx")); mlxfiles = fullfile(string({mlxfileinfo.folder}), string({mlxfileinfo.name})); - f = [mfiles; mlxfiles]; + f = [mfiles(:); mlxfiles(:)]; else % file f = processFileInput(f); diff --git a/test/autotrace_examples/matfile_example/matfile_example.m b/test/autotrace_examples/matfile_example/matfile_example.m new file mode 100644 index 0000000..cacddaa --- /dev/null +++ b/test/autotrace_examples/matfile_example/matfile_example.m @@ -0,0 +1,7 @@ +function y = matfile_example +% Example code for testing auto instrumentation, which loads a .mat file + +% Copyright 2025 The MathWorks, Inc. + +load("mymagic", "x"); +y = sum(x); \ No newline at end of file diff --git a/test/autotrace_examples/matfile_example/mymagic.mat b/test/autotrace_examples/matfile_example/mymagic.mat new file mode 100644 index 0000000..c8afb9a Binary files /dev/null and b/test/autotrace_examples/matfile_example/mymagic.mat differ diff --git a/test/autotrace_examples/two_subfolders_example/helper1/subfolder_helper1_1.m b/test/autotrace_examples/two_subfolders_example/helper1/subfolder_helper1_1.m new file mode 100644 index 0000000..ad67add --- /dev/null +++ b/test/autotrace_examples/two_subfolders_example/helper1/subfolder_helper1_1.m @@ -0,0 +1,6 @@ +function x = subfolder_helper1_1(x) +% example code for testing auto instrumentation, helper function + +% Copyright 2025 The MathWorks, Inc. + +x = x * 2; diff --git a/test/autotrace_examples/two_subfolders_example/helper1/subfolder_helper1_2.m b/test/autotrace_examples/two_subfolders_example/helper1/subfolder_helper1_2.m new file mode 100644 index 0000000..ad453a6 --- /dev/null +++ b/test/autotrace_examples/two_subfolders_example/helper1/subfolder_helper1_2.m @@ -0,0 +1,6 @@ +function x = subfolder_helper1_2(x) +% example code for testing auto instrumentation, helper function + +% Copyright 2025 The MathWorks, Inc. + +x = x * 3; \ No newline at end of file diff --git a/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_1.m b/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_1.m new file mode 100644 index 0000000..28ff177 --- /dev/null +++ b/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_1.m @@ -0,0 +1,6 @@ +function x = subfolder_helper2_1(x) +% example code for testing auto instrumentation, helper function + +% Copyright 2025 The MathWorks, Inc. + +x = x * 4; diff --git a/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_2.m b/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_2.m new file mode 100644 index 0000000..dde23fb --- /dev/null +++ b/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_2.m @@ -0,0 +1,6 @@ +function x = subfolder_helper2_2(x) +% example code for testing auto instrumentation, helper function + +% Copyright 2025 The MathWorks, Inc. + +x = x * 5; \ No newline at end of file diff --git a/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_3.m b/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_3.m new file mode 100644 index 0000000..de2312b --- /dev/null +++ b/test/autotrace_examples/two_subfolders_example/helper2/subfolder_helper2_3.m @@ -0,0 +1,6 @@ +function x = subfolder_helper2_3(x) +% example code for testing auto instrumentation, helper function + +% Copyright 2025 The MathWorks, Inc. + +x = x * 5; \ No newline at end of file diff --git a/test/autotrace_examples/two_subfolders_example/two_subfolders_example.m b/test/autotrace_examples/two_subfolders_example/two_subfolders_example.m new file mode 100644 index 0000000..4680c11 --- /dev/null +++ b/test/autotrace_examples/two_subfolders_example/two_subfolders_example.m @@ -0,0 +1,13 @@ +function x = two_subfolders_example +% Example code for testing auto instrumentation, with helper functions +% in a two subfolders + +% Copyright 2025 The MathWorks, Inc. + +x = 10; +x = subfolder_helper1_1(x); +x = subfolder_helper1_2(x); +x = subfolder_helper2_1(x); +x = subfolder_helper2_2(x); +x = subfolder_helper2_3(x); + diff --git a/test/tautotrace.m b/test/tautotrace.m index 3a74696..b1ecd0d 100644 --- a/test/tautotrace.m +++ b/test/tautotrace.m @@ -1,7 +1,7 @@ classdef tautotrace < matlab.unittest.TestCase % tests for AutoTrace - % Copyright 2024 The MathWorks, Inc. + % Copyright 2024-2025 The MathWorks, Inc. properties OtelConfigFile @@ -155,6 +155,35 @@ function testIncludeFolder(testCase) verifyEqual(testCase, results{2}.resourceSpans.scopeSpans.spans.parentSpanId, results{3}.resourceSpans.scopeSpans.spans.spanId); end + function testMultipleIncludeFolders(testCase) + % testMultipleIncludeFolders: specify multiple folders in AdditionalFiles + + % Add example folders to the path + examplefolder = fullfile(fileparts(mfilename('fullpath')), "autotrace_examples", "two_subfolders_example"); + testCase.applyFixture(matlab.unittest.fixtures.PathFixture(examplefolder, ... + "IncludingSubfolders",true)); + + % set up AutoTrace, turn off automatic detection and specify + % dependencies using their folder name + at = opentelemetry.autoinstrument.AutoTrace(@two_subfolders_example, ... + "AutoDetectFiles", false, "AdditionalFiles", fullfile(examplefolder, ["helper1" "helper2"])); + + % run the example + [~] = beginTrace(at); + + % perform test comparisons + results = readJsonResults(testCase); + verifyNumElements(testCase, results, 6); + + % check span names + verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.spans.name), "subfolder_helper1_1"); + verifyEqual(testCase, string(results{2}.resourceSpans.scopeSpans.spans.name), "subfolder_helper1_2"); + verifyEqual(testCase, string(results{3}.resourceSpans.scopeSpans.spans.name), "subfolder_helper2_1"); + verifyEqual(testCase, string(results{4}.resourceSpans.scopeSpans.spans.name), "subfolder_helper2_2"); + verifyEqual(testCase, string(results{5}.resourceSpans.scopeSpans.spans.name), "subfolder_helper2_3"); + verifyEqual(testCase, string(results{6}.resourceSpans.scopeSpans.spans.name), "two_subfolders_example"); + end + function testExcludeFolder(testCase) % testExcludeFolder: specify a folder in ExcludeFiles @@ -227,6 +256,28 @@ function testNonFileOptions(testCase) end end + function testIgnoreUnsupportedDependencies(testCase) + % testIgnoreUnsupportedDependencies: Check that File dependencies that are not + % .m or .mlx files are ignored. For example, .mat file. + + % Add example folders to the path + examplefolder = fullfile(fileparts(mfilename('fullpath')), "autotrace_examples", "matfile_example"); + testCase.applyFixture(matlab.unittest.fixtures.PathFixture(examplefolder)); + + % set up AutoTrace + at = opentelemetry.autoinstrument.AutoTrace(@matfile_example); + + % run the example + [~] = beginTrace(at); + + % perform test comparisons + results = readJsonResults(testCase); + + % should only return 1 span + verifyNumElements(testCase, results, 1); + verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.spans.name), "matfile_example"); + end + function testError(testCase) % testError: handling error situation