aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Logging/LogManager.cs
blob: ba73b32b416afda531f1ee592fcd515feb7785e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<UserControl x:Class="Tango.SharedUI.Controls.HiveControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Tango.SharedUI.Controls"
             mc:Ignorable="d" 
             >
    <Grid x:Name="grid">
        <Canvas x:Name="canvas">

        </Canvas>
    </Grid>
</UserControl>
ref='#n219'>219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Tango.Logging
{
    /// <summary>
    /// Represents a helper class for logging information and errors.
    /// </summary>
    public class LogManager
    {
        private List<ILogger> _loggers;
        private ProducerConsumerQueue<LogItemBase> _logs;
        private Thread _loggingThread;
        private bool _isStarted;

        /// <summary>
        /// Occurs when a new log as been received.
        /// </summary>
        public event EventHandler<LogItemBase> NewLog;

        /// <summary>
        /// Gets the registered loggers.
        /// </summary>
        public List<ILogger> RegisteredLoggers
        {
            get { return _loggers.ToList(); }
        }

        private static LogManager _default;
        /// <summary>
        /// Gets the default log manager instance.
        /// </summary>
        public static LogManager Default
        {
            get
            {
                if (_default == null)
                {
                    _default = new LogManager();
                }

                return _default;
            }
        }

        /// <summary>
        /// Initializes the <see cref="LogManager"/> class.
        /// </summary>
        public LogManager()
        {
            _loggers = new List<ILogger>();
            _logs = new ProducerConsumerQueue<LogItemBase>();
            Categories = new List<LogCategory>();

            Categories.Add(LogCategory.Critical);
            Categories.Add(LogCategory.Error);
            Categories.Add(LogCategory.Info);
            Categories.Add(LogCategory.Warning);
        }

        /// <summary>
        /// Gets or sets the logging categories filter.
        /// </summary>
        public List<LogCategory> Categories { get; private set; }

        /// <summary>
        /// Registers a logger.
        /// </summary>
        /// <param name="logger">The logger.</param>
        public void RegisterLogger(ILogger logger)
        {
            if (logger != null && !_loggers.Contains(logger))
            {
                _loggers.Add(logger);
            }
        }

        /// <summary>
        /// Unregisters a logger.
        /// </summary>
        /// <param name="logger">The logger.</param>
        public void UnregisterLogger(ILogger logger)
        {
            if (logger != null && _loggers.Contains(logger))
            {
                _loggers.Remove(logger);
            }
        }

        /// <summary>
        /// Add new exception log item.
        /// </summary>
        /// <param name="e">Exception.</param>
        /// <param name="description">Error description.</param>
        public Exception Log(Exception e, String description = null, [CallerMemberName] string caller = null, [CallerFilePath] string file = null, [CallerLineNumber] int lineNumber = 0)
        {
            return Log(e, LogCategory.Error, description, caller, file, lineNumber);
        }

        /// <summary>
        /// Add new exception log item.
        /// </summary>
        /// <param name="e">Exception.</param>
        /// <param name="description">Error description.</param>
        public Exception Log(Exception e, LogCategory category, String description = null, [CallerMemberName] string caller = null, [CallerFilePath] string file = null, [CallerLineNumber] int lineNumber = 0)
        {
            if (!Categories.Contains(category)) return e;

            ExceptionLogItem log = new ExceptionLogItem();
            log.CallerMethodName = caller;
            log.CallerFile = file;
            log.CallerLineNumber = lineNumber;
            log.TimeStamp = DateTime.Now;
            log.Exception = e;
            log.Category = category;
            log.Description = description;
            log.Message = log.Description + Environment.NewLine + log.Exception.FlattenException();

            AppendLog(log);

            return e;
        }

        /// <summary>
        /// Add new message log item.
        /// </summary>
        /// <param name="message">Message.</param>
        public String Log(String message, [CallerMemberName] string caller = null, [CallerFilePath] string file = null, [CallerLineNumber] int lineNumber = 0)
        {
            return Log(message, LogCategory.Info, null, caller, file, lineNumber);
        }

        /// <summary>
        /// Add new message log item.
        /// </summary>
        /// <param name="message">Message.</param>
        public String Log(String message, LogCategory category, [CallerMemberName] string caller = null, [CallerFilePath] string file = null, [CallerLineNumber] int lineNumber = 0)
        {
            return Log(message, category, null, caller, file, lineNumber);
        }

        /// <summary>
        /// Add new message log item.
        /// </summary>
        /// <param name="message">Message.</param>
        public String Log(String message, LogCategory category, Object logObject, [CallerMemberName] string caller = null, [CallerFilePath] string file = null, [CallerLineNumber] int lineNumber = 0)
        {
            if (!Categories.Contains(category)) return message;

            MessageLogItem log = new MessageLogItem();
            log.CallerMethodName = caller;
            log.CallerFile = file;
            log.CallerLineNumber = lineNumber;
            log.TimeStamp = DateTime.Now;
            log.Category = category;
            log.Message = message;
            log.LogObject = logObject;

            AppendLog(log);

            return message;
        }

        /// <summary>
        /// Appends the specified log item.
        /// </summary>
        /// <param name="logItem">The log item.</param>
        public void Log(LogItemBase logItem)
        {
            AppendLog(logItem);
        }

        /// <summary>
        /// Logs the current referenced assemblies in the app domain.
        /// </summary>
        public void LogReferencedAssemblies()
        {
            String log = "--------------------- Referenced Assemblies --------------------------" + Environment.NewLine + Environment.NewLine;

            try
            {
                string codeBase = typeof(LogManager).Assembly.CodeBase;
                UriBuilder uri = new UriBuilder(codeBase);
                string path = Uri.UnescapeDataString(uri.Path);
                String folder = Path.GetDirectoryName(path);

                foreach (var file in Directory.GetFiles(folder, "*.dll"))
                {
                    FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(file);
                    string version = fvi.ProductVersion;
                    log += Path.GetFileNameWithoutExtension(file) + ", v" + version + Environment.NewLine;
                }

                log += Environment.NewLine + "--------------------- --------------------- --------------------------";

            }
            catch { }
            Log(log);
        }

        /// <summary>
        /// Add new message log item.
        /// </summary>
        /// <param name="message">Message.</param>
        public void Log(MessageLogItem log)
        {
            log.TimeStamp = DateTime.Now;
            AppendLog(log);
        }

        /// <summary>
        /// Appends the log.
        /// </summary>
        /// <param name="log">The log.</param>
        private void AppendLog(LogItemBase log)
        {
            _logs.BlockEnqueue(log);
            StartLoggingThread();
        }

        /// <summary>
        /// Starts the logging thread.
        /// </summary>
        private void StartLoggingThread()
        {
            if (!_isStarted)
            {
                _isStarted = true;
                _loggingThread = new Thread(LoggingThreadMethod);
                _loggingThread.IsBackground = true;
                _loggingThread.Start();
            }
        }

        /// <summary>
        /// Loggings thread method.
        /// </summary>
        //[DebuggerStepThrough]
        //[DebuggerHidden]
        private void LoggingThreadMethod()
        {
            while (_isStarted)
            {
                LogItemBase log = _logs.BlockDequeue();

                _loggers.Where(x => x.Enabled).ToList().ForEach(x => x.OnLog(log));
                NewLog?.Invoke(this, log);
            }
        }

        /// <summary>
        /// Creates a new log safe which can be used to keep logs and then be disposed.
        /// </summary>
        /// <returns></returns>
        public LogSafe CreateLogSafe()
        {
            return new LogSafe(this);
        }
    }
}