logo logo
Home
Monday, 12 May 2008
 
 
English English  Español Español  
Tag Cloud
Architectures Artificial Associations Books Brain Conscious Consciousness Forums Howto Machine Machines Microsoft Neuroscience Projects Publications Research Researchers Reviews Robot Robotics Robots Services Spanish Studio
ConcurrentLogger Beta 1 Source Code Print E-mail
Written by Raúl Arrabales Moreno   
Friday, 25 May 2007
//
// CRANIUM.ConcurrentLogger - Concurrent Logger
// (c) 2007 Raúl Arrabales Moreno  
//
 
 
using System;
using System.Collections.Generic;
using System.Text;
 
// CCR Library
using Microsoft.Ccr.Core;
using Microsoft.Ccr.Core.Arbiters;
 
// Concurrent Logger is part of CRANIUM
namespace Cranium
{
 
    /// <summary>
    /// The Concurrent Logger LogLevel static class. Defines log levels.
    /// </summary>
    public static class LogLevel
    {
        // Predefined Log Levels
        /// <summary>
        /// <value>DEBUG Level is the highest level of log. ALL Messages are logged.</value>
        /// </summary>
        public const int DEBUG = 1;
 
        /// <summary>
        /// INFO Level is a highest level of log, i.e. Verbose. All messages except thise classified as DEBUG and INFO are logged.
        /// </summary>
        public const int INFO = 10;
 
        /// <summary>
        /// WARN Level is a medium level of log. All messages clasified as WARN, ERROR, and FATAL are logged.
        /// </summary>
        public const int WARN = 20;
 
        /// <summary>
        /// ERROR Level is a lower level of log. Only ERROR and FATAL messages are logged.
        /// </summary>
        public const int ERROR = 30;
 
        /// <summary>
        /// FATAL Level is the lower level of log. Only FATAL messages are logged.
        /// </summary>
        public const int FATAL = 40;
 
 
        /// <summary>
        /// Convert the int log level into a string. 
        /// </summary>
        /// <param name="level">Integer log level.</param>
        /// <returns>The corresponding string describing the log level, e.g. INFO.</returns>
        public static string getString(int level)
        {
            switch (level)
            {
                case LogLevel.DEBUG: { return "DEBUG"; break; }
                case LogLevel.INFO: { return "INFO"; break; }
                case LogLevel.WARN: { return "WARN"; break; }
                case LogLevel.ERROR: { return "ERROR"; break; }
                case LogLevel.FATAL: { return "FATAL"; break; }
            }
            return "undefined";
        }
    } 
 
 
 
    /// <summary>
    /// ConcurrentLogger Class. Provides Logging to a file facility.
    /// </summary>
    public class ConcurrentLogger
    {
        // CCR Dispatcher and Queue
        Dispatcher dispatcher;
        DispatcherQueue dq;
 
        // A string port where log messages are received.
        Port<String> stringPort;
 
        // Current log level
        int currentLevel;
 
        // Log File
        System.IO.StreamWriter streamWriter;
        String logFileName;
 
 
        /// <summary>
        /// Initialize the Concurrent Logger. 
        /// </summary>
        /// <param name="level">Log Level.</param>
        /// <param name="fileName">Name of the log file.</param>
        private void initConcurrentLogger(int level, string fileName)
        {
            currentLevel = level;
            logFileName = fileName;
 
            // Create the CCR Dispatcher (thread pool)
            dispatcher = new Dispatcher(0, "ConcurrentLogger Threads");
            
            // Create a dispatcher queue that queues work item tasks to the dispatcher
            dq = new DispatcherQueue("ConcurrentLogger DispatcherQueue", dispatcher);
 
            // Open the file
            streamWriter = new System.IO.StreamWriter(logFileName, true);
            streamWriter.AutoFlush = true;            
 
            // String Port: FIFO Queue to string objects.
            stringPort = new Port<string>();
 
            // Simply Receive log requests - persistent Receive           
            //Arbiter.Activate(dq, Arbiter.Receive(true, stringPort,
            //   delegate(String s) { streamWriter.WriteLine(s); }));
 
            // Receive log request, controlling errors and exclusive access
            Arbiter.Activate( dq, Arbiter.Interleave( 
                
                // Failure
                new TeardownReceiverGroup(),
 
                // ExclusiveExecution for Thread Safety
                new ExclusiveReceiverGroup(
                    Arbiter.Receive(true, stringPort, delegate(String s) {streamWriter.WriteLine(s);})),
 
                // Process concurrently as requests come in
                new ConcurrentReceiverGroup()
                )
             );
            
 
 
            // Write a header per each execution.
            stringPort.Post(" ");
            stringPort.Post("*** " + DateTime.Now.ToString() + 
                " - CRANIUM LOGGER INITIATED - Level: " + LogLevel.getString(currentLevel) + " ***");
            stringPort.Post(" ");
        }
 
        
 
        /// <summary>
        /// Default ConcurrentLogger Constructor. Assumes DEBUG level and cranium.log as the log file name. 
        /// </summary>        
        public ConcurrentLogger()
        {
            initConcurrentLogger(LogLevel.DEBUG, "cranium.log");            
        }
 
        /// <summary>
        /// ConcurrentLogger Constructor. Specifies log level. Assumes cranium.log as the log file name. 
        /// </summary>
        /// <param name="level">Log Level</param>        
        public ConcurrentLogger(int level)
        {
            initConcurrentLogger(level, "cranium.log");
        }
 
        /// <summary>
        /// ConcurrentLogger Constructor. Specifies name of the log file and log level.
        /// </summary>
        /// <param name="fileName">The name of the log file to write.</param>
        /// <param name="level">Log level</param>        
        public ConcurrentLogger(String fileName, int level)
        {
            initConcurrentLogger(level, fileName); 
        }
 
        /// <summary>
        /// Shutdown the Concurrent Logger. Disposes the thread dispatcher and closes the file.
        /// </summary>
        public void shutdown()
        {
            streamWriter.Close();
            dispatcher.Dispose();
        }
 
        /// <summary>
        /// Writes a log line in the log file.
        /// </summary>
        /// <param name="component">Name of the component that writes the log.</param>
        /// <param name="level">Log Level.</param>
        /// <param name="msg">Log Message.</param>
        public void writeLog(String component, int level, String msg)
        {            
            if (currentLevel <= level)
            {
                stringPort.Post(
                    DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString() + 
                    " [" + component + "] [" + LogLevel.getString(level) + "] " + msg);            
            }
        }
 
    }
}
 

Last Updated ( Friday, 25 May 2007 )
 
 
Top! Top!