aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Logging/SimpleLogManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Logging/SimpleLogManager.cs')
-rw-r--r--Emby.Server.Implementations/Logging/SimpleLogManager.cs301
1 files changed, 301 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Logging/SimpleLogManager.cs b/Emby.Server.Implementations/Logging/SimpleLogManager.cs
new file mode 100644
index 000000000..6129f38c4
--- /dev/null
+++ b/Emby.Server.Implementations/Logging/SimpleLogManager.cs
@@ -0,0 +1,301 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Logging;
+
+namespace Emby.Server.Implementations.Logging
+{
+ public class SimpleLogManager : ILogManager, IDisposable
+ {
+ public LogSeverity LogSeverity { get; set; }
+ public string ExceptionMessagePrefix { get; set; }
+ private FileLogger _fileLogger;
+
+ private readonly string LogDirectory;
+ private readonly string LogFilePrefix;
+ public string DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";
+
+ public SimpleLogManager(string logDirectory, string logFileNamePrefix)
+ {
+ LogDirectory = logDirectory;
+ LogFilePrefix = logFileNamePrefix;
+ }
+
+ public ILogger GetLogger(string name)
+ {
+ return new NamedLogger(name, this);
+ }
+
+ public void ReloadLogger(LogSeverity severity)
+ {
+ LogSeverity = severity;
+
+ var logger = _fileLogger;
+ if (logger != null)
+ {
+ logger.Dispose();
+ }
+
+ var path = Path.Combine(LogDirectory, LogFilePrefix + "-" + decimal.Floor(DateTime.Now.Ticks / 10000000) + ".txt");
+
+ _fileLogger = new FileLogger(path);
+
+ if (LoggerLoaded != null)
+ {
+ try
+ {
+
+ LoggerLoaded(this, EventArgs.Empty);
+
+ }
+ catch (Exception ex)
+ {
+ GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex);
+ }
+ }
+ }
+
+ public event EventHandler LoggerLoaded;
+
+ public void Flush()
+ {
+ var logger = _fileLogger;
+ if (logger != null)
+ {
+ logger.Flush();
+ }
+ }
+
+ private bool _console = true;
+ public void AddConsoleOutput()
+ {
+ _console = true;
+ }
+
+ public void RemoveConsoleOutput()
+ {
+ _console = false;
+ }
+
+ public void Log(string message)
+ {
+ if (_console)
+ {
+ Console.WriteLine(message);
+ }
+
+ var logger = _fileLogger;
+ if (logger != null)
+ {
+ message = DateTime.Now.ToString(DateTimeFormat) + " " + message;
+
+ logger.Log(message);
+ }
+ }
+
+ public void Dispose()
+ {
+ var logger = _fileLogger;
+ if (logger != null)
+ {
+ logger.Dispose();
+ }
+
+ _fileLogger = null;
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ public class FileLogger : IDisposable
+ {
+ private readonly FileStream _fileStream;
+
+ private bool _disposed;
+ private readonly CancellationTokenSource _cancellationTokenSource;
+ private readonly BlockingCollection<string> _queue = new BlockingCollection<string>();
+
+ public FileLogger(string path)
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+
+ _fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, 32768);
+ _cancellationTokenSource = new CancellationTokenSource();
+
+ Task.Factory.StartNew(LogInternal, _cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+ }
+
+ private void LogInternal()
+ {
+ while (!_cancellationTokenSource.IsCancellationRequested && !_disposed)
+ {
+ try
+ {
+ foreach (var message in _queue.GetConsumingEnumerable())
+ {
+ var bytes = Encoding.UTF8.GetBytes(message + Environment.NewLine);
+ if (_disposed)
+ {
+ return;
+ }
+
+ _fileStream.Write(bytes, 0, bytes.Length);
+
+ _fileStream.Flush(true);
+ }
+ }
+ catch
+ {
+
+ }
+ }
+ }
+
+ public void Log(string message)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ _queue.Add(message);
+ }
+
+ public void Flush()
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ _fileStream.Flush(true);
+ }
+
+ public void Dispose()
+ {
+ _cancellationTokenSource.Cancel();
+
+ Flush();
+
+ _disposed = true;
+ _fileStream.Dispose();
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ public class NamedLogger : ILogger
+ {
+ public string Name { get; private set; }
+ private readonly SimpleLogManager _logManager;
+
+ public NamedLogger(string name, SimpleLogManager logManager)
+ {
+ Name = name;
+ _logManager = logManager;
+ }
+
+ public void Info(string message, params object[] paramList)
+ {
+ Log(LogSeverity.Info, message, paramList);
+ }
+
+ public void Error(string message, params object[] paramList)
+ {
+ Log(LogSeverity.Error, message, paramList);
+ }
+
+ public void Warn(string message, params object[] paramList)
+ {
+ Log(LogSeverity.Warn, message, paramList);
+ }
+
+ public void Debug(string message, params object[] paramList)
+ {
+ if (_logManager.LogSeverity == LogSeverity.Info)
+ {
+ return;
+ }
+ Log(LogSeverity.Debug, message, paramList);
+ }
+
+ public void Fatal(string message, params object[] paramList)
+ {
+ Log(LogSeverity.Fatal, message, paramList);
+ }
+
+ public void FatalException(string message, Exception exception, params object[] paramList)
+ {
+ ErrorException(message, exception, paramList);
+ }
+
+ public void ErrorException(string message, Exception exception, params object[] paramList)
+ {
+ LogException(LogSeverity.Error, message, exception, paramList);
+ }
+
+ private void LogException(LogSeverity level, string message, Exception exception, params object[] paramList)
+ {
+ message = FormatMessage(message, paramList).Replace(Environment.NewLine, ". ");
+
+ var messageText = LogHelper.GetLogMessage(exception);
+
+ var prefix = _logManager.ExceptionMessagePrefix;
+
+ if (!string.IsNullOrWhiteSpace(prefix))
+ {
+ messageText.Insert(0, prefix);
+ }
+
+ LogMultiline(message, level, messageText);
+ }
+
+ private static string FormatMessage(string message, params object[] paramList)
+ {
+ if (paramList != null)
+ {
+ for (var i = 0; i < paramList.Length; i++)
+ {
+ var obj = paramList[i];
+
+ message = message.Replace("{" + i + "}", (obj == null ? "null" : obj.ToString()));
+ }
+ }
+
+ return message;
+ }
+
+ public void LogMultiline(string message, LogSeverity severity, StringBuilder additionalContent)
+ {
+ if (severity == LogSeverity.Debug && _logManager.LogSeverity == LogSeverity.Info)
+ {
+ return;
+ }
+
+ additionalContent.Insert(0, message + Environment.NewLine);
+
+ const char tabChar = '\t';
+
+ var text = additionalContent.ToString()
+ .Replace(Environment.NewLine, Environment.NewLine + tabChar)
+ .TrimEnd(tabChar);
+
+ if (text.EndsWith(Environment.NewLine))
+ {
+ text = text.Substring(0, text.LastIndexOf(Environment.NewLine, StringComparison.OrdinalIgnoreCase));
+ }
+
+ Log(severity, text);
+ }
+
+ public void Log(LogSeverity severity, string message, params object[] paramList)
+ {
+ message = severity + " " + Name + ": " + FormatMessage(message, paramList);
+
+ _logManager.Log(message);
+ }
+ }
+}