src/Microsoft.Azure.Relay/RelayEventSource.cs (525 lines of code) (raw):

// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace Microsoft.Azure.Relay { using System; using System.Diagnostics.Tracing; using System.Globalization; using System.Net; using System.Runtime.CompilerServices; interface ITraceSource { TrackingContext TrackingContext { get; } } /// <summary> /// EventSource for the new Dynamic EventSource type of Microsoft-Azure-Relay traces. /// /// The default Level is Informational /// /// Do not explicity include the Guid here, since EventSource has a mechanism to automatically /// map to an EventSource Guid based on the Name (Microsoft-Azure-Relay). The Guid will /// be consistent as long as the name stays Microsoft-Azure-Relay /// </summary> [EventSource(Name = "Microsoft-Azure-Relay")] class RelayEventSource : EventSource { public static readonly RelayEventSource Log = new RelayEventSource(); // Prevent additional instances other than RelayEventSource.Log RelayEventSource() { } [NonEvent] public void ObjectConnecting(object source) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { var details = PrepareTrace(source); this.ObjectConnecting(details.Source); } } [NonEvent] public void ObjectConnecting(string source, TrackingContext trackingContext) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.ObjectConnecting(source); } } [Event(40200, Level = EventLevel.Informational, Message = "{0}: Connecting.")] void ObjectConnecting(string source) { this.WriteEvent(40200, source); } [NonEvent] public void ObjectConnected(object source) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { var details = PrepareTrace(source); this.ObjectConnected(details.Source); } } [NonEvent] public void ObjectConnected(string source, TrackingContext trackingContext) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.ObjectConnected(source); } } [Event(40201, Level = EventLevel.Informational, Message = "{0}: Connected")] void ObjectConnected(string source) { this.WriteEvent(40201, source); } [NonEvent] public void ObjectClosing(object source) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { var details = PrepareTrace(source); this.ObjectClosing(details.Source); } } [Event(40202, Level = EventLevel.Informational, Message = "{0}: is Closing")] void ObjectClosing(string source) { this.WriteEvent(40202, source); } [NonEvent] public void ObjectClosed(object source) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { var details = PrepareTrace(source); this.ObjectClosed(details.Source); } } [Event(40203, Level = EventLevel.Informational, Message = "{0}: is Closed.")] void ObjectClosed(string source) { this.WriteEvent(40203, source); } [NonEvent] public void RelayListenerRendezvousStart(object source, string trackingId, string rendezvousAddress) { if (this.IsEnabled()) { var details = PrepareTrace(source); this.RelayListenerRendezvousStart(details.Source, trackingId, rendezvousAddress); } } [Event(40204, Message = "{0}: Relay Listener Received a connection request. ConnectionId: {1}, Rendezvous Address: {2}.")] void RelayListenerRendezvousStart(string source, string clientId, string rendezvousAddress) { this.WriteEvent(40204, source, clientId, rendezvousAddress); } [Event(40205, Message = "Relay Listener accepted a client connection.")] public void RelayListenerRendezvousStop() { if (this.IsEnabled()) { this.WriteEvent(40205); } } [NonEvent] public void RelayListenerRendezvousFailed(object source, string trackingId, Exception exception) { if (this.IsEnabled()) { var details = PrepareTrace(source); this.RelayListenerRendezvousFailed(details.Source, trackingId, ExceptionToString(exception, details.TrackingContext)); } } [NonEvent] public void RelayListenerRendezvousFailed(object source, string trackingId, string error) { if (this.IsEnabled()) { var details = PrepareTrace(source); this.RelayListenerRendezvousFailed(details.Source, trackingId, error); } } [Event(40206, Level = EventLevel.Warning, Message = "{0}: Relayed Listener failed to accept client. ConnectionId: {1}, Exception: {2}.")] void RelayListenerRendezvousFailed(string source, string clientId, string exception) { this.WriteEvent(40206, source, clientId, exception); } [NonEvent] public void RelayListenerRendezvousRejected(TrackingContext trackingContext, HttpStatusCode statusCode, string statusDescription) { if (this.IsEnabled()) { SetCurrentThreadActivityId(trackingContext); this.RelayListenerRendezvousRejected(trackingContext.ToString(), (int)statusCode, statusDescription); } } [Event(40207, Level = EventLevel.Warning, Message = "Relayed Listener is rejecting the client. ConnectionId: {0}, StatusCode: {1}, StatusDescription: {2}.")] public void RelayListenerRendezvousRejected(string connectionId, int statusCode, string statusDescription) { this.WriteEvent(40207, connectionId, statusCode, statusDescription); } // Not the actual event definition since we're using object and Exception types [NonEvent] public void HandledExceptionAsInformation(object source, Exception exception, [CallerMemberName] string member = "") { if (this.IsEnabled()) { var details = PrepareTrace(source); this.HandledExceptionAsInformation(details.Source, member, ExceptionToString(exception, details.TrackingContext)); } } [Event(40249, Message = "{0}.{1} Handled Exception: {2}")] void HandledExceptionAsInformation(string source, string member, string exception) { this.WriteEvent(40249, source, member, exception); } // Not the actual event definition since we're using object and Exception types [NonEvent] public void HandledExceptionAsWarning(object source, Exception exception, [CallerMemberName] string member = "") { if (this.IsEnabled()) { var details = PrepareTrace(source); this.HandledExceptionAsWarning(details.Source, member, ExceptionToString(exception, details.TrackingContext)); } } [Event(40250, Level = EventLevel.Warning, Message = "{0}.{1} Handled Exception: {2}")] void HandledExceptionAsWarning(string source, string member, string exception) { this.WriteEvent(40250, source, member, exception); } // Not the actual event definition since we're using object and Exception types [NonEvent] public void HandledExceptionAsError(object source, Exception exception, [CallerMemberName] string member = "") { if (this.IsEnabled()) { var details = PrepareTrace(source); this.HandledExceptionAsError(details.Source, member, ExceptionToString(exception, details.TrackingContext)); } } [Event(40251, Level = EventLevel.Error, Message = "{0}.{1} Handled Exception {2}")] void HandledExceptionAsError(string source, string member, string exception) { this.WriteEvent(40251, source, member, exception); } [NonEvent] public void GetTokenStart(object source) { if (this.IsEnabled()) { var details = PrepareTrace(source); this.GetTokenStart(details.Source); } } [Event(40255, Level = EventLevel.Informational, Message = "{0}: GetToken start")] void GetTokenStart(string source) { this.WriteEvent(40255, source); } [NonEvent] public void GetTokenStop(object source, DateTime tokenExpiry) { if (this.IsEnabled()) { PrepareTrace(source); this.GetTokenStop(DateTimeToString(tokenExpiry)); } } [Event(40256, Level = EventLevel.Informational, Message = "GetToken stop. New token expires at {0}.")] void GetTokenStop(string tokenExpiry) { this.WriteEvent(40256, tokenExpiry); } [NonEvent] public void TokenRenewScheduled(TimeSpan interval, object source) { if (this.IsEnabled()) { var details = PrepareTrace(source); this.TokenRenewScheduled(interval.ToString(), details.Source); } } [Event(40257, Level = EventLevel.Informational, Message = "{1}: Scheduling Token renewal after {0}.")] void TokenRenewScheduled(string interval, string source) { this.WriteEvent(40257, interval, source); } [NonEvent] public ArgumentNullException ArgumentNull(string paramName, object source = null, EventLevel level = EventLevel.Error) { return this.ThrowingException(new ArgumentNullException(paramName), source, level); } [NonEvent] public ArgumentException Argument(string paramName, string message, object source = null, EventLevel level = EventLevel.Error) { return this.ThrowingException(new ArgumentException(message, paramName), source, level); } [NonEvent] public ArgumentOutOfRangeException ArgumentOutOfRange(string paramName, object actualValue, string message, object source = null, EventLevel level = EventLevel.Error) { return this.ThrowingException(new ArgumentOutOfRangeException(paramName, actualValue, message), source, level); } [NonEvent] public TException ThrowingException<TException>(TException exception, object source = null, EventLevel level = EventLevel.Error, [CallerMemberName] string memberName = "") where TException : Exception { // Avoid converting ToString, etc. if ETW tracing is not enabled. if (this.IsEnabled(level, EventKeywords.None)) { var details = PrepareTrace(source); string exceptionString = ExceptionToString(exception, details.TrackingContext); switch (level) { case EventLevel.Critical: case EventLevel.LogAlways: case EventLevel.Error: this.ThrowingExceptionError(details.Source, exceptionString, memberName); break; case EventLevel.Warning: this.ThrowingExceptionWarning(details.Source, exceptionString, memberName); break; case EventLevel.Informational: case EventLevel.Verbose: default: this.ThrowingExceptionInfo(details.Source, exceptionString, memberName); break; } } // This allows "throw ServiceBusEventSource.Log.ThrowingException(..." return exception; } [Event(40262, Level = EventLevel.Error, Message = "{0}.{2}: Throwing an Exception: {1}")] void ThrowingExceptionError(string source, string exception, string memberName) { // The IsEnabled() check is in the [NonEvent] Wrapper method this.WriteEvent(40262, source, exception, memberName); } [Event(40263, Level = EventLevel.Warning, Message = "{0}.{2}: Throwing an Exception: {1}")] void ThrowingExceptionWarning(string source, string exception, string memberName) { // The IsEnabled() check is in the [NonEvent] Wrapper method this.WriteEvent(40263, source, exception, memberName); } [Event(40264, Level = EventLevel.Informational, Message = "{0}.{2}: Throwing an Exception: {1}")] void ThrowingExceptionInfo(string source, string exception, string memberName) { // The IsEnabled() check is in the [NonEvent] Wrapper method this.WriteEvent(40264, source, exception, memberName); } [NonEvent] public void Warning(object source, string message) { if (this.IsEnabled()) { var details = PrepareTrace(source); if (details.TrackingContext != null) { message += " " + details.TrackingContext.ToString(); } this.Warning(details.Source, message); } } [Event(40303, Level = EventLevel.Informational, Message = "{0}: {1}")] void Warning(string source, string details) { this.WriteEvent(40303, source, details); } [NonEvent] public void Info(object source, string message) { if (this.IsEnabled()) { var details = PrepareTrace(source); this.Info(details.Source, message); } } [NonEvent] public void Info(string source, TrackingContext trackingContext, string message) { if (this.IsEnabled()) { SetCurrentThreadActivityId(trackingContext); this.Info(source, message); } } [Event(40304, Level = EventLevel.Informational, Message = "{0}: {1}")] void Info(string source, string details) { this.WriteEvent(40304, source, details); } [NonEvent] public void HybridHttpResponseStreamWrite(TrackingContext trackingContext, int count) { if (this.IsEnabled(EventLevel.Verbose, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.HybridHttpResponseStreamWrite(count); } } [Event(40306, Level = EventLevel.Verbose, Message = "HybridHttpConnection+ResponseStream: WriteAsync(count={0})")] void HybridHttpResponseStreamWrite(int count) { this.WriteEvent(40306, count); } [NonEvent] public void HybridHttpResponseStreamFlush(TrackingContext trackingContext, string reason) { if (this.IsEnabled(EventLevel.Verbose, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.HybridHttpResponseStreamFlush(reason); } } [Event(40307, Level = EventLevel.Verbose, Message = "HybridHttpConnection+ResponseStream: FlushCoreAsync(reason={0})")] void HybridHttpResponseStreamFlush(string reason) { this.WriteEvent(40307, reason); } [NonEvent] public void HybridHttpConnectionSendBytes(TrackingContext trackingContext, int count) { if (this.IsEnabled(EventLevel.Verbose, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.HybridHttpConnectionSendBytes(count); } } [Event(40308, Level = EventLevel.Verbose, Message = "HybridHttpConnection: Sending {0} bytes on the rendezvous connection")] void HybridHttpConnectionSendBytes(int count) { this.WriteEvent(40308, count); } [NonEvent] public void HybridHttpCreatingRendezvousConnection(TrackingContext trackingContext) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.HybridHttpCreatingRendezvousConnection(); } } [Event(40309, Level = EventLevel.Informational, Message = "HybridHttpConnection: Creating the rendezvous connection")] void HybridHttpCreatingRendezvousConnection() { this.WriteEvent(40309); } [NonEvent] public void HybridHttpConnectionSendResponse(TrackingContext trackingContext, string connection, int status) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.HybridHttpConnectionSendResponse(connection, status); } } [Event(40310, Level = EventLevel.Informational, Message = "HybridHttpConnection: Sending the response command on the {0} connection, status: {1}")] void HybridHttpConnectionSendResponse(string connection, int status) { this.WriteEvent(40310, connection, status); } [Event(40311, Level = EventLevel.Warning, Message = "HybridHttpConnection: No RequestHandler is configured on the listener")] public void HybridHttpConnectionMissingRequestHandler() { this.WriteEvent(40311); } [NonEvent] public void HybridHttpReadRendezvousValue(object source, string value) { if (this.IsEnabled(EventLevel.Verbose, EventKeywords.None)) { var details = PrepareTrace(source); this.HybridHttpReadRendezvousValue(value); } } [Event(40313, Level = EventLevel.Verbose, Message = "HybridHttpConnection: Reading {0} from the rendezvous connection")] void HybridHttpReadRendezvousValue(string value) { this.WriteEvent(40313, value); } [NonEvent] public void HybridHttpRequestStarting(TrackingContext trackingContext) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.HybridHttpRequestStarting(trackingContext?.ToString() ?? string.Empty); } } [Event(40314, Level = EventLevel.Informational, Message = "HybridHttpConnection: request initializing. {0}")] void HybridHttpRequestStarting(string details) { this.WriteEvent(40314, details); } [NonEvent] public void HybridHttpRequestReceived(TrackingContext trackingContext, string method) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.None)) { SetCurrentThreadActivityId(trackingContext); this.HybridHttpRequestReceived(method, trackingContext?.Address ?? string.Empty); } } [Event(40315, Level = EventLevel.Informational, Message = "HybridHttpConnection: Request: {0} {1}")] void HybridHttpRequestReceived(string method, string address) { this.WriteEvent(40315, method, address); } [Event(40316, Level = EventLevel.Informational, Message = "HybridHttpConnection: Invoking user RequestHandler")] public void HybridHttpInvokingUserRequestHandler() { this.WriteEvent(40316); } [NonEvent] internal static string CreateSourceString(object source) { Type type; if (source == null) { return string.Empty; } else if ((type = source as Type) != null) { return type.Name; } return source.ToString(); } [NonEvent] static string ExceptionToString(Exception exception, TrackingContext trackingContext = null) { string exceptionString = exception?.ToString() ?? string.Empty; if (trackingContext != null) { exceptionString = $"{trackingContext}: {exceptionString}"; } return exceptionString; } [NonEvent] static string DateTimeToString(DateTime dateTime) { return dateTime.ToString(CultureInfo.InvariantCulture); } static TraceDetails PrepareTrace(object source) { string sourceString; TrackingContext trackingContext; var traceSource = source as ITraceSource; if (traceSource != null) { trackingContext = traceSource.TrackingContext; SetCurrentThreadActivityId(trackingContext); sourceString = traceSource.ToString(); } else { sourceString = CreateSourceString(source); trackingContext = null; } return new TraceDetails(sourceString, trackingContext); } static void SetCurrentThreadActivityId(TrackingContext trackingContext) { if (trackingContext != null) { SetCurrentThreadActivityId(trackingContext.ActivityId); } } public class Keywords // This is a bitvector { //public const EventKeywords Client = (EventKeywords)0x0001; //public const EventKeywords Relay = (EventKeywords)0x0002; //public const EventKeywords Messaging = (EventKeywords)0x0002; } struct TraceDetails { public string Source; public TrackingContext TrackingContext; public TraceDetails(string source, TrackingContext trackingContext) { this.Source = source; this.TrackingContext = trackingContext; } } } }