# logger.py -- Put log messages somewhere.
# Gareth Rees, Ravenbrook Limited, 2000-10-16.
# $Id: //info.ravenbrook.com/project/p4dti/branch/2001-02-05/lycos-beta/code/replicator/logger.py#2 $
#
# Copyright 2000 Ravenbrook Limited.  This document is provided "as is",
# without any express or implied warranty. In no event will the authors
# be held liable for any damages arising from the use of this document.
# You may make and distribute copies and derivative works of this
# document provided that (1) you do not charge a fee for this document or
# for its distribution, and (2) you retain as they appear all copyright
# and licence notices and document history entries, and (3) you append
# descriptions of your modifications to the document history.

import string
import sys
import time
import types

class logger:
    # message(id, format, arguments).  Format log message and return the
    # message as a string.
    def message(self, id, format, arguments = ()):
        assert isinstance(id, types.StringType)
        assert isinstance(format, types.StringType)
        check_digit = self.check_digit(id)
        date = time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime(time.time()))
        if type(arguments) != types.TupleType:
            arguments = (arguments,)
        return (("%s\t%s%s\t" + format + "\n")
                % ((date, id, check_digit) + arguments))

    # Compute the check digit for the given message id.  Message ids look like
    # P-NC, where P is the project name, N is the id number and C is the check
    # digit, computed by this function.  See
    # <http://info.ravenbrook.com/mail/2000/10/16/10-50-49/0.txt> for the
    # design decision.
    def check_digit(self, id):
        assert isinstance(id, types.StringType)
        sum = 0
        i = 0
        try:
            while 1:
                i = i - 1
                j = string.index(string.digits, id[i])
                sum = sum - i * j
        except (ValueError, IndexError):
            return "0123456789X"[sum % 11]
    
    # log(id, format, arguments, priority).  Log the message.

class file_logger(logger):
    file = None
    def __init__(self, file = sys.stdout):
        self.file = file
    def log(self, id, format, arguments = (), priority = None):
        self.file.write(self.message(id, format, arguments))
        self.file.flush()

class multi_logger(logger):
    loggers = []
    def __init__(self, loggers = []):
        self.loggers = loggers
    def log(self, id, format, arguments = (), priority = None):
        for l in self.loggers:
            l.log(id, format, arguments, priority)

# B. Document History
# 
# 2000-10-16 GDR Created.
# 
# 2000-11-30 GDR Added some type checking.
