/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Text; using System.ComponentModel; namespace Amazon.Runtime.Internal.Util { /// /// Logger wrapper for System.Diagnostics.TraceSource logger. /// internal class InternalSystemDiagnosticsLogger : InternalLogger { volatile int eventId = 0; TraceSource trace; public InternalSystemDiagnosticsLogger(Type declaringType) : base(declaringType) { this.trace = TraceSourceUtil.GetTraceSource(declaringType); } #region Overrides public override void Flush() { if (trace != null) this.trace.Flush(); } public override void Error(Exception exception, string messageFormat, params object[] args) { trace.TraceData(TraceEventType.Error, eventId++, new LogMessage(CultureInfo.InvariantCulture, messageFormat, args), exception); } public override void Debug(Exception exception, string messageFormat, params object[] args) { trace.TraceData(TraceEventType.Verbose, eventId++, new LogMessage(CultureInfo.InvariantCulture, messageFormat, args), exception); } public override void DebugFormat(string messageFormat, params object[] args) { trace.TraceData(TraceEventType.Verbose, eventId++, new LogMessage(CultureInfo.InvariantCulture, messageFormat, args)); } public override void InfoFormat(string message, params object[] arguments) { trace.TraceData(TraceEventType.Information, eventId++, new LogMessage(CultureInfo.InvariantCulture, message, arguments)); } public override bool IsDebugEnabled { get { return (trace != null); } } public override bool IsErrorEnabled { get { return (trace != null); } } public override bool IsInfoEnabled { get { return (trace != null); } } #endregion } /// /// Creates TraceRoute for a given Type or the closest "parent" that has a listener configured. /// Example: if type is Amazon.DynamoDB.AmazonDynamoDBClient, listeners can be configured for: /// -Amazon.DynamoDB.AmazonDynamoDBClient /// -Amazon.DynamoDB /// -Amazon /// The first matching TraceSource with listeners will be used. /// If no listeners are configured for type or one of its "parents", will return null. /// internal static class TraceSourceUtil { #region Public methods /// /// Gets a TraceSource for given Type with SourceLevels.All. /// If there are no listeners configured for targetType or one of its "parents", returns null. /// /// /// public static TraceSource GetTraceSource(Type targetType) { return GetTraceSource(targetType, SourceLevels.All); } /// /// Gets a TraceSource for given Type and SourceLevels. /// If there are no listeners configured for targetType or one of its "parents", returns null. /// /// /// /// public static TraceSource GetTraceSource(Type targetType, SourceLevels sourceLevels) { TraceSource traceSource = GetTraceSourceWithListeners(targetType.FullName, sourceLevels); return traceSource; } #endregion #region Private methods // Gets the name of the closest "parent" TraceRoute that has listeners, or null otherwise. private static TraceSource GetTraceSourceWithListeners(string name, SourceLevels sourceLevels) { string[] parts = name.Split(new char[] { '.' }, StringSplitOptions.None); List namesToTest = new List(); StringBuilder sb = new StringBuilder(); foreach (var part in parts) { if (sb.Length > 0) sb.Append("."); sb.Append(part); string partialName = sb.ToString(); namesToTest.Add(partialName); } namesToTest.Reverse(); foreach (var testName in namesToTest) { TraceSource ts = new TraceSource(testName, sourceLevels); ts.Listeners.AddRange(AWSConfigs.TraceListeners(testName)); // no listeners? skip if (ts.Listeners == null || ts.Listeners.Count == 0) { ts.Close(); continue; } // more than one listener? use this TraceSource if (ts.Listeners.Count > 1) return ts; TraceListener listener = ts.Listeners[0]; // single listener isn't DefaultTraceListener? use this TraceRoute if (!(listener is DefaultTraceListener)) return ts; // single listener is DefaultTraceListener but isn't named Default? use this TraceRoute if (!string.Equals(listener.Name, "Default", StringComparison.Ordinal)) return ts; // not the TraceSource we're looking for, close it ts.Close(); } // nothing found? no listeners are configured for any of the names, even the original, // so return null to signify failure return null; } #endregion } }