/// <summary> /// Formats the contents of the given <see cref="TraceRecord"/> into /// a single string containing comma-separated name-value pairs /// for each <see cref="TraceRecord"/> property. /// </summary> /// <param name="traceRecord">The <see cref="TraceRecord"/> from which /// to produce the result.</param> /// <returns>A string containing comma-separated name-value pairs.</returns> public virtual string Format(TraceRecord traceRecord) { if (traceRecord == null) { throw Error.ArgumentNull("traceRecord"); } // The first and last traces are injected by the tracing system itself. // We use these to format unique strings identifying the incoming request // and the outgoing response. if (string.Equals(traceRecord.Category, TraceCategories.RequestsCategory, StringComparison.Ordinal)) { return(this.FormatRequestEnvelope(traceRecord)); } List <string> messages = new List <string>(); if (!this.IsVerbose) { // In short format mode, we trace only End traces because it is // where the results of each operation will appear. if (traceRecord.Kind == TraceKind.Begin) { return(null); } } else { messages.Add( Error.Format( Resources.TimeLevelKindFormat, this.FormatDateTime(traceRecord.Timestamp), traceRecord.Level.ToString(), traceRecord.Kind.ToString())); if (!string.IsNullOrEmpty(traceRecord.Category)) { messages.Add(Error.Format(Resources.CategoryFormat, traceRecord.Category)); } messages.Add(Error.Format(Resources.IdFormat, traceRecord.RequestId.ToString())); } if (traceRecord.Elapsed != TimeSpan.Zero) { messages.Add(Error.Format(Resources.ElapsedFormat, traceRecord.Elapsed.ToString("c", CultureInfo.CurrentCulture))); } if (!string.IsNullOrEmpty(traceRecord.Message)) { messages.Add(Error.Format(Resources.MessageFormat, traceRecord.Message)); } if (traceRecord.Operator != null || traceRecord.Operation != null) { messages.Add(Error.Format(Resources.OperationFormat, traceRecord.Operator, traceRecord.Operation)); } if (traceRecord.Exception != null) { messages.Add(Error.Format(Resources.ExceptionFormat, traceRecord.Exception.ToString())); } return(string.Join(", ", messages)); }
/// <summary> /// Formats the contents of the given <see cref="TraceRecord"/> into /// a single string containing comma-separated name-value pairs /// for each <see cref="TraceRecord"/> property. /// </summary> /// <param name="traceRecord">The <see cref="TraceRecord"/> from which /// to produce the result.</param> /// <returns>A string containing comma-separated name-value pairs.</returns> public virtual string Format(TraceRecord traceRecord) { if (traceRecord == null) { throw Error.ArgumentNull("traceRecord"); } // The first and last traces are injected by the tracing system itself. // We use these to format unique strings identifying the incoming request // and the outgoing response. if (string.Equals(traceRecord.Category, TraceCategories.RequestsCategory, StringComparison.Ordinal)) { return this.FormatRequestEnvelope(traceRecord); } List<string> messages = new List<string>(); if (!this.IsVerbose) { // In short format mode, we trace only End traces because it is // where the results of each operation will appear. if (traceRecord.Kind == TraceKind.Begin) { return null; } } else { messages.Add( Error.Format( Resources.TimeLevelKindFormat, this.FormatDateTime(traceRecord.Timestamp), traceRecord.Level.ToString(), traceRecord.Kind.ToString())); if (!string.IsNullOrEmpty(traceRecord.Category)) { messages.Add(Error.Format(Resources.CategoryFormat, traceRecord.Category)); } messages.Add(Error.Format(Resources.IdFormat, traceRecord.RequestId.ToString())); } if (traceRecord.Elapsed != TimeSpan.Zero) { messages.Add(Error.Format(Resources.ElapsedFormat, traceRecord.Elapsed.ToString("c", CultureInfo.CurrentCulture))); } if (!string.IsNullOrEmpty(traceRecord.Message)) { messages.Add(Error.Format(Resources.MessageFormat, traceRecord.Message)); } if (traceRecord.Operator != null || traceRecord.Operation != null) { messages.Add(Error.Format(Resources.OperationFormat, traceRecord.Operator, traceRecord.Operation)); } if (traceRecord.Exception != null) { messages.Add(Error.Format(Resources.ExceptionFormat, traceRecord.Exception.ToString())); } return string.Join(", ", messages); }
/// <summary> /// Formats the given <see cref="TraceRecord"/> into a string describing /// either the initial receipt of the incoming request or the final send /// of the response, depending on <see cref="TraceKind"/>. /// </summary> /// <param name="traceRecord">The <see cref="TraceRecord"/> from which to /// produce the result.</param> /// <returns>A string containing comma-separated name-value pairs.</returns> public virtual string FormatRequestEnvelope(TraceRecord traceRecord) { if (traceRecord == null) { throw Error.ArgumentNull("traceRecord"); } List<string> messages = new List<string>(); if (this.IsVerbose) { messages.Add( Error.Format( (traceRecord.Kind == TraceKind.Begin) ? Resources.TimeRequestFormat : Resources.TimeResponseFormat, this.FormatDateTime(traceRecord.Timestamp))); } else { messages.Add((traceRecord.Kind == TraceKind.Begin) ? Resources.ShortRequestFormat : Resources.ShortResponseFormat); } ////if (traceRecord.Request != null) ////{ ////} if (traceRecord.Elapsed != TimeSpan.Zero) { messages.Add(Error.Format(Resources.ElapsedFormat, traceRecord.Elapsed.ToString("c", CultureInfo.CurrentCulture))); } if (this.IsVerbose) { messages.Add(Error.Format(Resources.IdFormat, traceRecord.RequestId.ToString())); } // The Message and Exception fields do not contain interesting information unless // there is a problem, so they appear after the more informative trace information. if (!string.IsNullOrEmpty(traceRecord.Message)) { messages.Add(Error.Format(Resources.MessageFormat, traceRecord.Message)); } if (traceRecord.Exception != null) { messages.Add(Error.Format(Resources.ExceptionFormat, traceRecord.Exception.ToString())); } return string.Join(", ", messages); }
/// <summary> /// Writes a trace to <see cref="System.Diagnostics.Trace"/> if the /// <paramref name="level"/> is greater than or equal <see cref="MinimumLevel"/>. /// </summary> /// <param name="request">The <see cref="HandlerRequest"/> associated with this trace. /// It may be <c>null</c> but the resulting trace will contain no correlation ID.</param> /// <param name="category">The category for the trace. This can be any user-defined /// value. It is not interpreted by this implementation but is written to the trace.</param> /// <param name="level">The <see cref="TraceLevel"/> of this trace. If it is less than /// <see cref="MinimumLevel"/>, this trace request will be ignored.</param> /// <param name="traceAction">The user callback to invoke to fill in a <see cref="TraceRecord"/> /// with additional information to add to the trace.</param> public virtual void Trace(HandlerRequest request, string category, TraceLevel level, Action<TraceRecord> traceAction) { if (category == null) { throw Error.ArgumentNull("category"); } if (traceAction == null) { throw Error.ArgumentNull("traceAction"); } if (level < TraceLevel.Off || level > TraceLevel.Fatal) { throw Error.ArgumentOutOfRange("level", level, Resources.TraceLevelOutOfRange); } if (this.MinimumLevel == TraceLevel.Off || level < this.MinimumLevel) { return; } if (request != null) { } TraceRecord traceRecord = new TraceRecord(request, category, level); traceAction(traceRecord); string message = this.Format(traceRecord); if (!string.IsNullOrEmpty(message)) { // Level may have changed in Translate above this.TraceMessage(traceRecord.Level, message); } }