1
1
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2
2
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
4
+ using System . Runtime . CompilerServices ;
4
5
using System . Threading ;
5
6
using System . Threading . Tasks ;
6
7
@@ -10,8 +11,17 @@ internal static class InvocationPipeline
10
11
{
11
12
internal static async Task < int > InvokeAsync ( ParseResult parseResult , CancellationToken cancellationToken )
12
13
{
14
+ using var invokeActivity = Activities . ActivitySource . StartActivity ( DiagnosticsStrings . InvokeMethod ) ;
15
+ if ( invokeActivity is not null )
16
+ {
17
+ invokeActivity . DisplayName = parseResult . CommandResult . FullCommandName ( ) ;
18
+ invokeActivity . AddTag ( DiagnosticsStrings . Command , parseResult . CommandResult . Command . Name ) ;
19
+ invokeActivity . AddTag ( DiagnosticsStrings . InvokeType , DiagnosticsStrings . Async ) ;
20
+ }
21
+
13
22
if ( parseResult . Action is null )
14
23
{
24
+ invokeActivity ? . SetStatus ( Diagnostics . ActivityStatusCode . Error ) ;
15
25
return ReturnCodeForMissingAction ( parseResult ) ;
16
26
}
17
27
@@ -41,7 +51,9 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
41
51
switch ( parseResult . Action )
42
52
{
43
53
case SynchronousCommandLineAction syncAction :
44
- return syncAction . Invoke ( parseResult ) ;
54
+ var syncResult = syncAction . Invoke ( parseResult ) ;
55
+ invokeActivity ? . SetExitCode ( syncResult ) ;
56
+ return syncResult ;
45
57
46
58
case AsynchronousCommandLineAction asyncAction :
47
59
var startedInvocation = asyncAction . InvokeAsync ( parseResult , cts . Token ) ;
@@ -52,23 +64,30 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
52
64
53
65
if ( terminationHandler is null )
54
66
{
55
- return await startedInvocation ;
67
+ var asyncResult = await startedInvocation ;
68
+ invokeActivity ? . SetExitCode ( asyncResult ) ;
69
+ return asyncResult ;
56
70
}
57
71
else
58
72
{
59
73
// Handlers may not implement cancellation.
60
74
// In such cases, when CancelOnProcessTermination is configured and user presses Ctrl+C,
61
75
// ProcessTerminationCompletionSource completes first, with the result equal to native exit code for given signal.
62
76
Task < int > firstCompletedTask = await Task . WhenAny ( startedInvocation , terminationHandler . ProcessTerminationCompletionSource . Task ) ;
63
- return await firstCompletedTask ; // return the result or propagate the exception
77
+ var asyncResult = await firstCompletedTask ; // return the result or propagate the exception
78
+ invokeActivity ? . SetExitCode ( asyncResult ) ;
79
+ return asyncResult ;
64
80
}
65
81
66
82
default :
67
- throw new ArgumentOutOfRangeException ( nameof ( parseResult . Action ) ) ;
83
+ var error = new ArgumentOutOfRangeException ( nameof ( parseResult . Action ) ) ;
84
+ invokeActivity ? . Error ( error ) ;
85
+ throw error ;
68
86
}
69
87
}
70
88
catch ( Exception ex ) when ( parseResult . Configuration . EnableDefaultExceptionHandler )
71
89
{
90
+ invokeActivity ? . Error ( ex ) ;
72
91
return DefaultExceptionHandler ( ex , parseResult . Configuration ) ;
73
92
}
74
93
finally
@@ -79,9 +98,18 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
79
98
80
99
internal static int Invoke ( ParseResult parseResult )
81
100
{
101
+ using var invokeActivity = Activities . ActivitySource . StartActivity ( DiagnosticsStrings . InvokeMethod ) ;
102
+ if ( invokeActivity is not null )
103
+ {
104
+ invokeActivity . DisplayName = parseResult . CommandResult . FullCommandName ( ) ;
105
+ invokeActivity . AddTag ( DiagnosticsStrings . Command , parseResult . CommandResult . Command . Name ) ;
106
+ invokeActivity . AddTag ( DiagnosticsStrings . InvokeType , DiagnosticsStrings . Sync ) ;
107
+ }
108
+
82
109
switch ( parseResult . Action )
83
110
{
84
111
case null :
112
+ invokeActivity ? . Error ( ) ;
85
113
return ReturnCodeForMissingAction ( parseResult ) ;
86
114
87
115
case SynchronousCommandLineAction syncAction :
@@ -112,15 +140,20 @@ internal static int Invoke(ParseResult parseResult)
112
140
}
113
141
}
114
142
115
- return syncAction . Invoke ( parseResult ) ;
143
+ var result = syncAction . Invoke ( parseResult ) ;
144
+ invokeActivity ? . SetExitCode ( result ) ;
145
+ return result ;
116
146
}
117
147
catch ( Exception ex ) when ( parseResult . Configuration . EnableDefaultExceptionHandler )
118
148
{
149
+ invokeActivity ? . Error ( ex ) ;
119
150
return DefaultExceptionHandler ( ex , parseResult . Configuration ) ;
120
151
}
121
152
122
153
default :
123
- throw new InvalidOperationException ( $ "{ nameof ( AsynchronousCommandLineAction ) } called within non-async invocation.") ;
154
+ var error = new InvalidOperationException ( $ "{ nameof ( AsynchronousCommandLineAction ) } called within non-async invocation.") ;
155
+ invokeActivity ? . Error ( error ) ;
156
+ throw error ;
124
157
}
125
158
}
126
159
@@ -150,5 +183,38 @@ private static int ReturnCodeForMissingAction(ParseResult parseResult)
150
183
return 0 ;
151
184
}
152
185
}
186
+
187
+ private static void Succeed ( this Diagnostics . Activity activity )
188
+ {
189
+ activity . SetStatus ( Diagnostics . ActivityStatusCode . Ok ) ;
190
+ activity . AddTag ( DiagnosticsStrings . ExitCode , 0 ) ;
191
+ }
192
+ private static void Error ( this Diagnostics . Activity activity , int statusCode )
193
+ {
194
+ activity . SetStatus ( Diagnostics . ActivityStatusCode . Error ) ;
195
+ activity . AddTag ( DiagnosticsStrings . ExitCode , statusCode ) ;
196
+ }
197
+
198
+ private static void Error ( this Diagnostics . Activity activity , Exception ? exception = null )
199
+ {
200
+ activity . SetStatus ( Diagnostics . ActivityStatusCode . Error ) ;
201
+ activity . AddTag ( DiagnosticsStrings . ExitCode , 1 ) ;
202
+ if ( exception is not null )
203
+ {
204
+ activity . AddBaggage ( DiagnosticsStrings . Exception , exception . ToString ( ) ) ;
205
+ }
206
+ }
207
+
208
+ private static void SetExitCode ( this Diagnostics . Activity activity , int exitCode )
209
+ {
210
+ if ( exitCode == 0 )
211
+ {
212
+ activity . Succeed ( ) ;
213
+ }
214
+ else
215
+ {
216
+ activity . Error ( exitCode ) ;
217
+ }
218
+ }
153
219
}
154
220
}
0 commit comments