123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.IO;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- using Wayne.Lib.IO;
- namespace Wayne.Lib.Log
- {
- /// <summary>
- /// Logger is a static class used to create log objects.
- /// </summary>
- public static class Logger
- {
- #region Fields
- /// <summary>
- /// Default date and time format to use in log files.
- /// </summary>
- public const string DefaultDateTimeFormat = "HH':'mm':'ss'.'fff'[#]'";
- private const int DefaultDebugMarkerBroadcastPort = 11001;
- private static readonly List<DebugLogger> OutstandingLogObjects = new List<DebugLogger>();
- private static readonly object OutstandingLogObjectsLock = new object(); // Locking object to safely access the OutstandingLogObjects.
- private static readonly Dictionary<string, IEventSubscriber> EventSubscriberDict = new Dictionary<string, IEventSubscriber>();
- private static readonly object EventSubscriberDictSyncObj = new object();
- private static readonly Dictionary<string, ExternalLogWriter> ExternalLogWriterNameDict = new Dictionary<string, ExternalLogWriter>();
- private static readonly Dictionary<ExternalLogWriterWrapper, ExternalLogWriter> ExternalLogWriterWrapperDict = new Dictionary<ExternalLogWriterWrapper, ExternalLogWriter>();
- private static readonly object ExternalLogWriterDictSyncObj = new object();
- private static readonly byte[] DebugMarkerBroadcastReceiverBuffer = new byte[100];
- private static readonly List<string> DebugConfigFileNameList = new List<string>();
- private static readonly List<string> EventConfigFileNameList = new List<string>();
- private static readonly List<string[]> DebugConfigFilesList = new List<string[]>();
- private static readonly List<string[]> EventConfigFilesList = new List<string[]>();
- private static readonly List<LogConfigBuilder> DebugConfigBuilderList = new List<LogConfigBuilder>();
- private static readonly List<LogConfigBuilder> EventConfigBuilderList = new List<LogConfigBuilder>();
- private static readonly List<LogConfigOutput> LeftoverLinesLogConfigOutputs = new List<LogConfigOutput>();
- private static readonly List<LogConfigOutput> LeftoverEntitiesLogConfigOutputs = new List<LogConfigOutput>();
- private static bool active;
- private static LoggerThread loggerThread;
- private static LoggerThread eventLoggerThread;
- private static LogConfig debugConfig;
- private static LogConfig eventConfig;
- private static DotNetLog dotNetLog;
- private static GlobalLogEntryCounter globalLogEntryCounter;
- private static IPEndPoint debugMarkerBroadcastAddress;
- private static System.Net.Sockets.Socket debugMarkerBroadcastReceiverSocket;
- #endregion
- #region Construction
- static Logger()
- {
- Reset();
- }
- #endregion
- #region Internal Properties
- /// <summary>
- /// Tells whether someone has called the Close() method.
- /// </summary>
- public static bool IsClosed
- {
- get { return !active; }
- }
- /// <summary>
- /// Internal access to the DebugConfig.
- /// </summary>
- internal static LogConfig DebugConfig
- {
- get { return debugConfig; }
- }
- /// <summary>
- /// Internal access to the GlobalLogEntryCounter.
- /// </summary>
- internal static GlobalLogEntryCounter GlobalLogEntryCounter
- {
- get { return globalLogEntryCounter; }
- }
- #endregion
- #region Internal Methods
- /// <summary>
- /// This method is used to fire an event instead of throwing an exception if something
- /// "crashes" in a thread (in order to keep the thread alive but still "report" exceptions).
- /// </summary>
- /// <param name="exception"></param>
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")]
- internal static void FireOnThreadException(LogException exception)
- {
- try
- {
- if (OnThreadException != null)
- OnThreadException(null, new EventArgs<LogException>(exception));
- }
- catch (Exception) { }
- }
- /// <summary>
- /// Internal method that is used by the EventLogSubscriptionLogWriter to publish an
- /// event entry to a specific subscriber.
- /// </summary>
- /// <param name="eventSubscriberId"></param>
- /// <param name="eventLogEntry"></param>
- /// <param name="storageType"></param>
- internal static void PublishEventLog(string eventSubscriberId, EventLogEntry eventLogEntry,
- LogConfigEventLogStorageType storageType)
- {
- //eventLogStorage.Add(eventSubscriberId, eventLogEntry, storageType);
- IEventSubscriber eventSubscriber;
- lock (EventSubscriberDictSyncObj)
- {
- if (!EventSubscriberDict.TryGetValue(eventSubscriberId, out eventSubscriber))
- eventSubscriber = null;
- }
- if (eventSubscriber != null)
- eventSubscriber.HandleEvent(eventLogEntry);
- }
- #endregion
- #region Internal Methods: Persistent log objects
- internal static void RegisterPersistentLogObject(DebugLogger debugLogger)
- {
- lock (OutstandingLogObjectsLock)
- {
- if (!OutstandingLogObjects.Contains(debugLogger))
- OutstandingLogObjects.Add(debugLogger);
- }
- }
- internal static void UnregisterPersistentLogObject(DebugLogger debugLogger)
- {
- lock (OutstandingLogObjectsLock)
- {
- if (OutstandingLogObjects.Contains(debugLogger))
- OutstandingLogObjects.Remove(debugLogger);
- }
- }
- #endregion
- #region Public Events
- /// <summary>
- /// An event that is fired when the logging thread is catching an exception.
- /// </summary>
- public static event EventHandler<Wayne.Lib.EventArgs<LogException>> OnThreadException;
- #endregion
- #region Public Properties
- /// <summary>
- /// The current debug log configuration file.
- /// </summary>
- [Obsolete("This property is no longer supported. Use the property DebugLoggingConfigured to check whether it's active or not.", true)]
- public static string DebugConfigFileName
- {
- get { return string.Empty; }
- }
- /// <summary>
- /// The current event log configuration file.
- /// </summary>
- [Obsolete("This property is no longer supported. Use the property EventLoggingConfigured to check whether it's active or not.", true)]
- public static string EventConfigFileName
- {
- get { return string.Empty; }
- }
- /// <summary>
- /// Is any debug logging configured?
- /// </summary>
- public static bool DebugLoggingConfigured
- {
- get { return debugConfig.IsConfigured; }
- }
- /// <summary>
- /// Is any event logging configured?
- /// </summary>
- public static bool EventLoggingConfigured
- {
- get { return eventConfig.IsConfigured; }
- }
- /// <summary>
- /// Should the logger be synchronized or not?
- /// Default is false (the log writing is performed in another thread).
- /// </summary>
- public static bool Synchronized { get; set; }
- #endregion
- #region Public Methods: ConfigFile handling
- /// <summary>
- /// Clear all loaded log configuration .
- /// </summary>
- public static void ClearConfigFiles()
- {
- if (!active)
- return;
- DebugConfigFileNameList.Clear();
- EventConfigFileNameList.Clear();
- DebugConfigFilesList.Clear();
- EventConfigFilesList.Clear();
- DebugConfigBuilderList.Clear();
- EventConfigBuilderList.Clear();
- LeftoverLinesLogConfigOutputs.Clear();
- LeftoverEntitiesLogConfigOutputs.Clear();
- RefreshConfig();
- }
- /// <summary>
- /// Reloads the configuration from the specified configuration file.
- /// </summary>
- /// <param name="debugConfigFileName">Log configuration for the debug logging.</param>
- /// <param name="eventConfigFileName">Log configuration for the event logging.</param>
- public static void SetConfigFile(string debugConfigFileName, string eventConfigFileName)
- {
- if (!active)
- return;
- ClearConfigFiles();
- AddDebugConfigFile(debugConfigFileName);
- AddEventConfigFile(eventConfigFileName);
- }
- /// <summary>
- /// Reloads the configuration from the specified configuration file for the debug logging. To activate the event logging
- /// SetConfigFile(string,string) should be called.
- /// </summary>
- /// <param name="debugConfigFileName">Log configuration for the debug logging.</param>
- public static void SetConfigFile(string debugConfigFileName)
- {
- if (!active)
- return;
- ClearConfigFiles();
- AddDebugConfigFile(debugConfigFileName);
- }
- /// <summary>
- /// Reloads the configuration, adding the given debug log config file.
- /// </summary>
- /// <param name="debugConfigFileName">Log configuration for the debug logging.</param>
- public static void AddDebugConfigFile(string debugConfigFileName)
- {
- if (!active)
- return;
- DebugConfigFileNameList.Add(debugConfigFileName);
- RefreshConfig();
- }
- /// <summary>
- /// Reloads the configuration, adding the given debug log config file.
- /// </summary>
- /// <param name="logConfigBuilders">Log configurations for the debug logging.</param>
- public static void AddDebugConfigFile(params LogConfigBuilder[] logConfigBuilders)
- {
- if (!active)
- return;
- DebugConfigBuilderList.AddRange(logConfigBuilders);
- RefreshConfig();
- }
- /// <summary>
- /// Reloads the configuration, adding the given debug log config file.
- /// </summary>
- /// <param name="debugConfigFileStream">Log configuration for the debug logging.</param>
- public static void AddDebugConfigFile(Stream debugConfigFileStream)
- {
- AddDebugConfigFile(debugConfigFileStream, Encoding.UTF8);
- }
- /// <summary>
- /// Reloads the configuration, adding the given debug log config file.
- /// </summary>
- /// <param name="debugConfigFileStream">Log configuration for the debug logging.</param>
- /// <param name="encoding">The encoding of the stream.</param>
- public static void AddDebugConfigFile(Stream debugConfigFileStream, Encoding encoding)
- {
- if (!active)
- return;
- DebugConfigFilesList.Add(GetFileLines(debugConfigFileStream, encoding));
- RefreshConfig();
- }
- /// <summary>
- /// Reloads the configuration, adding the given event log config file.
- /// </summary>
- /// <param name="eventConfigFileName">Log configuration for the event logging.</param>
- public static void AddEventConfigFile(string eventConfigFileName)
- {
- if (!active)
- return;
- EventConfigFileNameList.Add(eventConfigFileName);
- RefreshConfig();
- }
- /// <summary>
- /// Reloads the configuration, adding the given event log config file.
- /// </summary>
- /// <param name="logConfigBuilders">Log configurations for the event logging.</param>
- public static void AddEventConfigFile(params LogConfigBuilder[] logConfigBuilders)
- {
- if (!active)
- return;
- EventConfigBuilderList.AddRange(logConfigBuilders);
- RefreshConfig();
- }
- /// <summary>
- /// Reloads the configuration, adding the given event log config file.
- /// </summary>
- /// <param name="eventConfigFileStream">Log configuration for the event logging.</param>
- public static void AddEventConfigFile(Stream eventConfigFileStream)
- {
- AddDebugConfigFile(eventConfigFileStream, Encoding.UTF8);
- }
- /// <summary>
- /// Reloads the configuration, adding the given event log config file.
- /// </summary>
- /// <param name="eventConfigFileStream">Log configuration for the event logging.</param>
- /// <param name="encoding">The encoding of the stream.</param>
- public static void AddEventConfigFile(Stream eventConfigFileStream, Encoding encoding)
- {
- if (!active)
- return;
- EventConfigFilesList.Add(GetFileLines(eventConfigFileStream, encoding));
- RefreshConfig();
- }
- /// <summary>
- /// Reloads the configuration, adding the given leftover log line output.
- /// </summary>
- /// <param name="output">An output to receive leftover log lines.</param>
- public static void AddLeftoverLinesOutput(LogConfigOutput output)
- {
- if (!active)
- return;
- LeftoverLinesLogConfigOutputs.Add((LogConfigOutput)output.Clone());
- RefreshConfig();
- }
- /// <summary>
- /// Reloads the configuration, adding the given leftover log entity output.
- /// </summary>
- /// <param name="output">An output to receive leftover log entities.</param>
- public static void AddLeftoverEntitiesOutput(LogConfigOutput output)
- {
- if (!active)
- return;
- LeftoverEntitiesLogConfigOutputs.Add((LogConfigOutput)output.Clone());
- RefreshConfig();
- }
- private static string[] GetFileLines(Stream fileStream, Encoding encoding)
- {
- List<string> lines = new List<string>();
- using (StreamReader reader = new StreamReader(fileStream, encoding))
- {
- while (!reader.EndOfStream)
- lines.Add(reader.ReadLine());
- }
- return lines.ToArray();
- }
- #endregion
- #region Public Methods: Refresh
- /// <summary>
- /// Re-loads the configuration for the logging.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")]
- public static void RefreshConfig()
- {
- if (!active)
- return;
- InitDebugMarkerBroadcastListener();
- // Refresh the DebugConfig.
- List<string[]> debugConfigFiles = new List<string[]>(DebugConfigFilesList);
- foreach (string fileName in DebugConfigFileNameList)
- debugConfigFiles.Add(FileSupport.LoadToStringArray(fileName));
- if (DebugConfigBuilderList.Count > 0)
- debugConfigFiles.Add(LogConfigBuilder.GetLogConfigFileLines(DebugConfigBuilderList.ToArray()));
- DebugConfig.Refresh(debugConfigFiles, LeftoverLinesLogConfigOutputs.ToArray(), LeftoverEntitiesLogConfigOutputs.ToArray());
- // Refresh the EventConfig.
- List<string[]> eventConfigFiles = new List<string[]>(EventConfigFilesList);
- foreach (string fileName in EventConfigFileNameList)
- eventConfigFiles.Add(FileSupport.LoadToStringArray(fileName));
- if (EventConfigBuilderList.Count > 0)
- eventConfigFiles.Add(LogConfigBuilder.GetLogConfigFileLines(EventConfigBuilderList.ToArray()));
- eventConfig.Refresh(eventConfigFiles, new LogConfigOutput[0], new LogConfigOutput[0]);
- // Start the thread if it's not yet started (first time it's null).
- if ((loggerThread == null) && (debugConfigFiles.Count > 0))
- loggerThread = new LoggerThread(LogType.Debug, debugConfig);
- if ((eventLoggerThread == null) && (eventConfigFiles.Count > 0))
- eventLoggerThread = new LoggerThread(LogType.Event, eventConfig);
- // To prevent locking the list while iterating, take a copy and iterate through the copy.
- // The danger of doing this is that an object could be removed after the copy and before its
- // Invalidate-method is called. But nothing really bad can happen due to this...
- List<DebugLogger> outstandingLogObjectsCopy;
- lock (OutstandingLogObjectsLock)
- {
- outstandingLogObjectsCopy = new List<DebugLogger>(OutstandingLogObjects);
- }
- foreach (DebugLogger debugLogger in outstandingLogObjectsCopy)
- {
- try
- {
- debugLogger.Invalidate();
- }
- catch (Exception) { }
- }
- // Check if the dotNetLog should be active or not.
- dotNetLog.CheckActive();
- }
- #endregion
- #region Public Methods: Reset
- /// <summary>
- /// Resets the logger completely.
- /// </summary>
- public static void Reset()
- {
- Close();
- active = true;
- debugConfig = new LogConfig();
- eventConfig = new LogConfig();
- dotNetLog = new DotNetLog();
- globalLogEntryCounter = new GlobalLogEntryCounter();
- }
- #endregion
- #region Public Methods: Close
- /// <summary>
- /// Closes the logger. This should be done as the last things before the application terminates.
- /// </summary>
- public static void Close()
- {
- if (active)
- {
- // Shut down the config.
- if (debugConfig != null)
- {
- debugConfig.Dispose();
- debugConfig = null;
- }
- if (eventConfig != null)
- {
- eventConfig.Dispose();
- eventConfig = null;
- }
- if (dotNetLog != null)
- {
- // Shut down the dotNetLog.
- dotNetLog.Dispose();
- dotNetLog = null;
- }
- ExternalLogWriterNameDict.Clear();
- ExternalLogWriterWrapperDict.Clear();
- // Now we're closed.
- active = false;
- // Shut down the loggerThread.
- if (loggerThread != null)
- {
- loggerThread.Dispose();
- loggerThread = null;
- }
- if (eventLoggerThread != null)
- {
- eventLoggerThread.Dispose();
- eventLoggerThread = null;
- }
- if (debugMarkerBroadcastReceiverSocket != null)
- {
- try
- {
- if (debugMarkerBroadcastReceiverSocket.Connected)
- {
- debugMarkerBroadcastReceiverSocket.Shutdown(SocketShutdown.Both);
- }
- }
- catch { }
- try
- {
- debugMarkerBroadcastReceiverSocket.Close();
- }
- catch { }
- debugMarkerBroadcastReceiverSocket = null;
- }
- if (globalLogEntryCounter != null)
- {
- globalLogEntryCounter.Dispose();
- globalLogEntryCounter = null;
- }
- debugMarkerBroadcastAddress = null;
- DebugConfigFileNameList.Clear();
- DebugConfigFilesList.Clear();
- EventConfigFileNameList.Clear();
- EventConfigFilesList.Clear();
- DebugConfigBuilderList.Clear();
- EventConfigBuilderList.Clear();
- OutstandingLogObjects.Clear();
- EventSubscriberDict.Clear();
- LeftoverLinesLogConfigOutputs.Clear();
- LeftoverEntitiesLogConfigOutputs.Clear();
- Synchronized = false;
- }
- }
- #endregion
- #region Public Methods: LogEntry
- /// <summary>
- /// Logs the given LogEntry.
- /// </summary>
- /// <param name="logEntry">The LogEntry to log.</param>
- public static void AddEntry(LogEntry logEntry)
- {
- if (!active)
- return;
- if (loggerThread != null)
- loggerThread.AddEntry(logEntry);
- if ((eventLoggerThread != null) && (logEntry is EventLogEntry))
- eventLoggerThread.AddEntry(logEntry); // eventThread has higher priority?
- }
- /// <summary>
- /// Logs the given ExceptionLogEntry.
- /// </summary>
- /// <param name="logEntry">The LogEntry to log.</param>
- public static void AddExceptionLogEntry(ExceptionLogEntry logEntry)
- {
- AddEntry(logEntry);
- }
- /// <summary>
- /// Logs the given ErrorLogEntry.
- /// </summary>
- /// <param name="logEntry">The LogEntry to log.</param>
- public static void AddErrorLogEntry(ErrorLogEntry logEntry)
- {
- AddEntry(logEntry);
- }
- /// <summary>
- /// Logs the given EventLogEntry.
- /// </summary>
- /// <param name="logEntry">The LogEntry to log.</param>
- public static void AddEventLogEntry(EventLogEntry logEntry)
- {
- AddEntry(logEntry);
- }
- #endregion
- #region Public Methods: Unregister entity
- /// <summary>
- /// Removes the specified entity from the internal filter buffers.
- /// </summary>
- /// <param name="entity"></param>
- public static void UnregisterEntity(IIdentifiableEntity entity)
- {
- if (debugConfig != null)
- debugConfig.UnregisterEntity(entity);
- if (eventConfig != null)
- eventConfig.UnregisterEntity(entity);
- }
- #endregion
- #region Public Methods for Event Subscribers
- /// <summary>
- /// Remove an event log from the storage. This method should be called from a registered IEventSubscriber when
- /// it has handled an event.
- /// </summary>
- /// <param name="eventSubscriber"></param>
- /// <param name="eventLogEntry"></param>
- public static void EventLogHandled(IEventSubscriber eventSubscriber, EventLogEntry eventLogEntry)
- {
- //eventLogStorage.Remove(eventSubscriber, eventLogEntry);
- }
- /// <summary>
- /// Register an IEventSubscriber, so it can start receiving events. The event subscriber will be sent the pending events that
- /// has been stored since the subscriber was registered the last time.
- /// </summary>
- /// <param name="eventSubscriber"></param>
- public static void RegisterEventSubscriber(IEventSubscriber eventSubscriber)
- {
- if (eventSubscriber == null)
- throw new ArgumentNullException("eventSubscriber");
- lock (EventSubscriberDictSyncObj)
- {
- EventSubscriberDict[eventSubscriber.SubscriberId] = eventSubscriber;
- }
- //EventLogEntry[] entries = eventLogStorage.GetPendingEvents(eventSubscriber.SubscriberId);
- //foreach (EventLogEntry entry in entries)
- // eventSubscriber.HandleEvent(entry);
- }
- /// <summary>
- /// Unregister a registered IEventSubscriber.
- /// </summary>
- /// <param name="eventSubscriber"></param>
- public static void UnregisterEventSubscriber(IEventSubscriber eventSubscriber)
- {
- if (eventSubscriber == null)
- throw new ArgumentNullException("eventSubscriber");
- lock (EventSubscriberDictSyncObj)
- {
- EventSubscriberDict.Remove(eventSubscriber.SubscriberId);
- }
- }
- #endregion
- #region ExternalLogging
- private static string GetExternalLogWriterKey(ExternalLogWriter externalLogWriter)
- {
- return string.Format("{0}#{1}", externalLogWriter.ExternalLogType, externalLogWriter.ExternalLogName);
- }
- private static string GetExternalLogWriterKey(ExternalLogWriterWrapper externalLogWriterWrapper)
- {
- return string.Format("{0}#{1}", externalLogWriterWrapper.ExternalLogType, externalLogWriterWrapper.ExternalLogName);
- }
- /// <summary>
- /// Register an ExternalLogWriter.
- /// </summary>
- /// <param name="externalLogWriter">The external log writer to register.</param>
- public static void RegisterExternalLogger(ExternalLogWriter externalLogWriter)
- {
- if (ExternalLogWriterDictSyncObj != null)
- lock (ExternalLogWriterDictSyncObj)
- ExternalLogWriterNameDict[GetExternalLogWriterKey(externalLogWriter)] = externalLogWriter;
- }
- /// <summary>
- /// Unregister an ExternalLogWriter.
- /// </summary>
- /// <param name="externalLogWriter">The external log writer to unregister.</param>
- public static void UnregisterExternalLogger(ExternalLogWriter externalLogWriter)
- {
- if (ExternalLogWriterDictSyncObj != null)
- lock (ExternalLogWriterDictSyncObj)
- {
- ExternalLogWriterNameDict.Remove(GetExternalLogWriterKey(externalLogWriter));
- bool found;
- do
- {
- found = false;
- foreach (KeyValuePair<ExternalLogWriterWrapper, ExternalLogWriter> pair in ExternalLogWriterWrapperDict)
- {
- if (pair.Value == externalLogWriter)
- {
- ExternalLogWriterWrapperDict.Remove(pair.Key);
- found = true;
- break;
- }
- }
- }
- while (found);
- }
- }
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- internal static void PerformExternalLogEntry(ExternalLogWriterWrapper externalLogWriterWrapper, LogEntry logEntry)
- {
- if (ExternalLogWriterDictSyncObj != null)
- {
- lock (ExternalLogWriterDictSyncObj)
- {
- ExternalLogWriter externalLogWriter;
- if (!ExternalLogWriterWrapperDict.TryGetValue(externalLogWriterWrapper, out externalLogWriter))
- {
- if (ExternalLogWriterNameDict.TryGetValue(GetExternalLogWriterKey(externalLogWriterWrapper), out externalLogWriter))
- {
- externalLogWriter.InitParametersInternal(externalLogWriterWrapper.Parameters);
- ExternalLogWriterWrapperDict[externalLogWriterWrapper] = externalLogWriter;
- }
- }
- if (externalLogWriter != null)
- {
- try
- {
- if (externalLogWriter.Active)
- {
- string text = LogTextWriting.GetLogEntryText(externalLogWriterWrapper, logEntry,
- externalLogWriterWrapper.WritingParameters);
- externalLogWriter.LogInternal(logEntry, text);
- }
- }
- catch { }
- }
- }
- }
- }
- /// <summary>
- /// Get the LogTextWritingParameters for the requested ExternalLogWriter.
- /// </summary>
- /// <param name="externalLogWriter">The ExternalLogWriter to get the parameters of.</param>
- [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#")]
- internal static LogTextWritingParameters GetExternalLoggerWritingParameters(ExternalLogWriter externalLogWriter)
- {
- if (ExternalLogWriterDictSyncObj != null)
- {
- lock (ExternalLogWriterDictSyncObj)
- {
- foreach (KeyValuePair<ExternalLogWriterWrapper, ExternalLogWriter> pair in ExternalLogWriterWrapperDict)
- {
- if (pair.Value == externalLogWriter)
- {
- return pair.Key.WritingParameters;
- }
- }
- }
- }
- return null;
- }
- #endregion
- #region Debug Marker Broadcasting
- /// <summary>
- /// Broadcasts a debug marker to be inserted into all active logfiles.
- /// </summary>
- /// <param name="debugMarker">The text to insert into all the log files.</param>
- // public static void InjectDebugMarker(string debugMarker)
- // {
- // try
- // {
- // System.Net.Sockets.Socket transmitterSocket = null;
- // try
- // {
- // try
- // {
- //transmitterSocket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.IP);
- // transmitterSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
- // var lingerOption = new LingerOption(true, 0);
- // transmitterSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lingerOption);
- // transmitterSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, 1);
- // transmitterSocket.Bind(new IPEndPoint(IPAddress.Any, 0)); // Bind the socket to the "any" end point.
- // byte[] data = Encoding.UTF8.GetBytes(debugMarker);
- // int offset = 0;
- // int size = data.Length;
- // if (size > DebugMarkerBroadcastReceiverBuffer.Length)
- // size = DebugMarkerBroadcastReceiverBuffer.Length;
- // int currentSentSize;
- // do
- // {
- // currentSentSize = transmitterSocket.SendTo(data, offset, size, SocketFlags.None, GetDebugMarkerBroadcastIPEndPoint());
- // offset += currentSentSize;
- // size -= currentSentSize;
- // }
- // while ((size > 0) && (currentSentSize > 0));
- // }
- // catch (Exception) { }
- // }
- // finally
- // {
- // if (transmitterSocket != null)
- // {
- // try
- // {
- // transmitterSocket.Shutdown(SocketShutdown.Both);
- // }
- // finally
- // {
- // transmitterSocket.Close();
- // }
- // }
- // }
- // }
- // catch (Exception) { }
- // }
- private static void InitDebugMarkerBroadcastListener()
- {
- if (debugMarkerBroadcastReceiverSocket == null)
- {
- try
- {
- debugMarkerBroadcastReceiverSocket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.IP);
- debugMarkerBroadcastReceiverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
- //debugMarkerBroadcastReceiverSocket.Bind(new IPEndPoint(IPAddress.Any, GetDebugMarkerBroadcastIPEndPoint().Port)); // Bind the socket to the "any" end point.
- debugMarkerBroadcastReceiverSocket.BeginReceive(DebugMarkerBroadcastReceiverBuffer, 0, DebugMarkerBroadcastReceiverBuffer.Length, 0, ReceiveCallback, debugMarkerBroadcastReceiverSocket); // Start to listen.
- }
- catch
- {
- try
- {
- debugMarkerBroadcastReceiverSocket.Close();
- }
- catch (Exception)
- {
- }
- debugMarkerBroadcastReceiverSocket = null;
- }
- }
- }
- private static void ReceiveCallback(IAsyncResult ar)
- {
- if (debugMarkerBroadcastReceiverSocket != null)
- {
- try
- {
- try
- {
- System.Net.Sockets.Socket socket = (System.Net.Sockets.Socket)ar.AsyncState;
- int bytesReceived = 0;
- try
- {
- try
- {
- bytesReceived = socket.EndReceive(ar);
- }
- catch { }
- }
- finally
- {
- if (bytesReceived > 0)
- {
- string debugMarker = Encoding.UTF8.GetString(DebugMarkerBroadcastReceiverBuffer, 0, bytesReceived);
- AddEntry(new DebugMarkerLogEntry(debugMarker));
- }
- }
- }
- finally
- {
- if (active)
- debugMarkerBroadcastReceiverSocket.BeginReceive(DebugMarkerBroadcastReceiverBuffer, 0, DebugMarkerBroadcastReceiverBuffer.Length, 0, ReceiveCallback, debugMarkerBroadcastReceiverSocket);
- }
- }
- catch { }
- }
- }
- //[System.Diagnostics.DebuggerStepThrough()]
- //private static IPEndPoint GetDebugMarkerBroadcastIPEndPoint()
- //{
- // try
- // {
- // if (debugMarkerBroadcastAddress == null)
- // {
- // using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"Software\Dresser Wayne\ISM Nucleus\TCP IP\UDP Broadcast", false))
- // {
- // IPAddress broadcastAddress;
- // int broadcastPort;
- // if (key != null)
- // {
- // broadcastAddress = IPAddress.Parse((string)key.GetValue("BroadcastAddress", "255.255.255.255"));
- // broadcastPort = (int)key.GetValue("LogMarkerInjectorPort", DefaultDebugMarkerBroadcastPort);
- // }
- // else
- // {
- // broadcastPort = DefaultDebugMarkerBroadcastPort;
- // broadcastAddress = IPAddress.Broadcast;
- // }
- // if (broadcastAddress != null)
- // debugMarkerBroadcastAddress = new IPEndPoint(broadcastAddress, broadcastPort);
- // }
- // }
- // }
- // catch
- // {
- // if (debugMarkerBroadcastAddress == null)
- // debugMarkerBroadcastAddress = new IPEndPoint(IPAddress.Broadcast, DefaultDebugMarkerBroadcastPort);
- // }
- // return debugMarkerBroadcastAddress;
- //}
- #endregion
- #region DateTimeToString
- internal static string DateTimeToString(DateTime dateTime, string dateTimeFormat)
- {
- if (GlobalLogEntryCounter != null)
- return DateTimeToString(dateTime, dateTimeFormat, GlobalLogEntryCounter.GetNextValue());
- return DateTimeToString(dateTime, dateTimeFormat, 0);
- }
- internal static string DateTimeToString(DateTime dateTime, string dateTimeFormat, UInt64 logEntryIndex)
- {
- return FormatDateTime(dateTime) + "[" + logEntryIndex.ToString("00000") + "]";
- }
- private static string FormatDateTime(DateTime dt)
- {
- char[] chars = new char[12];
- Write2Chars(chars, 0, dt.Hour);
- chars[2] = ':';
- Write2Chars(chars, 3, dt.Minute);
- chars[5] = ':';
- Write2Chars(chars, 6, dt.Second);
- chars[8] = '.';
- Write2Chars(chars, 9, dt.Millisecond / 10);
- chars[11] = Digit(dt.Millisecond % 10);
- return new string(chars);
- }
- private static void Write2Chars(char[] chars, int offset, int value)
- {
- chars[offset] = Digit(value / 10);
- chars[offset + 1] = Digit(value % 10);
- }
- private static char Digit(int value)
- {
- return (char)(value + '0');
- }
- #endregion
- }
- }
|