/// <summary> /// Traces both a begin and an end trace around a specified operation. /// </summary> /// <param name="traceWriter">The <see cref="ITraceWriter"/>.</param> /// <param name="request">The <see cref="HttpRequestMessage"/> with which to associate the trace. It may be null.</param> /// <param name="category">The logical category of the trace.</param> /// <param name="level">The <see cref="TraceLevel"/> of the trace.</param> /// <param name="operatorName">The name of the object performing the operation. It may be null.</param> /// <param name="operationName">The name of the operation being performed. It may be null.</param> /// <param name="beginTrace">The <see cref="Action"/> to invoke prior to performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <param name="execute">An <see cref="Action"/> that performs the operation.</param> /// <param name="endTrace">The <see cref="Action"/> to invoke after successfully performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <param name="errorTrace">The <see cref="Action"/> to invoke if an error was encountered performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> public static void TraceBeginEnd(this ITraceWriter traceWriter, HttpRequestMessage request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord> beginTrace, Action execute, Action <TraceRecord> endTrace, Action <TraceRecord> errorTrace) { if (traceWriter == null) { throw System.Web.Http.Error.ArgumentNull("traceWriter"); } if (execute == null) { throw System.Web.Http.Error.ArgumentNull("execute"); } traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.Begin; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (beginTrace != null) { beginTrace(traceRecord); } }); try { execute(); traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (endTrace != null) { endTrace(traceRecord); } }); } catch (Exception exception) { traceWriter.TraceError(exception, request, category, operatorName, operationName, errorTrace); throw; } }
private static async Task <TResult> TraceBeginEndAsyncCore <TResult>(this ITraceWriter traceWriter, HttpRequestMessage request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord, TResult> endTrace, Action <TraceRecord> errorTrace, Task <TResult> task) { try { TResult result = await task; traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (endTrace != null) { endTrace(traceRecord, result); } }); return(result); } catch (OperationCanceledException) { traceWriter.Trace( request, category, TraceLevel.Warn, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Message = SRResources.TraceCancelledMessage; if (errorTrace != null) { errorTrace(traceRecord); } }); throw; } catch (Exception exception) { traceWriter.TraceError(exception, request, category, operatorName, operationName, errorTrace); throw; } }
public void LogError(string errorPath, string errorMessage) { _traceWriter.Trace(_request, TraceCategories.FormattingCategory, TraceLevel.Error, (traceRecord) => { traceRecord.Kind = TraceKind.Trace; traceRecord.Operator = _operatorName; traceRecord.Operation = _operationName; traceRecord.Message = errorMessage; }); _formatterLogger.LogError(errorPath, errorMessage); }
/// <summary> /// Operations the with basic retry asynchronous. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="asyncOperation">The asynchronous operation.</param> /// <param name="transientExceptionTypes">The transient exception types.</param> /// <param name="retryDelayMilliseconds">The retry delay milliseconds.</param> /// <param name="maxRetries">The maximum retries.</param> /// <param name="traceWriter">The trace writer.</param> /// <returns></returns> public static async Task <T> OperationWithBasicRetryAsync <T>(Func <Task <T> > asyncOperation, Type[] transientExceptionTypes, int retryDelayMilliseconds = 1000, int maxRetries = 60, ITraceWriter traceWriter = null) { int retryCount = 0; while (true) { try { return(await asyncOperation()); } catch (Exception ex) when(IsTransientError(ex, transientExceptionTypes)) { if (traceWriter != null) { traceWriter.Trace(System.Diagnostics.TraceLevel.Error, $"Error: {ex.Message}. Retrying {retryCount}/{maxRetries}", ex); } if (++retryCount >= maxRetries) { throw; } Thread.Sleep(retryDelayMilliseconds); } } }
private static void TraceError( this ITraceWriter traceWriter, Exception exception, HttpRequestMessage request, string category, string operatorName, string operationName, Action <TraceRecord> errorTrace ) { TraceLevel traceLevel = TraceWriterExceptionMapper.GetMappedTraceLevel(exception) ?? TraceLevel.Error; traceWriter.Trace( request, category, traceLevel, (traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Exception = exception; TraceWriterExceptionMapper.TranslateHttpResponseException(traceRecord); if (errorTrace != null) { errorTrace(traceRecord); } } ); }
/// <summary> /// Writes a single <see cref="TraceRecord"/> to the given <see cref="ITraceWriter"/> if the trace writer /// is enabled for the given <paramref name="category"/> and <paramref name="level"/>. /// </summary> /// <param name="traceWriter">The <see cref="ITraceWriter"/></param> /// <param name="request">The <see cref="HttpRequestMessage"/> with which to correlate the request. /// It may be null, but if so cannot be correlated with any request.</param> /// <param name="category">The category for the trace.</param> /// <param name="level">The <see cref="TraceLevel"/> for the trace.</param> /// <param name="exception">The <see cref="Exception"/> to trace. It may not be null.</param> public static void Trace( this ITraceWriter traceWriter, HttpRequestMessage request, string category, TraceLevel level, Exception exception ) { if (traceWriter == null) { throw System.Web.Http.Error.ArgumentNull("traceWriter"); } if (exception == null) { throw System.Web.Http.Error.ArgumentNull("exception"); } traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Exception = exception; } ); }
// GET api/employees/12345 //public Employee Get(int id) //{ // return list.First(e => e.Id == id); //} public Employee Get(int id) { var employee = list.FirstOrDefault(e => e.Id == id); if (traceWriter != null) { traceWriter.Info(Request, "EmployeesController", String.Format("Getting employee {0}", id)); } if (traceWriter != null) { traceWriter.Trace( Request, "System.Web.Http.Controllers", System.Web.Http.Tracing.TraceLevel.Info, (traceRecord) => { traceRecord.Message = String.Format("Getting employee {0}", id); traceRecord.Operation = "Get(int)"; traceRecord.Operator = "EmployeeController"; }); } return(employee); }
/// <summary> /// Writes a single <see cref="TraceRecord"/> to the given <see cref="ITraceWriter"/> if the trace writer /// is enabled for the given <paramref name="category"/> and <paramref name="level"/>. /// </summary> /// <param name="traceWriter"> /// The <see cref="ITraceWriter"/>. /// </param> /// <param name="request"> /// The <see cref="HandlerRequest"/> with which to correlate the request. /// It may be null, but if so will not be correlated with any request. /// </param> /// <param name="category"> /// The category for the trace. /// </param> /// <param name="level"> /// The <see cref="TraceLevel"/> for the trace. /// </param> /// <param name="exception"> /// The <see cref="Exception"/> to trace. It may not be null. /// </param> /// <param name="messageFormat"> /// The string to use to format a message. It may not be null. /// </param> /// <param name="messageArguments"> /// Optional list of arguments for the <paramref name="messageFormat"/>. /// </param> public static void Trace(this ITraceWriter traceWriter, HandlerRequest request, string category, TraceLevel level, Exception exception, string messageFormat, params object[] messageArguments) { if (traceWriter == null) { throw Internal.Error.ArgumentNull("traceWriter"); } if (exception == null) { throw Internal.Error.ArgumentNull("exception"); } if (messageFormat == null) { throw Internal.Error.ArgumentNull("messageFormat"); } traceWriter.Trace( request, category, level, traceRecord => { traceRecord.Exception = exception; traceRecord.Message = Internal.Error.Format(messageFormat, messageArguments); }); }
public void Trace(HttpRequestMessage request, string category, TraceLevel level, Action <TraceRecord> traceAction) { if (request != null) { var traceQueryString = request.GetQueryString("trace");; bool shouldTrace; if (traceQueryString != null && Boolean.TryParse(traceQueryString, out shouldTrace) && shouldTrace) { object perRequestTrace; if (!request.Properties.TryGetValue("perRequestTrace", out perRequestTrace)) { perRequestTrace = new List <string>(); request.Properties["perRequestTrace"] = perRequestTrace; } var record = new TraceRecord(request, category, level); traceAction(record); (perRequestTrace as List <string>).Add(Log(record)); } } if (_innerWriter != null) { _innerWriter.Trace(request, category, level, traceAction); } }
/// <summary> /// Writes a single <see cref="TraceRecord"/> to the given <see cref="ITraceWriter"/> if the trace writer /// is enabled for the given <paramref name="category"/> and <paramref name="level"/>. /// </summary> /// <param name="traceWriter">The <see cref="ITraceWriter"/></param> /// <param name="request">The <see cref="HttpRequestMessage"/> with which to correlate the request. /// It may be null, but if so will not be correlated with any request.</param> /// <param name="category">The category for the trace.</param> /// <param name="level">The <see cref="TraceLevel"/> for the trace.</param> /// <param name="exception">The <see cref="Exception"/> to trace. It may not be null.</param> /// <param name="messageFormat">The string to use to format a message. It may not be null.</param> /// <param name="messageArguments">Optional list of arguments for the <paramref name="messageFormat"/>.</param> public static void Trace(this ITraceWriter traceWriter, HttpRequestMessage request, string category, TraceLevel level, Exception exception, string messageFormat, params object[] messageArguments) { if (traceWriter == null) { throw System.Web.Http.Error.ArgumentNull("traceWriter"); } if (exception == null) { throw System.Web.Http.Error.ArgumentNull("exception"); } if (messageFormat == null) { throw System.Web.Http.Error.ArgumentNull("messageFormat"); } traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Exception = exception; traceRecord.Message = System.Web.Http.Error.Format(messageFormat, messageArguments); }); }
public HttpResponseMessage Get(int id) { var employee = list.FirstOrDefault(e => e.Id == id); if (employee == null) { var response = Request.CreateResponse(HttpStatusCode.NotFound, new HttpError(Resources.Messages.NotFound)); return(response); } if (traceWriter != null) { traceWriter.Info(Request, "EmployeesController", String.Format("Getting employee {0}", id)); traceWriter.Trace(Request, "System.Web.Http.Controllers", System.Web.Http.Tracing.TraceLevel.Info, (traceRecord) => { traceRecord.Message = String.Format("Getting employee {0}", id); traceRecord.Operation = "Get(int)"; traceRecord.Operator = "EmployeeController"; }); } var blackListed = ""; var allowedFormatters = Configuration.Formatters.Where(f => !f.SupportedMediaTypes.Any(m => m.MediaType.Equals(blackListed, StringComparison.OrdinalIgnoreCase))); var result = Configuration.Services.GetContentNegotiator().Negotiate(typeof(Employee), Request, allowedFormatters); return(new HttpResponseMessage() { Content = new ObjectContent <Employee>(employee, result.Formatter, result.MediaType) }); }
private static async Task TraceBeginEndAsyncCore(this ITraceWriter traceWriter, HandlerRequest request, string category, TraceLevel level, string operatorName, string operationName, TimeSpan elapsed, Action <TraceRecord> endTrace, Action <TraceRecord> errorTrace, Task task) { try { await task; traceWriter.Trace( request, category, level, traceRecord => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Elapsed = elapsed; if (endTrace != null) { endTrace(traceRecord); } }); } catch (OperationCanceledException) { traceWriter.Trace( request, category, TraceLevel.Warn, traceRecord => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Message = Resources.TraceCancelledMessage; if (errorTrace != null) { errorTrace(traceRecord); } }); throw; } catch (Exception exception) { traceWriter.TraceError(exception, request, category, operatorName, operationName, errorTrace); throw; } }
public HttpResponseMessage GetTrace() { ITraceWriter x = Configuration.Services.GetTraceWriter(); x.Trace(Request, "Category", TraceLevel.Error, $"this is test"); return(null); }
/// <summary> /// Traces both a begin and an end trace around a specified asynchronous operation. /// </summary> /// <remarks>The end trace will occur when the asynchronous operation completes, either success or failure.</remarks> /// <param name="traceWriter">The <see cref="ITraceWriter"/>.</param> /// <param name="request">The <see cref="HttpRequestMessage"/> with which to associate the trace. It may be null.</param> /// <param name="category">The logical category of the trace.</param> /// <param name="level">The <see cref="TraceLevel"/> of the trace.</param> /// <param name="operatorName">The name of the object performing the operation. It may be null.</param> /// <param name="operationName">The name of the operation being performed. It may be null.</param> /// <param name="beginTrace">The <see cref="Action"/> to invoke prior to performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <param name="execute">An <see cref="Func{Task}"/> that returns the <see cref="Task"/> that will perform the operation.</param> /// <param name="endTrace">The <see cref="Action"/> to invoke after successfully performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <param name="errorTrace">The <see cref="Action"/> to invoke if an error was encountered performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <returns>The <see cref="Task"/> returned by the operation.</returns> public static Task TraceBeginEndAsync(this ITraceWriter traceWriter, HttpRequestMessage request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord> beginTrace, Func <Task> execute, Action <TraceRecord> endTrace, Action <TraceRecord> errorTrace) { if (traceWriter == null) { throw System.Web.Http.Error.ArgumentNull("traceWriter"); } if (execute == null) { throw System.Web.Http.Error.ArgumentNull("execute"); } traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.Begin; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (beginTrace != null) { beginTrace(traceRecord); } }); try { Task task = execute(); // If the operation returned a null Task, we cannot do any // further tracing. Return that null to the caller as // would happen if tracing were not enabled. if (task == null) { return(task); } return(traceWriter.TraceBeginEndAsyncCore(request, category, level, operatorName, operationName, endTrace, errorTrace, task)); } catch (Exception exception) { traceWriter.TraceError(exception, request, category, operatorName, operationName, errorTrace); throw; } }
/// <summary> /// Writes a single <see cref="TraceRecord"/> to the given <see cref="ITraceWriter"/> if the trace writer /// is enabled for the given <paramref name="category"/> and <paramref name="level"/>. /// </summary> /// <param name="traceWriter"> /// The <see cref="ITraceWriter"/>. /// </param> /// <param name="request"> /// The <see cref="HandlerRequest"/> with which to correlate the request. /// It may be null, but if so cannot be correlated with any request. /// </param> /// <param name="category"> /// The category for the trace. /// </param> /// <param name="level"> /// The <see cref="TraceLevel"/> for the trace. /// </param> /// <param name="exception"> /// The <see cref="Exception"/> to trace. It may not be null. /// </param> public static void Trace(this ITraceWriter traceWriter, HandlerRequest request, string category, TraceLevel level, Exception exception) { if (traceWriter == null) { throw Internal.Error.ArgumentNull("traceWriter"); } if (exception == null) { throw Internal.Error.ArgumentNull("exception"); } traceWriter.Trace(request, category, level, traceRecord => { traceRecord.Exception = exception; }); }
public void Trace(HttpRequestMessage request, string category, TraceLevel level, Action <TraceRecord> traceAction) { if (level != TraceLevel.Off) { var record = new TraceRecord(request, category, level); traceAction(record); if (!string.IsNullOrWhiteSpace(_hubname)) { _hub.Value.Clients.All.logMessage(ComposeMessage(record)); } _traceWriter.Trace(request, category, level, traceAction); } }
public static Task <TResult> TraceBeginEndAsync <TResult>(this ITraceWriter traceWriter, HandlerRequest request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord> beginTrace, Func <Task <TResult> > execute, Action <TraceRecord, TResult> endTrace, Action <TraceRecord> errorTrace) { if (traceWriter == null) { throw Internal.Error.ArgumentNull("traceWriter"); } if (execute == null) { throw Internal.Error.ArgumentNull("execute"); } Stopwatch stopwatch = Stopwatch.StartNew(); traceWriter.Trace( request, category, level, traceRecord => { traceRecord.Kind = TraceKind.Begin; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (beginTrace != null) { beginTrace(traceRecord); } }); try { Task <TResult> task = execute(); // If the operation returned a null Task, we cannot do any // further tracing. Return that null to the caller as // would happen if tracing were not enabled. if (task == null) { return(null); } return(traceWriter.TraceBeginEndAsyncCore(request, category, level, operatorName, operationName, stopwatch.Elapsed, endTrace, errorTrace, task)); } catch (Exception exception) { traceWriter.TraceError(exception, request, category, operatorName, operationName, errorTrace); throw; } }
/// <summary> /// Writes a single <see cref="TraceRecord"/> to the given <see cref="ITraceWriter"/> if the trace writer /// is enabled for the given <paramref name="category"/> and <paramref name="level"/>. /// </summary> /// <param name="traceWriter">The <see cref="ITraceWriter"/></param> /// <param name="level">The <see cref="TraceLevel"/> for the trace.</param> /// <param name="message">The message to log (or null).</param> /// <param name="exception">The exception to log (or null).</param> /// <param name="request">Request used for message correlation. Defaults to null.</param> /// <param name="category">The category for the trace. Defaults to the method or property name of the caller.</param> public static void Trace(this ITraceWriter traceWriter, TraceLevel level, string message, Exception exception, HttpRequestMessage request = null, [CallerMemberName] string category = "") { if (traceWriter == null) { // If tracing is disabled or we don't have a trace writer then just return. return; } traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Message = message; traceRecord.Exception = exception; }); }
private static void TraceError(this ITraceWriter traceWriter, Exception exception, HandlerRequest request, string category, string operatorName, string operationName, Action <TraceRecord> errorTrace) { Contract.Requires(traceWriter != null); traceWriter.Trace( request, category, TraceLevel.Error, traceRecord => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Exception = exception; if (errorTrace != null) { errorTrace(traceRecord); } }); }
protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, IJsonLineInfo lineInfo, string path, Exception ex) { ErrorContext errorContext = GetErrorContext(currentObject, keyValue, path, ex); #if HAVE_TRACE_WRITER if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Error && !errorContext.Traced) { // only write error once errorContext.Traced = true; // kind of a hack but meh. might clean this up later string message = (GetType() == typeof(JsonSerializerInternalWriter)) ? "Error serializing" : "Error deserializing"; if (contract != null) { message += " " + contract.UnderlyingType; } message += ". " + ex.Message; // add line information to non-json.net exception message if (!(ex is JsonException)) { message = JsonPosition.FormatMessage(lineInfo, path, message); } TraceWriter.Trace(TraceLevel.Error, message, ex); } #endif #if HAVE_RUNTIME_SERIALIZATION // attribute method is non-static so don't invoke if no object if (contract != null && currentObject != null) { contract.InvokeOnError(currentObject, Serializer.Context, errorContext); } #endif if (!errorContext.Handled) { Serializer.OnError(new ErrorEventArgs(currentObject, errorContext)); } return(errorContext.Handled); }
protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, IJsonLineInfo lineInfo, string path, Exception ex) { ErrorContext errorContext = GetErrorContext(currentObject, keyValue, path, ex); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Error && !errorContext.Traced) { // only write error once errorContext.Traced = true; string message = (_serializing) ? "Error serializing" : "Error deserializing"; if (contract != null) { message += " " + contract.UnderlyingType; } message += ". " + ex.Message; // add line information to non-json.net exception message if (!(ex is JsonException)) { message = JsonPosition.FormatMessage(lineInfo, path, message); } TraceWriter.Trace(TraceLevel.Error, message, ex); } // attribute method is non-static so don't invoke if no object if (contract != null && currentObject != null) { contract.InvokeOnError(currentObject, Serializer.Context, errorContext); } if (!errorContext.Handled) { Serializer.OnError(new ErrorEventArgs(currentObject, errorContext)); } return(errorContext.Handled); }
/// <summary> /// Displays an error message in the list with the specified writer, request, and exception. /// </summary> /// <param name="traceWriter">The <see cref="T:System.Web.Http.Tracing.ITraceWriter" />.</param> /// <param name="request">The <see cref="T:System.Net.Http.HttpRequestMessage" /> with which to associate the trace. It may be null.</param> /// <param name="exception">The error occurred during execution.</param> public static void Error(this ITraceWriter traceWriter, HttpRequestMessage request, Exception exception) { traceWriter.Trace(request, "Application", TraceLevel.Error, exception); }
/// <summary> /// Traces both a begin and an end trace around a specified operation. /// </summary> /// <param name="traceWriter"> /// The <see cref="ITraceWriter"/>. /// </param> /// <param name="request"> /// The <see cref="HandlerRequest"/> with which to associate the trace. It may be null. /// </param> /// <param name="category"> /// The logical category of the trace. /// </param> /// <param name="level"> /// The <see cref="TraceLevel"/> of the trace. /// </param> /// <param name="operatorName"> /// The name of the object performing the operation. It may be null. /// </param> /// <param name="operationName"> /// The name of the operation being performaed. It may be null. /// </param> /// <param name="beginTrace"> /// The <see cref="Action"/> to invoke prior to performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null. /// </param> /// <param name="execute"> /// An <see cref="Action"/> that performs the operation. /// </param> /// <param name="endTrace"> /// The <see cref="Action"/> to invoke after successfully performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null. /// </param> /// <param name="errorTrace"> /// The <see cref="Action"/> to invoke if an error was encountered performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null. /// </param> public static TResult TraceBeginEnd <TResult>(this ITraceWriter traceWriter, HandlerRequest request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord> beginTrace, Func <TResult> execute, Action <TraceRecord> endTrace, Action <TraceRecord> errorTrace) { if (traceWriter == null) { throw Internal.Error.ArgumentNull("traceWriter"); } if (execute == null) { throw Internal.Error.ArgumentNull("execute"); } Stopwatch stopwatch = Stopwatch.StartNew(); traceWriter.Trace( request, category, level, traceRecord => { traceRecord.Kind = TraceKind.Begin; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (beginTrace != null) { beginTrace(traceRecord); } }); try { var result = execute(); traceWriter.Trace( request, category, level, traceRecord => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (endTrace != null) { endTrace(traceRecord); } traceRecord.Elapsed = stopwatch.Elapsed; }); return(result); } catch (Exception ex) { traceWriter.Trace( request, category, TraceLevel.Error, traceRecord => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Exception = ex; if (errorTrace != null) { errorTrace(traceRecord); } traceRecord.Elapsed = stopwatch.Elapsed; }); throw; } }
public void Trace(TraceLevel level, string message, Exception ex) { // write to any existing trace writer if (_innerTraceWriter != null && level <= _innerTraceWriter.LevelFilter) { _innerTraceWriter.Trace(level, message, ex); } IExecutionTimer timer = _timerStrategy(); if (_traceMessages.Count > 0) { // check message to see if serialization is complete if (message.StartsWith("Serialized JSON:", StringComparison.Ordinal) || message.StartsWith("Deserialized JSON:", StringComparison.Ordinal)) { TimerResult timeResult = null; if (timer != null) { timeResult = timer.Stop(_start); _timelineMessage.AsTimedMessage(timeResult); } // set final JSON onto previous message JsonTraceMessage lastMessage = _traceMessages.Last(); lastMessage.JsonText = message.Substring(message.IndexOf(Environment.NewLine, StringComparison.Ordinal)).Trim(); lastMessage.Duration = (timeResult != null) ? (TimeSpan?)timeResult.Duration : null; _traceMessages.Clear(); return; } } JsonAction action = JsonAction.Unknown; string type = null; string json = null; if (_traceMessages.Count == 0) { Match match = Regex.Match(message, @"^Started serializing ([^\s]+)", RegexOptions.Compiled | RegexOptions.CultureInvariant); if (match.Success) { type = match.Groups[1].Value.TrimEnd('.'); action = JsonAction.Serialize; } else { match = Regex.Match(message, @"^Started deserializing ([^\s]+)", RegexOptions.Compiled | RegexOptions.CultureInvariant); if (match.Success) { type = match.Groups[1].Value.TrimEnd('.'); action = JsonAction.Deserialize; } else { if (message.StartsWith("Serialized JSON:", StringComparison.Ordinal)) { action = JsonAction.Serialize; } else if (message.StartsWith("Deserialized JSON:", StringComparison.Ordinal)) { action = JsonAction.Deserialize; } if (action != JsonAction.Unknown) { json = message.Substring(message.IndexOf(Environment.NewLine, StringComparison.Ordinal)).Trim(); message = null; } } } // create timeline message // will be updated each trace with new duration _timelineMessage = CreateJsonTimelineMessage(action, type); _messageBroker.Publish(_timelineMessage); if (timer != null) { _start = timer.Start(); } } else { JsonTraceMessage previous = _traceMessages.Last(); previous.Duration = null; action = previous.Action; type = previous.Type; } TimerResult result = null; if (timer != null) { result = timer.Stop(_start); _timelineMessage.AsTimedMessage(result); } JsonTraceMessage traceMessage = new JsonTraceMessage { Ordinal = _traceMessages.Count, MessageDate = DateTime.Now, Level = level, Message = message, Exception = ex, JsonText = json, Action = action, Type = (type != null) ? RemoveAssemblyDetails(type) : null, Duration = (result != null) ? (TimeSpan?)result.Duration : null }; _messageBroker.Publish(traceMessage); _traceMessages.Add(traceMessage); }
public static void Info(this ITraceWriter?traceWriter, Func <string> message, int indent = 0, Exception?exception = default) => traceWriter?.Trace(TraceLevel.Info, message, indent, exception);
/// <summary> /// Traces both a begin and an end trace around a specified asynchronous operation. /// </summary> /// <remarks>The end trace will occur when the asynchronous operation completes, either success or failure.</remarks> /// <param name="traceWriter">The <see cref="ITraceWriter"/>.</param> /// <param name="request">The <see cref="HttpRequestMessage"/> with which to associate the trace. It may be null.</param> /// <param name="category">The logical category of the trace.</param> /// <param name="level">The <see cref="TraceLevel"/> of the trace.</param> /// <param name="operatorName">The name of the object performing the operation. It may be null.</param> /// <param name="operationName">The name of the operation being performed. It may be null.</param> /// <param name="beginTrace">The <see cref="Action"/> to invoke prior to performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <param name="execute">An <see cref="Func{Task}"/> that returns the <see cref="Task"/> that will perform the operation.</param> /// <param name="endTrace">The <see cref="Action"/> to invoke after successfully performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <param name="errorTrace">The <see cref="Action"/> to invoke if an error was encountered performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <returns>The <see cref="Task"/> returned by the operation.</returns> public static Task TraceBeginEndAsync(this ITraceWriter traceWriter, HttpRequestMessage request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord> beginTrace, Func <Task> execute, Action <TraceRecord> endTrace, Action <TraceRecord> errorTrace) { if (traceWriter == null) { throw System.Web.Http.Error.ArgumentNull("traceWriter"); } if (execute == null) { throw System.Web.Http.Error.ArgumentNull("execute"); } traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.Begin; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (beginTrace != null) { beginTrace(traceRecord); } }); try { Task task = execute(); // If the operation returned a null Task, we cannot do any // further tracing. Return that null to the caller as // would happen if tracing were not enabled. if (task == null) { return(task); } return(task .Then(() => { traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (endTrace != null) { endTrace(traceRecord); } }); }) .Catch((info) => { traceWriter.Trace( request, category, TraceLevel.Error, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Exception = info.Exception.GetBaseException(); traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (errorTrace != null) { errorTrace(traceRecord); } }); return info.Throw(info.Exception); }) .Finally(() => { if (task.IsCanceled) { traceWriter.Trace( request, category, TraceLevel.Warn, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Message = SRResources.TraceCancelledMessage; if (errorTrace != null) { errorTrace(traceRecord); } }); } })); } catch (Exception ex) { traceWriter.Trace( request, category, TraceLevel.Error, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Exception = ex; if (errorTrace != null) { errorTrace(traceRecord); } }); throw; } }
public static Task TraceBeginEndAsync(this ITraceWriter traceWriter, HttpRequestMessage request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord> beginTrace, Func <Task> execute, Action <TraceRecord> endTrace, Action <TraceRecord> errorTrace) { if (traceWriter == null) { throw System.Web.Http.Error.ArgumentNull("traceWriter"); } if (execute == null) { throw System.Web.Http.Error.ArgumentNull("execute"); } bool isTracing = false; traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { isTracing = true; traceRecord.Kind = TraceKind.Begin; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (beginTrace != null) { beginTrace(traceRecord); } }); try { Task task = execute(); // If we are not tracing, there is no need to ContinueWith if (!isTracing || task == null) { return(task); } Task <Task> returnTask = task.ContinueWith <Task>((t) => { if (t.IsCanceled) { traceWriter.Trace( request, category, TraceLevel.Warn, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Message = SRResources.TraceCancelledMessage; if (errorTrace != null) { errorTrace(traceRecord); } }); return(TaskHelpers.Canceled()); } if (t.IsFaulted) { traceWriter.Trace( request, category, TraceLevel.Error, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Exception = t.Exception.GetBaseException(); traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (errorTrace != null) { errorTrace(traceRecord); } }); return(TaskHelpers.FromErrors(t.Exception.InnerExceptions)); } traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (endTrace != null) { endTrace(traceRecord); } }); return(TaskHelpers.Completed()); }); return(returnTask.FastUnwrap()); } catch (Exception ex) { if (isTracing) { traceWriter.Trace( request, category, TraceLevel.Error, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.End; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; traceRecord.Exception = ex; if (errorTrace != null) { errorTrace(traceRecord); } }); } throw; } }
/// <summary> /// Displays an error message in the list with the specified writer, request, exception, message format and argument. /// </summary> /// <param name="traceWriter">The <see cref="T:System.Web.Http.Tracing.ITraceWriter" />.</param> /// <param name="request">The <see cref="T:System.Net.Http.HttpRequestMessage" /> with which to associate the trace. It may be null.</param> /// <param name="exception">The exception.</param> /// <param name="messageFormat">The format of the message.</param> /// <param name="messageArguments">The argument in the message.</param> public static void Error(this ITraceWriter traceWriter, HttpRequestMessage request, Exception exception, string messageFormat, params object[] messageArguments) { traceWriter.Trace(request, "Application", TraceLevel.Error, exception, messageFormat, messageArguments); }
/// <summary> /// Displays an error message in the <see cref="T:System.Web.Http.Tracing.TraceWriterExtensions" /> class with the specified writer, request, and message format and argument. /// </summary> /// <param name="traceWriter">The <see cref="T:System.Web.Http.Tracing.ITraceWriter" />.</param> /// <param name="request">The <see cref="T:System.Net.Http.HttpRequestMessage" /> with which to associate the trace. It may be null.</param> /// <param name="messageFormat">The format of the message.</param> /// <param name="messageArguments">The message argument.</param> public static void Fatal(this ITraceWriter traceWriter, HttpRequestMessage request, string messageFormat, params object[] messageArguments) { traceWriter.Trace(request, "Application", TraceLevel.Fatal, messageFormat, messageArguments); }