@@ -29,19 +29,35 @@ public static void RequestStarting(this ILogger logger, HttpContext httpContext)
2929 }
3030 }
3131
32- public static void RequestFinished ( this ILogger logger , HttpContext httpContext )
32+ public static void RequestFinished ( this ILogger logger , HttpContext httpContext , int startTimeInTicks )
3333 {
3434 if ( logger . IsEnabled ( LogLevel . Information ) )
3535 {
36+ var elapsed = new TimeSpan ( Environment . TickCount - startTimeInTicks ) ;
3637 logger . Log (
3738 logLevel : LogLevel . Information ,
3839 eventId : 2 ,
39- state : new HostingRequestFinished ( httpContext ) ,
40+ state : new HostingRequestFinished ( httpContext , elapsed ) ,
4041 exception : null ,
4142 formatter : HostingRequestFinished . Callback ) ;
4243 }
4344 }
4445
46+ public static void RequestFailed ( this ILogger logger , HttpContext httpContext , int startTimeInTicks )
47+ {
48+ if ( logger . IsEnabled ( LogLevel . Information ) )
49+ {
50+ var elapsed = new TimeSpan ( Environment . TickCount - startTimeInTicks ) ;
51+ logger . Log (
52+ logLevel : LogLevel . Information ,
53+ eventId : 2 ,
54+ state : new HostingRequestFailed ( httpContext , elapsed ) ,
55+ exception : null ,
56+ formatter : HostingRequestFailed . Callback ) ;
57+ }
58+ }
59+
60+
4561 private class HostingLogScope : ILogValues
4662 {
4763 private readonly HttpContext _httpContext ;
@@ -110,29 +126,64 @@ private class HostingRequestFinished
110126 internal static readonly Func < object , Exception , string > Callback = ( state , exception ) => ( ( HostingRequestFinished ) state ) . ToString ( ) ;
111127
112128 private readonly HttpContext _httpContext ;
129+ private readonly TimeSpan _elapsed ;
113130
114131 private IEnumerable < KeyValuePair < string , object > > _cachedGetValues ;
115132 private string _cachedToString ;
116133
117- public HostingRequestFinished ( HttpContext httpContext )
134+ public HostingRequestFinished ( HttpContext httpContext , TimeSpan elapsed )
118135 {
119136 _httpContext = httpContext ;
137+ _elapsed = elapsed ;
120138 }
121139
122140 public override string ToString ( ) => _cachedToString ?? Interlocked . CompareExchange (
123141 ref _cachedToString ,
124- $ "Request finished { _httpContext . Response . StatusCode } { _httpContext . Response . ContentType } ",
142+ $ "Request finished in { _elapsed . TotalMilliseconds } ms { _httpContext . Response . StatusCode } { _httpContext . Response . ContentType } ",
125143 null ) ;
126144
127145 public IEnumerable < KeyValuePair < string , object > > GetValues ( ) => _cachedGetValues ?? Interlocked . CompareExchange (
128146 ref _cachedGetValues ,
129147 new [ ]
130148 {
149+ new KeyValuePair < string , object > ( "ElapsedMilliseconds" , _elapsed . TotalMilliseconds ) ,
131150 new KeyValuePair < string , object > ( "StatusCode" , _httpContext . Response . StatusCode ) ,
132151 new KeyValuePair < string , object > ( "ContentType" , _httpContext . Response . ContentType ) ,
133152 } ,
134153 null ) ;
135154 }
155+
156+ private class HostingRequestFailed
157+ {
158+ internal static readonly Func < object , Exception , string > Callback = ( state , exception ) => ( ( HostingRequestFailed ) state ) . ToString ( ) ;
159+
160+ private readonly HttpContext _httpContext ;
161+ private readonly TimeSpan _elapsed ;
162+
163+ private IEnumerable < KeyValuePair < string , object > > _cachedGetValues ;
164+ private string _cachedToString ;
165+
166+ public HostingRequestFailed ( HttpContext httpContext , TimeSpan elapsed )
167+ {
168+ _httpContext = httpContext ;
169+ _elapsed = elapsed ;
170+ }
171+
172+ public override string ToString ( ) => _cachedToString ?? Interlocked . CompareExchange (
173+ ref _cachedToString ,
174+ $ "Request finished in { _elapsed . TotalMilliseconds } ms 500",
175+ null ) ;
176+
177+ public IEnumerable < KeyValuePair < string , object > > GetValues ( ) => _cachedGetValues ?? Interlocked . CompareExchange (
178+ ref _cachedGetValues ,
179+ new [ ]
180+ {
181+ new KeyValuePair < string , object > ( "ElapsedMilliseconds" , _elapsed . TotalMilliseconds ) ,
182+ new KeyValuePair < string , object > ( "StatusCode" , 500 ) ,
183+ new KeyValuePair < string , object > ( "ContentType" , null ) ,
184+ } ,
185+ null ) ;
186+ }
136187 }
137188}
138189
0 commit comments