Skip to content

chore: Change ExporterBase::GetArtifactFullName accessibility to public #2759

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

Merged

Conversation

filzrev
Copy link
Contributor

@filzrev filzrev commented Jun 8, 2025

This PR intended to fix #2619
By changing ExporterBase::GetArtifactFullName from internal to public.

Expected use case
Print benchmark results as clickable links when benchmark completed.

Example Code to output benchmark result summaries

    public class Program
    {
        public static void Main(string[] args)
        {
            var summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly)
                                             .Run(args)
                                             .ToArray();

            summaries.PrintBenchmarkResults();
        }
    }

    internal static class SummariesExtensions
    {
        public static void PrintBenchmarkResults(this Summary[] summaries)
        {
            if (summaries.Length == 0)
            {
                return; // Benchmark is not executed (Invalid filter is specified or print infomation only(e.g. `--help`)
            }

            // LogFilePath/ResultsDirectoryPath is shared between summaries.
            var firstSummary = summaries[0];

            var logger = ConsoleLogger.Default;

            // Print log file path.
            var logFilePath = firstSummary.LogFilePath;
            logger.WriteLine();
            logger.WriteLine("Benchmark LogFile:");
            WriteLineAsClickableLink(logger, logFilePath);

            // Print results directory path.
            var resultsDirectoryPath = firstSummary.ResultsDirectoryPath;
            logger.WriteLine();
            logger.WriteLine("Benchmark Results Directory:");
            WriteLineAsClickableLink(logger, resultsDirectoryPath);

            // Print exported file links.
            logger.WriteLine();
            logger.WriteLine("Exported Files:");
            foreach (var summary in summaries)
            {
                var exportedFiles = ExtractExportedFiles(summary);
                foreach (var path in exportedFiles)
                {
                    var relativePath = path.Substring(resultsDirectoryPath.Length + 1); // Path.GetRelativePath(resultsDirectoryPath, path);
                    WriteLineAsClickableLink(logger, path, caption: relativePath);
                }
            }
            logger.WriteLine();
        }

        private static string[] ExtractExportedFiles(Summary summary)
        {
            var config = summary.BenchmarksCases[0].Config;
            var exporters = config.GetExporters().OfType<ExporterBase>();

            return config.GetExporters()
                         .OfType<ExporterBase>()
                         .Select(x => x.GetArtifactFullName(summary))
                         .ToArray();
        }

        private static void WriteLineAsClickableLink(ILogger logger, string link, string? caption = null, string prefixIndent = "  ")
        {
            logger.Write($"{prefixIndent}");
            if (!Console.IsOutputRedirected)
            {
                logger.WriteLine(ToClickableLink(link, caption));
            }
            else
            {
                logger.WriteLine(link);
            }
        }

        private static string ToClickableLink(string url, string? caption = null)
        {
            const char ESC = '\u001B'; // `\e`
            caption ??= url;
            return $"{ESC}]8;;{url}{ESC}\\{caption}{ESC}]8;;{ESC}\\";
        }
    }

Example of output messages

Benchmark LogFile:
  C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\BenchmarkDotNet.Artifacts\BenchmarkDotNet.Samples.IntroBasic-20250608-191326.log

Benchmark Results Directory:
  C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\BenchmarkDotNet.Artifacts\results

Exported Files:
  BenchmarkDotNet.Samples.IntroBasic-report.csv
  BenchmarkDotNet.Samples.IntroBasic-report-github.md
  BenchmarkDotNet.Samples.IntroBasic-report.html

@filzrev filzrev changed the title chore: modify ExporterBase::GetArtifactFullName accessibility chore: Change ExporterBase::GetArtifactFullName accessibility to public Jun 8, 2025
@AndreyAkinshin AndreyAkinshin merged commit d8eea0d into dotnet:master Jun 8, 2025
8 checks passed
@AndreyAkinshin AndreyAkinshin added this to the v0.15.1 milestone Jun 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Added support to get exported file paths
2 participants