/// <summary> /// Stop the Logger and release any resources held by the Logger. /// </summary> /// <remarks> /// This method has no effect if the Logger has already been stopped. /// Stopping a Logger makes it unusable. Any attempt to use a stopped /// Logger may result in an exception. /// </remarks> public virtual void Shutdown() { lock (this) { if (IsStarted) { // zero length Log info serves as a shutdown marker Queue.Add(new object[0]); try { Monitor.Wait(this, 1000); } catch (Exception) { Stop(); } finally { LogOutput.Close(); } } } }
/// <summary> /// Event notification to perform a regular daemon activity. /// </summary> /// <remarks> /// To get it called, another thread has to set /// <see cref="Util.Daemon.Daemon.IsNotification"/> to <b>true</b>: /// <code>daemon.IsNotification = true;</code> /// </remarks> /// <seealso cref="Util.Daemon.Daemon.OnWait"/> protected override void OnNotify() { int MAX_TOTAL = Limit; int totalCharCount = 0; bool truncate = false; int truncateCount = 0; int truncateLinesCount = 0; int truncateCharCount = 0; bool isDone = false; do { object[] message = (object[])Queue.RemoveNoWait(); // check for end of queue; if any messages have been discarded, report the // number and size if (message == null) { if (truncate && truncateCount > 0) { message = new object[] { DateTime.Now, GetInteger(LEVEL_WARNING), Thread.CurrentThread, null, "Asynchronous logging character limit exceeded; discarding " + truncateCount + " Log messages " + "(lines=" + truncateLinesCount + ", chars=" + truncateCharCount + ")" }; isDone = true; } else { break; } } if (message.Length == 0) { // zero length message array serves as a shutdown marker IsExiting = true; return; } int level = (int)message[1]; if (level > Level) { // Log level must have been changed after start continue; } string text = FormatMessage(message); string textSafe = text == null ? String.Empty : text; Exception exception = message[3] as Exception; string exc = exception == null ? String.Empty : (exception.StackTrace == null ? String.Empty : exception.StackTrace); totalCharCount += textSafe.Length + exc.Length; if (truncate && !isDone) { truncateCount += 1; truncateLinesCount += textSafe.Split('\n').Length; truncateLinesCount += exc.Split('\n').Length; truncateCharCount += textSafe.Length; truncateCharCount += exc.Length; } else { if (totalCharCount > MAX_TOTAL) { truncate = true; } OnLog(); if (exception == null) { LogOutput.Log(level, textSafe); } else if (text == null) { LogOutput.Log(level, exception); } else { LogOutput.Log(level, exception, textSafe); } } }while (!isDone); }