logger.anubis 9.19 KB

   
 *Project*                             The Anubis Project
   
 *Title*                               Message logger
   
 *Copyright*                     Copyright (c) David René 2006. 
 
 *Created: 2006 03 21  
 *Authors*  David René
            Cédric Ricard
            
 *Overview* 
   
   This file  contain some helper  functions for logging  informations on the  console and
   file. logger is based on the almost same behaviour as well know syslog on unix system.
 

read tools/streams.anubis
read tools/basis.anubis
read system/string.anubis
read system/lists.anubis

public type LogLevel:
	logNone,
	logCriticalError,
	logError,
	logWarning,
	logInfo,
	logDebug,
	logTrace.

public type LogMask:
	logMask(String mask).
	
public define Int32
	get_log_level_value
	(
		LogLevel level
	) =
	if level is
	{
		logNone						then 0,
		logCriticalError	then 1,
		logError					then 2,
		logWarning				then 3,
		logInfo						then 4,
		logDebug					then 5,
		logTrace					then 6,
	}.

public define LogLevel
	get_LogLevel_from_value
	(
		Int32 value
	) =
	if value = 0 then 
		logNone
	else if value = 1 then
		logCriticalError
	else if value = 2 then
		logError
	else if value = 3 then
		logWarning
	else if value = 4 then
		logInfo
	else if value = 5 then
		logDebug
	else if value = 6 then
		logTrace
	else 
		logTrace.

define String
	get_log_level_char
	(
		LogLevel level
	) =
	if level is
	{
		logNone						then "N",
		logCriticalError	then "C",
		logError					then "E",
		logWarning				then "W",
		logInfo						then "I",
		logDebug					then "D",
		logTrace					then "T",
	}.

// This type is made private because its content may change with versions
type PrivateLogger:
    _logger(String            loggerName,
            Int32             formatting_size,
    				String            fileName,
            Var(LogLevel)     fileLevel,
            Var(LogLevel)     consoleLevel,
            Var(List(String)) traceMasks,
            Var(Bool)         displayName,
            Var(Bool)         colorConsole).

public type Logger:
	logger(PrivateLogger pl).
	
public define String logGetName( Logger al ) = 
  al.pl.loggerName.

public define One logSetConsoleLevel( Logger al, LogLevel level) =
  consoleLevel(al.pl) <- level .

public define LogLevel logGetConsoleLevel( Logger al ) =
  *consoleLevel(al.pl).

public define One logSetFileLevel( Logger al,  LogLevel level) =
  fileLevel(al.pl) <- level .

public define LogLevel logSetFileLevel( Logger al ) =
  *fileLevel(al.pl).

public define One logAddTraceMask(Logger al, String mask) =
	al.pl.traceMasks <- append_once(*al.pl.traceMasks, mask).
	
public define One logSetTraceMask(Logger al, List(String) masks) =
	al.pl.traceMasks <- masks.
	
public define List(String) logGetTraceMask(Logger al) =
	*al.pl.traceMasks.
	
public define One logClearTraceMask(Logger al) =
	al.pl.traceMasks <- [].
	
public define One logSetColoring( Logger al,  Bool activate ) =
  colorConsole(al.pl) <- activate.

public define Bool logGetColoring( Logger al ) =
  *colorConsole(al.pl).

/**
 * Old and deprecated methode creating an unnamed logger.
 */
public define Logger createLogger(String fileName) =
 	logger(_logger("Unnamed", 7, fileName, var(logInfo), var(logInfo), var([]), var(false), var(true))).

/**
 * nullLoger is useful when we can't create log file and we must give a logger to a function
 */
public define Logger nullLogger = logger(_logger("", 7, "", var(logInfo), var(logInfo), var([]), var(false), var(true))).

/**
 * Creates a new named logger.
 */
public define Logger createLogger(String name, String fileName) =
	logger(_logger(name, length(name),fileName,  var(logInfo), var(logInfo), var([]), var(true), var(true))).

public define Logger createLogger(String name, Int32 size, String fileName, LogLevel fileLevel, LogLevel consoleLevel) =
	logger(_logger(name, size, fileName, var(fileLevel), var(consoleLevel), var([]), var(true), var(true))).
 
define One logFileError( Logger al, String logStr, LogLevel lvl).
define One logConsoleError( Logger al, String logStr, LogLevel lvl).

public define One logCriticalError( Logger al, String logStr )=
  logFileError(al, logStr, logCriticalError);
  logConsoleError(al, logStr, logCriticalError).

public define One logError( Logger al, String logStr )=
  logFileError(al, logStr, logError);
  logConsoleError(al, logStr, logError).

public define One logWarning( Logger al, String logStr )=
  logFileError(al, logStr, logWarning);
  logConsoleError(al, logStr, logWarning).

public define One logInfo( Logger al, String logStr )=
  logFileError(al, logStr, logInfo);
  logConsoleError(al, logStr, logInfo).

public define One logDebug( Logger al, String logStr )=
  logFileError(al, logStr, logDebug);
  logConsoleError(al, logStr, logDebug).

public define One logTrace( Logger al, LogMask m, String logStr )=
	if contains(*al.pl.traceMasks, m.mask) then
	  logFileError(al, logStr, logTrace);
	  logConsoleError(al, logStr, logTrace)
	else unique.

public define Maybe(Logger)
  get_logger
  (
    List(Logger)  loggers,
    String        name
  )=
  if loggers is
  {
    []      then failure,
    [h .t]  then
      if h.pl.loggerName = name then
        success(h)
      else
        get_logger(t, name)
  }.
  
// ----------------- private implementation ----------------------

define String get_color_tag(LogLevel level) =
	if level is
	{
		logNone						then implode([27]) + "[0m",
		logCriticalError	then implode([27]) + "[4;41;30m",
		logError					then implode([27]) + "[1;31m",
		logWarning				then implode([27]) + "[1;33m",
		logInfo						then implode([27]) + "[1;37m",
		logDebug					then implode([27]) + "[37m",
		logTrace					then implode([27]) + "[1;30m",
	}.
         
define One doLogFileError( Logger al, LogLevel level, String msg) =
  if length (al.pl.fileName) > 0 then
    if (Maybe(RWStream))file(al.pl.fileName, append) is
    {
      failure then unique, //nothing to write 
      success(st) then
        with currentTime = (UTime)now,
        		 lvlStr = get_log_level_char(level),
        if currentTime is utime(sec,micro) then
          if convert_time(sec) is date_and_time(y, month, d, h, min, s, _, _, _) then 
            with finalStr = "[" +integer_to_string(y) +
                      zero_pad_n(2, month) +
                      zero_pad_n(2, d) + "-" +
                      zero_pad_n(2, h) + ":" +
                      zero_pad_n(2, min) + ":" +
                      zero_pad_n(2, s) + "." +
                      zero_pad_n(3,micro/1000) + "|" + lvlStr + "][" + integer_to_string(virtual_machine_id) + "] " +
                      msg + "\n",
      forget(reliable_write(st, to_byte_array(finalStr)))
    }
  else 
    unique.

define One doLogConsoleError( Logger al, LogLevel level, String msg) =
  with currentTime = (UTime)now,
			 lvlStr = get_log_level_char(level),
			 color = if *al.pl.colorConsole then get_color_tag(level) else "",
			 colorEnd = if *al.pl.colorConsole then get_color_tag(logNone) else "",
			 prefix = if *al.pl.displayName then fill_or_cut((al.pl.loggerName), al.pl.formatting_size, ' ') + ": " else "",
  if currentTime is utime(sec,micro) then
    if convert_time(sec) is date_and_time(y, month, d, h, min, s, _, _, _) then
      print( color + prefix + "[" +integer_to_string(y) +
                      zero_pad_n(2, month) +
                      zero_pad_n(2, d) + "-" +
                      zero_pad_n(2, h) + ":" +
                      zero_pad_n(2, min) + ":" +
                      zero_pad_n(2, s) + "." +
                      zero_pad_n(3, micro/1000) + "|" + lvlStr + "][" + integer_to_string(virtual_machine_id) + "] " +
                      msg + colorEnd + "\n").

   

define One logFileError( Logger al, String logStr, LogLevel lvl)=
  if get_log_level_value(lvl) =< get_log_level_value(*al.pl.fileLevel) then
    doLogFileError(al, lvl, logStr)
  else
    unique.

define One logConsoleError( Logger al, String logStr, LogLevel lvl)=
  if get_log_level_value(lvl) =< get_log_level_value(*al.pl.consoleLevel) then 
    doLogConsoleError(al, lvl, logStr)
  else
    unique.



// --------------- UNIT TEST -----------------

define One otherThreadFunction
	(
		Logger log
	)
	=
	logInfo(log, "Log successfully created.");
	logCriticalError(log, "This is a critical error.");
	logError(log, "This is a fake error.");
	logWarning(log, "The test will exit soon...");
	logInfo(log, "This is the end.");
	logDebug(log, "Simple debug infos.");
	logTrace(log, logMask("NotDisplayed"), "This trace shouldn't be displayed.");
	logTrace(log, logMask("Displayed"), "This trace should be displayed.").
		
	
global define One
	test_logger(List(String) args)
	= 
	//print(implode([27]) + "[12C");
	//print(implode([27]) + "[12C");
	//print(implode([27]) + "[12C");
	with log = createLogger("MyLog", "./logger_test_file.log"),
	logAddTraceMask(log, "Displayed");
	delegate otherThreadFunction(log), unique;
	logSetConsoleLevel(log, logTrace);
	logInfo(log, "Log successfully created.");
	logCriticalError(log, "This is a critical error.");
	logError(log, "This is a fake error.");
	logWarning(log, "The test will exit soon...");
	logInfo(log, "This is the end.");
	logDebug(log, "Simple debug infos.");
	logTrace(log, logMask("NotDisplayed"), "This trace shouldn't be displayed.");
	logTrace(log, logMask("Displayed"), "This trace should be displayed.");
	println("Normal text. Test end.").