PageRenderTime 37ms CodeModel.GetById 21ms app.highlight 13ms RepoModel.GetById 0ms app.codeStats 1ms

/source/D3Sharp/Utils/TinyLogger.cs

https://github.com/darkschasu/d3sharp
C# | 273 lines | 193 code | 49 blank | 31 comment | 15 complexity | 7aac4339231336dc2758f8cf2af472cf MD5 | raw file
  1/*
  2 * Copyright (C) 2011 D3Sharp Project
  3 *
  4 * This program is free software; you can redistribute it and/or modify
  5 * it under the terms of the GNU General Public License as published by
  6 * the Free Software Foundation; either version 2 of the License, or
  7 * (at your option) any later version.
  8 *
  9 * This program is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 * GNU General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU General Public License
 15 * along with this program; if not, write to the Free Software
 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 17 */
 18
 19using System;
 20using System.Collections.Generic;
 21using System.Diagnostics;
 22using System.Globalization;
 23using System.IO;
 24using System.Linq;
 25
 26namespace D3Sharp.Utils
 27{
 28    public enum Level
 29    {
 30        Trace,
 31        Debug,
 32        Info,
 33        Warn,
 34        Error,
 35        Fatal,
 36        Incoming,
 37        Outgoing,
 38    }
 39
 40    public static class LogManager
 41    {
 42        public static bool Enabled { get; set; }
 43
 44        internal readonly static List<Target> Targets = new List<Target>();
 45        internal static readonly Dictionary<string, Logger> Loggers = new Dictionary<string, Logger>();
 46
 47        public static void AttachLogTarget(Target target)
 48        {
 49            Targets.Add(target);
 50        }
 51
 52        public static Logger CreateLogger()
 53        {
 54            var frame = new StackFrame(1, false);
 55            var name = frame.GetMethod().DeclaringType.Name;
 56            if (name == null) throw new Exception("Error getting full name for declaring type.");
 57            if (!Loggers.ContainsKey(name)) Loggers.Add(name, new Logger(name));
 58            return Loggers[name];
 59        }
 60
 61        public static Logger CreateLogger(string name)
 62        {
 63            if (!Loggers.ContainsKey(name)) Loggers.Add(name, new Logger(name));
 64            return Loggers[name];
 65        }
 66    }
 67
 68    internal static class LogRouter
 69    {
 70        public static void RouteMessage(Level level, string logger, string message)
 71        {
 72            if (!LogManager.Enabled) return;
 73            if (LogManager.Targets.Count == 0) return;
 74
 75            foreach (var target in LogManager.Targets.Where(target => level >= target.MinimumLevel))
 76            {
 77                target.LogMessage(level, logger, message);
 78            }
 79        }
 80
 81        public static void RouteException(Level level, string logger, string message, Exception exception)
 82        {
 83            if (!LogManager.Enabled) return;
 84            if (LogManager.Targets.Count == 0) return;
 85
 86            foreach (var target in LogManager.Targets.Where(target => level >= target.MinimumLevel))
 87            {
 88                target.LogException(level, logger, message, exception);
 89            }
 90        }
 91    }
 92
 93    public class Logger
 94    {
 95        public string Name { get; protected set; }
 96
 97        public Logger(string name)
 98        {
 99            Name = name;
100        }
101
102        private void Log(Level level, string message, object[] args)
103        {
104            LogRouter.RouteMessage(level, this.Name, args == null ? message : string.Format(CultureInfo.InvariantCulture, message, args));
105        }
106
107        private void LogException(Level level, string message, object[] args, Exception exception)
108        {
109            LogRouter.RouteException(level, this.Name, args == null ? message : string.Format(CultureInfo.InvariantCulture, message, args), exception);
110        }
111
112        public void Trace(string message) { Log(Level.Trace, message, null); }
113        public void Trace(string message, params object[] args) { Log(Level.Trace, message, args); }
114
115        public void Debug(string message) { Log(Level.Debug, message, null); }
116        public void Debug(string message, params object[] args) { Log(Level.Debug, message, args); }
117
118        public void Info(string message) { Log(Level.Info, message, null); }
119        public void Info(string message, params object[] args) { Log(Level.Info, message, args); }
120
121        public void Warn(string message) { Log(Level.Warn, message, null); }
122        public void Warn(string message, params object[] args) { Log(Level.Warn, message, args); }
123
124        public void Error(string message) { Log(Level.Error, message, null); }
125        public void Error(string message, params object[] args) { Log(Level.Error, message, args); }
126
127        public void Fatal(string message) { Log(Level.Fatal, message, null); }
128        public void Fatal(string message, params object[] args) { Log(Level.Fatal, message, args); }
129
130        public void TraceException(Exception exception, string message) { LogException(Level.Trace, message, null, exception); }
131        public void TraceException(Exception exception, string message, params object[] args) { LogException(Level.Trace, message, args, exception); }
132
133        public void DebugException(Exception exception, string message) { LogException(Level.Debug, message, null, exception); }
134        public void DebugException(Exception exception, string message, params object[] args) { LogException(Level.Debug, message, args, exception); }
135
136        public void InfoException(Exception exception, string message) { LogException(Level.Info, message, null, exception); }
137        public void InfoException(Exception exception, string message, params object[] args) { LogException(Level.Info, message, args, exception); }
138
139        public void WarnException(Exception exception, string message) { LogException(Level.Warn, message, null, exception); }
140        public void WarnException(Exception exception, string message, params object[] args) { LogException(Level.Warn, message, args, exception); }
141
142        public void ErrorException(Exception exception, string message) { LogException(Level.Error, message, null, exception); }
143        public void ErrorException(Exception exception, string message, params object[] args) { LogException(Level.Error, message, args, exception); }
144
145        public void FatalException(Exception exception, string message) { LogException(Level.Fatal, message, null, exception); }
146        public void FatalException(Exception exception, string message, params object[] args) { LogException(Level.Fatal, message, args, exception); }
147
148        public void LogIncoming(Google.ProtocolBuffers.IMessage msg) { Log(Level.Incoming, msg.AsText(), null); }
149        public void LogOutgoing(Google.ProtocolBuffers.IMessage msg) { Log(Level.Outgoing, msg.AsText(), null); }
150        public void LogIncoming(D3Sharp.Net.Game.Packets.GameMessage msg) { Log(Level.Incoming, msg.AsText(), null); }
151        public void LogOutgoing(D3Sharp.Net.Game.Packets.GameMessage msg) { Log(Level.Outgoing, msg.AsText(), null); }
152    }
153
154    public class Target
155    {
156        public Level MinimumLevel { get; protected set; }
157        public virtual void LogMessage(Level level, string logger, string message) { throw new NotSupportedException(); }
158        public virtual void LogException(Level level, string logger, string message, Exception exception) { throw new NotSupportedException(); }
159    }
160
161    public class FileTarget : Target, IDisposable
162    {
163        private readonly string _filePath;
164
165        private FileStream _fileStream;
166        private StreamWriter _logStream;
167
168        public FileTarget(Level minLevel, string filePath)
169        {
170            MinimumLevel = minLevel;
171            _filePath = filePath;
172            this._fileStream = new FileStream(_filePath, FileMode.Append, FileAccess.Write);
173            this._logStream = new StreamWriter(this._fileStream);
174            this._logStream.AutoFlush = true;
175        }
176
177        public override void LogMessage(Level level, string logger, string message)
178        {
179            this._logStream.WriteLine(string.Format("[{0}] [{1}]: {2}", level.ToString().PadLeft(5), logger, message));
180        }
181
182        public override void LogException(Level level, string logger, string message, Exception exception)
183        {
184            this._logStream.WriteLine(string.Format("[{0}] [{1}]: {2} - [Exception] {3}", level.ToString().PadLeft(5), logger, message, exception));
185        }
186
187        #region de-ctor
188
189        // IDisposable pattern: http://msdn.microsoft.com/en-us/library/fs2xkftw%28VS.80%29.aspx
190
191        private bool _disposed = false;
192        public void Dispose()
193        {
194            Dispose(true);
195            GC.SuppressFinalize(this); // Take object out the finalization queue to prevent finalization code for it from executing a second time.
196        }
197
198        private void Dispose(bool disposing)
199        {
200            if (this._disposed) return; // if already disposed, just return
201
202            if (disposing) // only dispose managed resources if we're called from directly or in-directly from user code.
203            {
204                this._logStream.Close();
205                this._logStream.Dispose();
206                this._fileStream.Close();
207                this._fileStream.Dispose();
208            }
209
210            this._logStream = null;
211            this._fileStream = null;
212
213            _disposed = true;
214        }
215
216        ~FileTarget() { Dispose(false); } // finalizer called by the runtime. we should only dispose unmanaged objects and should NOT reference managed ones.
217
218        #endregion
219    }
220
221    public class ConsoleTarget : Target
222    {
223        // Win32 API constants.
224        private const int StdOutputHandle = -11;
225        private const int CodePage = 437;
226
227        public ConsoleTarget(Level minLevel, bool initConsole = false)
228        {
229            MinimumLevel = minLevel;
230            // if (initConsole) InitConsole(); TODO: Make sure only get compiled in win32
231        }
232
233        // TODO: Make sure only get compiled in win32
234        /*private static void InitConsole() // binds a new console window to a windowed application.
235        {
236            NativeMethods.AllocConsole(); // allocate a new console window.
237            var stdHandle = NativeMethods.GetStdHandle(StdOutputHandle); // the stdout handle.
238            var safeFileHandle = new Microsoft.Win32.SafeHandles.SafeFileHandle(stdHandle, true);
239            var fileStream = new FileStream(safeFileHandle, FileAccess.Write);
240            var encoding = Encoding.GetEncoding(CodePage);
241            var standardOutput = new StreamWriter(fileStream, encoding) { AutoFlush = true };
242            Console.SetOut(standardOutput); // set console's output stream to stdout.
243        }*/
244
245        public override void LogMessage(Level level, string logger, string message)
246        {
247            SetForeGroundColor(level);
248            Console.WriteLine(string.Format("[{0}] [{1}]: {2}", level.ToString().PadLeft(5), logger, message));
249        }
250
251        public override void LogException(Level level, string logger, string message, Exception exception)
252        {
253            SetForeGroundColor(level);
254            Console.WriteLine(string.Format("[{0}] [{1}]: {2} - [Exception] {3}", level.ToString().PadLeft(5), logger, message, exception));
255        }
256
257        private static void SetForeGroundColor(Level level)
258        {
259            switch (level)
260            {
261                case Level.Trace: Console.ForegroundColor = ConsoleColor.DarkGray; break;
262                case Level.Debug: Console.ForegroundColor = ConsoleColor.Gray; break;
263                case Level.Info: Console.ForegroundColor = ConsoleColor.White; break;
264                case Level.Warn: Console.ForegroundColor = ConsoleColor.Yellow; break;
265                case Level.Error: Console.ForegroundColor = ConsoleColor.Magenta; break;
266                case Level.Fatal: Console.ForegroundColor = ConsoleColor.Red; break;
267                case Level.Incoming:
268                case Level.Outgoing: Console.ForegroundColor = ConsoleColor.White; break;
269                default: break;
270            }
271        }
272    }
273}