1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Collections . Immutable ;
4+ using System . IO ;
5+ using System . Linq ;
6+ using BenchmarkDotNet . Analysers ;
7+ using BenchmarkDotNet . Diagnosers ;
8+ using BenchmarkDotNet . Engines ;
9+ using BenchmarkDotNet . Exporters ;
10+ using BenchmarkDotNet . Extensions ;
11+ using BenchmarkDotNet . Jobs ;
12+ using BenchmarkDotNet . Loggers ;
13+ using BenchmarkDotNet . Portability ;
14+ using BenchmarkDotNet . Reports ;
15+ using BenchmarkDotNet . Running ;
16+ using BenchmarkDotNet . Toolchains ;
17+ using BenchmarkDotNet . Validators ;
18+ using RunMode = BenchmarkDotNet . Diagnosers . RunMode ;
19+
20+ namespace BenchmarkDotNet . Diagnostics . dotTrace
21+ {
22+ public class DotTraceDiagnoser : IProfiler
23+ {
24+ private readonly Uri nugetUrl ;
25+ private readonly string toolsDownloadFolder ;
26+
27+ public DotTraceDiagnoser ( Uri nugetUrl = null , string toolsDownloadFolder = null )
28+ {
29+ this . nugetUrl = nugetUrl ;
30+ this . toolsDownloadFolder = toolsDownloadFolder ;
31+ }
32+
33+ public IEnumerable < string > Ids => new [ ] { "DotTrace" } ;
34+ public string ShortName => "dotTrace" ;
35+
36+ public RunMode GetRunMode ( BenchmarkCase benchmarkCase )
37+ {
38+ return IsSupported ( benchmarkCase . Job . Environment . GetRuntime ( ) . RuntimeMoniker ) ? RunMode . ExtraRun : RunMode . None ;
39+ }
40+
41+ private readonly List < string > snapshotFilePaths = new ( ) ;
42+
43+ public void Handle ( HostSignal signal , DiagnoserActionParameters parameters )
44+ {
45+ var job = parameters . BenchmarkCase . Job ;
46+ bool isInProcess = job . GetToolchain ( ) . IsInProcess ;
47+ var logger = parameters . Config . GetCompositeLogger ( ) ;
48+ DotTraceToolBase tool = isInProcess
49+ ? new InProcessDotTraceTool ( logger , nugetUrl , downloadTo : toolsDownloadFolder )
50+ : new ExternalDotTraceTool ( logger , nugetUrl , downloadTo : toolsDownloadFolder ) ;
51+
52+ var runtimeMoniker = job . Environment . GetRuntime ( ) . RuntimeMoniker ;
53+ if ( ! IsSupported ( runtimeMoniker ) )
54+ {
55+ logger . WriteLineError ( $ "Runtime '{ runtimeMoniker } ' is not supported by dotTrace") ;
56+ return ;
57+ }
58+
59+ switch ( signal )
60+ {
61+ case HostSignal . BeforeAnythingElse :
62+ tool . Init ( parameters ) ;
63+ break ;
64+ case HostSignal . BeforeActualRun :
65+ snapshotFilePaths . Add ( tool . Start ( parameters ) ) ;
66+ break ;
67+ case HostSignal . AfterActualRun :
68+ tool . Stop ( parameters ) ;
69+ break ;
70+ }
71+ }
72+
73+ public IEnumerable < IExporter > Exporters => Enumerable . Empty < IExporter > ( ) ;
74+ public IEnumerable < IAnalyser > Analysers => Enumerable . Empty < IAnalyser > ( ) ;
75+
76+ public IEnumerable < ValidationError > Validate ( ValidationParameters validationParameters )
77+ {
78+ var runtimeMonikers = validationParameters . Benchmarks . Select ( b => b . Job . Environment . GetRuntime ( ) . RuntimeMoniker ) . Distinct ( ) ;
79+ foreach ( var runtimeMoniker in runtimeMonikers )
80+ {
81+ if ( ! IsSupported ( runtimeMoniker ) )
82+ yield return new ValidationError ( true , $ "Runtime '{ runtimeMoniker } ' is not supported by dotTrace") ;
83+ }
84+ }
85+
86+ internal static bool IsSupported ( RuntimeMoniker runtimeMoniker )
87+ {
88+ switch ( runtimeMoniker )
89+ {
90+ case RuntimeMoniker . HostProcess :
91+ case RuntimeMoniker . Net461 :
92+ case RuntimeMoniker . Net462 :
93+ case RuntimeMoniker . Net47 :
94+ case RuntimeMoniker . Net471 :
95+ case RuntimeMoniker . Net472 :
96+ case RuntimeMoniker . Net48 :
97+ case RuntimeMoniker . Net481 :
98+ case RuntimeMoniker . Net50 :
99+ case RuntimeMoniker . Net60 :
100+ case RuntimeMoniker . Net70 :
101+ case RuntimeMoniker . Net80 :
102+ return true ;
103+ case RuntimeMoniker . NotRecognized :
104+ case RuntimeMoniker . Mono :
105+ case RuntimeMoniker . NativeAot60 :
106+ case RuntimeMoniker . NativeAot70 :
107+ case RuntimeMoniker . NativeAot80 :
108+ case RuntimeMoniker . Wasm :
109+ case RuntimeMoniker . WasmNet50 :
110+ case RuntimeMoniker . WasmNet60 :
111+ case RuntimeMoniker . WasmNet70 :
112+ case RuntimeMoniker . WasmNet80 :
113+ case RuntimeMoniker . MonoAOTLLVM :
114+ case RuntimeMoniker . MonoAOTLLVMNet60 :
115+ case RuntimeMoniker . MonoAOTLLVMNet70 :
116+ case RuntimeMoniker . MonoAOTLLVMNet80 :
117+ case RuntimeMoniker . Mono60 :
118+ case RuntimeMoniker . Mono70 :
119+ case RuntimeMoniker . Mono80 :
120+ #pragma warning disable CS0618 // Type or member is obsolete
121+ case RuntimeMoniker . NetCoreApp50 :
122+ #pragma warning restore CS0618 // Type or member is obsolete
123+ return false ;
124+ case RuntimeMoniker . NetCoreApp20 :
125+ case RuntimeMoniker . NetCoreApp21 :
126+ case RuntimeMoniker . NetCoreApp22 :
127+ return RuntimeInformation . IsWindows ( ) ;
128+ case RuntimeMoniker . NetCoreApp30 :
129+ case RuntimeMoniker . NetCoreApp31 :
130+ return RuntimeInformation . IsWindows ( ) || RuntimeInformation . IsLinux ( ) ;
131+ default :
132+ throw new ArgumentOutOfRangeException ( nameof ( runtimeMoniker ) , runtimeMoniker , $ "Runtime moniker { runtimeMoniker } is not supported") ;
133+ }
134+ }
135+
136+ public IEnumerable < Metric > ProcessResults ( DiagnoserResults results ) => ImmutableArray < Metric > . Empty ;
137+
138+ public void DisplayResults ( ILogger logger )
139+ {
140+ if ( snapshotFilePaths . Any ( ) )
141+ {
142+ logger . WriteLineInfo ( "The following dotTrace snapshots were generated:" ) ;
143+ foreach ( string snapshotFilePath in snapshotFilePaths )
144+ logger . WriteLineInfo ( $ "* { snapshotFilePath } ") ;
145+ }
146+ }
147+ }
148+ }
0 commit comments