view Implab/Diagnostics/LogContext.cs @ 35:2880242f987a diagnostics

initial log capabilities
author cin
date Mon, 14 Apr 2014 18:25:26 +0400
parents
children
line wrap: on
line source

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Implab.Diagnostics {
    public class LogContext {
        LogicalOperation m_currentOperation;
        readonly LogicalOperation m_traceBound;
        readonly int m_threadId;
        readonly LogContext m_parent;

        readonly static object _consoleLock = new object();

        [ThreadStatic]
        static LogContext _current;

        public static LogContext Current {
            get {
                if (_current == null)
                    _current = new LogContext();
                return _current;
            }
        }

        LogContext(LogContext context) {
            if (context == null)
                throw new ArgumentNullException("context");

            m_parent = context;
            m_currentOperation = context.CurrentOperation;
            m_traceBound = context.CurrentOperation;
            m_threadId = Thread.CurrentThread.ManagedThreadId;

            TraceEvent(TraceEventType.Transfer, String.Empty);
        }

        LogContext() {
            m_currentOperation = new LogicalOperation();
            m_traceBound = m_currentOperation;
            m_threadId = Thread.CurrentThread.ManagedThreadId;
        }

        public static void Transfer(LogContext from) {
            _current = from == null ? new LogContext() : new LogContext(from);
        }

        public LogContext ParentContext {
            get {
                return m_parent;
            }
        }

        public LogicalOperation CurrentOperation {
            get {
                return m_currentOperation;
            }
        }

        public LogicalOperation TraceBound {
            get {
                return m_traceBound;
            }
        }

        public int ThreadId {
            get {
                return m_threadId;
            }
        }

        public void StartLogicalOperation() {
            StartLogicalOperation(null);
        }

        public void StartLogicalOperation(string name) {
            TraceEvent(TraceEventType.OperationStarted, "{0}", name);
            m_currentOperation = new LogicalOperation(name, m_currentOperation);
        }

        public void EndLogicalOperation() {
            if (m_traceBound == m_currentOperation) {
                TraceEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace");
            } else {
                var op = m_currentOperation;
                m_currentOperation = m_currentOperation.Parent;
                TraceEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration);
            }
        }

        public void TraceEvent(TraceEventType type, string format, params object[] args) {
            /*var msg = new StringBuilder();
            for (int i = 0; i < CurrentOperation.Level; i++)
                msg.Append("  ");
            msg.Append(type);
            msg.AppendFormat("[{0}]: ",m_threadId);
            msg.AppendFormat(format, args);

            lock (_consoleLock) {
                Console.ForegroundColor = (ConsoleColor)(m_threadId % 15 + 1);
                Console.WriteLine(msg.ToString());
            }*/
        }
    }
}