- remove unused log4py, will use python logging instead
- use Settings for SOAPServer - create package GnuviechAdmin - move SOAPServer to package GnuviechAdmin git-svn-id: file:///home/www/usr01/svn/gnuviechadmin/gnuviech.info/gnuviechadmin/trunk@167 a67ec6bc-e5d5-0310-a910-815c51eb3124
This commit is contained in:
parent
b7e63e7984
commit
5d6938910c
25 changed files with 16 additions and 2122 deletions
|
@ -4,10 +4,11 @@
|
||||||
# (c) 2006 Jan Dittberner <jan@dittberner.info>
|
# (c) 2006 Jan Dittberner <jan@dittberner.info>
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
from SOAPpy import SOAPServer
|
import SOAPpy
|
||||||
import logging
|
import logging
|
||||||
|
from gvadm import Settings
|
||||||
|
|
||||||
class GnuviechAdminSOAPServer(SOAPServer):
|
class SOAPServer(SOAPpy.SOAPServer):
|
||||||
"""
|
"""
|
||||||
SOAP Server class for the gnuviech administration tool backend
|
SOAP Server class for the gnuviech administration tool backend
|
||||||
"""
|
"""
|
||||||
|
@ -23,7 +24,7 @@ class GnuviechAdminSOAPServer(SOAPServer):
|
||||||
This method creates the SOAPServer and registers the methods to be
|
This method creates the SOAPServer and registers the methods to be
|
||||||
available to connected SOAP clients.
|
available to connected SOAP clients.
|
||||||
"""
|
"""
|
||||||
SOAPServer.__init__(self, ("127.0.0.1", 8080))
|
SOAPpy.SOAPServer.__init__(self, Settings.soapaddress)
|
||||||
self.logger = logging.getLogger('GnuviechAdminSOAPServer')
|
self.logger = logging.getLogger('GnuviechAdminSOAPServer')
|
||||||
hdlr = logging.FileHandler('soapserver.log')
|
hdlr = logging.FileHandler('soapserver.log')
|
||||||
hdlr.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
|
hdlr.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
|
||||||
|
@ -41,5 +42,5 @@ class GnuviechAdminSOAPServer(SOAPServer):
|
||||||
self.serve_forever()
|
self.serve_forever()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
server = GnuviechAdminSOAPServer()
|
server = SOAPServer()
|
||||||
server.main()
|
server.main()
|
8
backend/GnuviechAdmin/__init__.py
Normal file
8
backend/GnuviechAdmin/__init__.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# (c) 2006 Jan Dittberner <jan@dittberner.info>
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
"""
|
||||||
|
This package contains classes for the gnuviech administration tool backend.
|
||||||
|
"""
|
|
@ -16,3 +16,6 @@ mailreceiver = 'root@gnuviech.info'
|
||||||
popgroup = 'poponly'
|
popgroup = 'poponly'
|
||||||
popgroup = 'poponly'
|
popgroup = 'poponly'
|
||||||
pophome = '/home/mail/'
|
pophome = '/home/mail/'
|
||||||
|
webhome = '/home/www/'
|
||||||
|
|
||||||
|
soapaddress = ('127.0.0.1', 8080);
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[Default]
|
|
||||||
Ansi: false
|
|
||||||
LogLevel: Normal
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
LogLevel: Debug
|
|
|
@ -1,593 +0,0 @@
|
||||||
"""
|
|
||||||
|
|
||||||
Python logging module - Version 1.3
|
|
||||||
|
|
||||||
Loglevels:
|
|
||||||
|
|
||||||
LOGLEVEL_NONE, LOGLEVEL_ERROR, LOGLEVEL_NORMAL, LOGLEVEL_VERBOSE, LOGLEVEL_DEBUG
|
|
||||||
|
|
||||||
Format-Parameters:
|
|
||||||
|
|
||||||
%C -- The name of the current class.
|
|
||||||
%D -- Program duration since program start.
|
|
||||||
%d -- Program duration for the last step (last output).
|
|
||||||
%F -- The name of the current function.
|
|
||||||
%f -- Current filename
|
|
||||||
%L -- Log type (Error, Warning, Debug or Info)
|
|
||||||
%M -- The actual message.
|
|
||||||
%N -- The current line number.
|
|
||||||
%T -- Current time (human readable).
|
|
||||||
%t -- Current time (machine readable)
|
|
||||||
%U -- Current fully qualified module/file.
|
|
||||||
%u -- Current module/file.
|
|
||||||
%x -- NDC (nested diagnostic contexts).
|
|
||||||
|
|
||||||
Pre-defined Formats:
|
|
||||||
|
|
||||||
FMT_SHORT -- %M
|
|
||||||
FMT_MEDIUM -- [ %C.%F ] %D: %M
|
|
||||||
FMT_LONG -- %T %L %C [%F] %x%M
|
|
||||||
FMT_DEBUG -- %T [%D (%d)] %L %C [%F (%N)] %x%M
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Logging levels
|
|
||||||
LOGLEVEL_NONE = 1 << 0
|
|
||||||
LOGLEVEL_ERROR = 1 << 1
|
|
||||||
LOGLEVEL_NORMAL = 1 << 2
|
|
||||||
LOGLEVEL_VERBOSE = 1 << 3
|
|
||||||
LOGLEVEL_DEBUG = 1 << 4
|
|
||||||
|
|
||||||
# Pre-defined format strings
|
|
||||||
FMT_SHORT = "%M"
|
|
||||||
FMT_MEDIUM = "[ %C.%F ] %D: %M"
|
|
||||||
FMT_LONG = "%T %L %C [%F] %x%M"
|
|
||||||
FMT_DEBUG = "%T [%D (%d)] %L %C [%F (%N)] %x%M"
|
|
||||||
|
|
||||||
# Special logging targets
|
|
||||||
TARGET_MYSQL = "MySQL"
|
|
||||||
TARGET_POSTGRES = "Postgres"
|
|
||||||
TARGET_SYSLOG = "Syslog"
|
|
||||||
TARGET_SYS_STDOUT = "sys.stdout"
|
|
||||||
TARGET_SYS_STDERR = "sys.stderr"
|
|
||||||
TARGET_SYS_STDOUT_ALIAS = "stdout"
|
|
||||||
TARGET_SYS_STDERR_ALIAS = "stderr"
|
|
||||||
|
|
||||||
SPECIAL_TARGETS = [ TARGET_MYSQL, TARGET_POSTGRES, TARGET_SYSLOG, TARGET_SYS_STDOUT, TARGET_SYS_STDERR, TARGET_SYS_STDOUT_ALIAS, TARGET_SYS_STDERR_ALIAS ]
|
|
||||||
|
|
||||||
# Configuration files
|
|
||||||
CONFIGURATION_FILES = {}
|
|
||||||
CONFIGURATION_FILES[1] = "log4py.conf" # local directory
|
|
||||||
CONFIGURATION_FILES[2] = "$HOME/.log4py.conf" # hidden file in the home directory
|
|
||||||
CONFIGURATION_FILES[3] = "/etc/log4py.conf" # system wide file
|
|
||||||
|
|
||||||
# Constants for the FileAppender
|
|
||||||
ROTATE_NONE = 0
|
|
||||||
ROTATE_DAILY = 1
|
|
||||||
ROTATE_WEEKLY = 2
|
|
||||||
ROTATE_MONTHLY = 3
|
|
||||||
|
|
||||||
# The following constants are of internal interest only
|
|
||||||
|
|
||||||
# Message constants (used for ansi colors and for logtype %L)
|
|
||||||
MSG_DEBUG = 1 << 0
|
|
||||||
MSG_WARN = 1 << 1
|
|
||||||
MSG_ERROR = 1 << 2
|
|
||||||
MSG_INFO = 1 << 3
|
|
||||||
|
|
||||||
# Boolean constants
|
|
||||||
TRUE = "TRUE"
|
|
||||||
FALSE = "FALSE"
|
|
||||||
|
|
||||||
# Color constants
|
|
||||||
BLACK = 30
|
|
||||||
RED = 31
|
|
||||||
GREEN = 32
|
|
||||||
YELLOW = 33
|
|
||||||
BLUE = 34
|
|
||||||
PURPLE = 35
|
|
||||||
AQUA = 36
|
|
||||||
WHITE = 37
|
|
||||||
|
|
||||||
LOG_MSG = { MSG_DEBUG: "DEBUG", MSG_WARN: "WARNING", MSG_ERROR: "ERROR", MSG_INFO: "INFO"}
|
|
||||||
LOG_COLORS = { MSG_DEBUG: [WHITE, BLACK, FALSE], MSG_WARN: [WHITE, BLACK, FALSE], MSG_ERROR: [WHITE, BLACK, TRUE], MSG_INFO: [WHITE, BLACK, FALSE]}
|
|
||||||
LOG_LEVELS = { "DEBUG": LOGLEVEL_DEBUG, "VERBOSE": LOGLEVEL_VERBOSE, "NORMAL": LOGLEVEL_NORMAL, "NONE": LOGLEVEL_NONE, "ERROR": LOGLEVEL_ERROR }
|
|
||||||
|
|
||||||
SECTION_DEFAULT = "Default"
|
|
||||||
|
|
||||||
from time import time, strftime, localtime
|
|
||||||
from types import StringType, ClassType, InstanceType, FileType, TupleType
|
|
||||||
from string import zfill, atoi, lower, upper, join, replace, split, strip
|
|
||||||
from re import sub
|
|
||||||
from ConfigParser import ConfigParser, NoOptionError
|
|
||||||
from os import stat, rename
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
import os
|
|
||||||
import copy
|
|
||||||
import socket
|
|
||||||
import locale
|
|
||||||
if (os.name == "posix"):
|
|
||||||
import syslog
|
|
||||||
|
|
||||||
try:
|
|
||||||
import MySQLdb
|
|
||||||
mysql_available = TRUE
|
|
||||||
except:
|
|
||||||
mysql_available = FALSE
|
|
||||||
|
|
||||||
def get_homedirectory():
|
|
||||||
if (sys.platform == "win32"):
|
|
||||||
if (os.environ.has_key("USERPROFILE")):
|
|
||||||
return os.environ["USERPROFILE"]
|
|
||||||
else:
|
|
||||||
return "C:\\"
|
|
||||||
else:
|
|
||||||
if (os.environ.has_key("HOME")):
|
|
||||||
return os.environ["HOME"]
|
|
||||||
else:
|
|
||||||
# No home directory set
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# This is the main class for the logging module
|
|
||||||
|
|
||||||
class Logger:
|
|
||||||
|
|
||||||
cache = {}
|
|
||||||
instance = None
|
|
||||||
configfiles = []
|
|
||||||
hostname = socket.gethostname()
|
|
||||||
|
|
||||||
def __init__(self, useconfigfiles = TRUE, customconfigfiles = None):
|
|
||||||
""" **(private)** Class initalization & customization. """
|
|
||||||
if (customconfigfiles):
|
|
||||||
if (type(customconfigfiles) == StringType):
|
|
||||||
customconfigfiles = [customconfigfiles]
|
|
||||||
Logger.configfiles = customconfigfiles
|
|
||||||
|
|
||||||
if (not Logger.instance):
|
|
||||||
self.__Logger_setdefaults()
|
|
||||||
if (useconfigfiles == TRUE):
|
|
||||||
self.__Logger_appendconfigfiles(Logger.configfiles)
|
|
||||||
# read the default options
|
|
||||||
self.__Logger_parse_options()
|
|
||||||
|
|
||||||
self.__Logger_timeinit = time()
|
|
||||||
self.__Logger_timelaststep = self.__Logger_timeinit
|
|
||||||
|
|
||||||
Logger.instance = self
|
|
||||||
|
|
||||||
if (useconfigfiles == TRUE):
|
|
||||||
# read and pre-cache settings for named classids
|
|
||||||
self.__Logger_cache_options()
|
|
||||||
|
|
||||||
def get_root(self):
|
|
||||||
""" Provides a way to change the base logger object's properties. """
|
|
||||||
return Logger.instance
|
|
||||||
|
|
||||||
def get_instance(self, classid = "Main", use_cache = TRUE):
|
|
||||||
""" Either get the cached logger instance or create a new one
|
|
||||||
|
|
||||||
Note that this is safe, even if you have your target set to sys.stdout
|
|
||||||
or sys.stderr
|
|
||||||
"""
|
|
||||||
|
|
||||||
cache = Logger.cache
|
|
||||||
|
|
||||||
if (type(classid) == ClassType):
|
|
||||||
classid = classid.__name__
|
|
||||||
elif (type(classid) == InstanceType):
|
|
||||||
classid = classid.__class__.__name__
|
|
||||||
|
|
||||||
# classid has to be lowercase, because the ConfigParser returns sections lowercase
|
|
||||||
classid = lower(classid)
|
|
||||||
|
|
||||||
if ((cache.has_key(classid)) and (use_cache == TRUE)):
|
|
||||||
cat = Logger.cache[classid]
|
|
||||||
else:
|
|
||||||
instance = Logger.instance
|
|
||||||
|
|
||||||
# test for targets which won't deep copy
|
|
||||||
targets = instance.__Logger_targets
|
|
||||||
deepcopyable = TRUE
|
|
||||||
for i in range(len(targets)):
|
|
||||||
if (type(targets[i]) == FileType):
|
|
||||||
deepcopyable = FALSE
|
|
||||||
if (deepcopyable == FALSE):
|
|
||||||
# swap the non-copyable target out for a moment
|
|
||||||
del instance.__Logger_targets
|
|
||||||
cat = copy.deepcopy(instance)
|
|
||||||
instance.__Logger_targets = targets
|
|
||||||
cat.__Logger_targets = targets
|
|
||||||
else:
|
|
||||||
cat = copy.deepcopy(instance)
|
|
||||||
|
|
||||||
cat.__Logger_classname = classid
|
|
||||||
# new categories have their own private Nested Diagnostic Contexts
|
|
||||||
self.__Logger_ndc = []
|
|
||||||
self.__Logger_classid = classid
|
|
||||||
|
|
||||||
cat.debug("Class %s instantiated" % classid)
|
|
||||||
if (use_cache == TRUE):
|
|
||||||
cache[classid] = cat
|
|
||||||
|
|
||||||
return cat
|
|
||||||
|
|
||||||
# Log-target handling (add, remove, set, remove_all)
|
|
||||||
|
|
||||||
def add_target(self, target, *args):
|
|
||||||
""" Add a target to the logger targets. """
|
|
||||||
if (not target in self.__Logger_targets):
|
|
||||||
if (target == TARGET_MYSQL):
|
|
||||||
if (mysql_available == TRUE):
|
|
||||||
# Required parameters: dbhost, dbname, dbuser, dbpass, dbtable
|
|
||||||
try:
|
|
||||||
self.__Logger_mysql_connection = MySQLdb.connect(host=args[0], db=args[1], user=args[2], passwd=args[3])
|
|
||||||
self.__Logger_mysql_cursor = self.__Logger_mysql_connection.cursor()
|
|
||||||
self.__Logger_mysql_tablename = args[4]
|
|
||||||
self.__Logger_targets.append(target)
|
|
||||||
except MySQLdb.OperationalError, detail:
|
|
||||||
self.error("MySQL connection failed: %s" % detail)
|
|
||||||
else:
|
|
||||||
self.error("MySQL target not added - Python-mysql not available")
|
|
||||||
else:
|
|
||||||
if (type(target) == StringType):
|
|
||||||
if (target not in SPECIAL_TARGETS):
|
|
||||||
# This is a filename
|
|
||||||
target = FileAppender(target, self.__Logger_rotation)
|
|
||||||
if ((target == TARGET_SYSLOG) and (os.name != "posix")):
|
|
||||||
self.warn("TARGET_SYSLOG is not available on non-posix platforms!")
|
|
||||||
else:
|
|
||||||
self.__Logger_targets.append(target)
|
|
||||||
|
|
||||||
def remove_target(self, target):
|
|
||||||
""" Remove a target from the logger targets. """
|
|
||||||
if (target in self.__Logger_targets):
|
|
||||||
if (target == TARGET_MYSQL):
|
|
||||||
self.__Logger_mysql_connection.close()
|
|
||||||
self.__Logger_targets.remove(target)
|
|
||||||
|
|
||||||
def set_target(self, target):
|
|
||||||
""" Set a single target. """
|
|
||||||
if (type(target) == StringType):
|
|
||||||
if (target not in SPECIAL_TARGETS):
|
|
||||||
# File target
|
|
||||||
target = FileAppender(target, self.__Logger_rotation)
|
|
||||||
self.__Logger_targets = [ target ]
|
|
||||||
|
|
||||||
def remove_all_targets(self):
|
|
||||||
""" Remove all targets from the logger targets. """
|
|
||||||
self.__Logger_targets=[]
|
|
||||||
|
|
||||||
def get_targets(self):
|
|
||||||
""" Returns all defined targets. """
|
|
||||||
return self.__Logger_targets
|
|
||||||
|
|
||||||
# Methods to set properties
|
|
||||||
|
|
||||||
def set_loglevel(self, loglevel):
|
|
||||||
""" Set the loglevel for the current instance. """
|
|
||||||
self.__Logger_loglevel = loglevel
|
|
||||||
|
|
||||||
def set_formatstring(self, formatstring):
|
|
||||||
""" Set a format string. """
|
|
||||||
self.__Logger_formatstring = formatstring
|
|
||||||
|
|
||||||
def set_use_ansi_codes(self, useansicodes):
|
|
||||||
""" Use ansi codes for output to the console (TRUE or FALSE). """
|
|
||||||
self.__Logger_useansicodes = useansicodes
|
|
||||||
|
|
||||||
def set_time_format(self, timeformat):
|
|
||||||
""" Set the time format (default: loaded from the system locale). """
|
|
||||||
self.__Logger_timeformat = timeformat
|
|
||||||
|
|
||||||
def set_rotation(self, rotation):
|
|
||||||
""" Set the file rotation mode to one of ROTATE_NONE, ROTATE_DAILY, ROTATE_WEEKLY, ROTATE_MONTHLY """
|
|
||||||
self.__Logger_rotation = rotation
|
|
||||||
for i in range(len(self.__Logger_targets)):
|
|
||||||
target = self.__Logger_targets[i]
|
|
||||||
if (isinstance(target, FileAppender)):
|
|
||||||
target.set_rotation(rotation)
|
|
||||||
|
|
||||||
# Method to get properties
|
|
||||||
|
|
||||||
def get_loglevel(self):
|
|
||||||
""" Returns the current loglevel. """
|
|
||||||
return self.__Logger_loglevel
|
|
||||||
|
|
||||||
def get_formatstring(self):
|
|
||||||
""" Returns the current format string. """
|
|
||||||
return self.__Logger_formatstring
|
|
||||||
|
|
||||||
def get_use_ansi_codes(self):
|
|
||||||
""" Returns, wether ansi codes are being used or not. """
|
|
||||||
return self.__Logger_useansicodes
|
|
||||||
|
|
||||||
def get_time_format(self):
|
|
||||||
""" Returns the current time format. """
|
|
||||||
return self.__Logger_timeformat
|
|
||||||
|
|
||||||
def get_rotation(self):
|
|
||||||
""" Returns the current rotation setting. """
|
|
||||||
return self.__Logger_rotation
|
|
||||||
|
|
||||||
# Methods to push and pop trace messages for nested contexts
|
|
||||||
|
|
||||||
def push(self, message):
|
|
||||||
""" Add a trace message. """
|
|
||||||
self.__Logger_ndc.append(message)
|
|
||||||
|
|
||||||
def pop(self):
|
|
||||||
""" Remove the topmost trace message. """
|
|
||||||
ct = len(self.__Logger_ndc)
|
|
||||||
if (ct):
|
|
||||||
del(self.__Logger_ndc[ct-1])
|
|
||||||
|
|
||||||
def clear_ndc(self):
|
|
||||||
""" Clears all NDC messages. """
|
|
||||||
self.__Logger_ndc = []
|
|
||||||
|
|
||||||
# Methods to actually print messages
|
|
||||||
|
|
||||||
def debug(self, *messages):
|
|
||||||
""" Write a debug message. """
|
|
||||||
if (self.__Logger_loglevel >= LOGLEVEL_DEBUG):
|
|
||||||
message = self.__Logger_collate_messages(messages)
|
|
||||||
self.__Logger_showmessage(message, MSG_DEBUG)
|
|
||||||
|
|
||||||
def warn(self, *messages):
|
|
||||||
""" Write a warning message. """
|
|
||||||
if (self.__Logger_loglevel >= LOGLEVEL_VERBOSE):
|
|
||||||
message = self.__Logger_collate_messages(messages)
|
|
||||||
self.__Logger_showmessage(message, MSG_WARN)
|
|
||||||
|
|
||||||
def error(self, *messages):
|
|
||||||
""" Write a error message. """
|
|
||||||
if (self.__Logger_loglevel >= LOGLEVEL_ERROR):
|
|
||||||
message = self.__Logger_collate_messages(messages)
|
|
||||||
self.__Logger_showmessage(message, MSG_ERROR)
|
|
||||||
|
|
||||||
def info(self, *messages):
|
|
||||||
""" Write a info message. """
|
|
||||||
if (self.__Logger_loglevel >= LOGLEVEL_NORMAL):
|
|
||||||
message = self.__Logger_collate_messages(messages)
|
|
||||||
self.__Logger_showmessage(message, MSG_INFO)
|
|
||||||
|
|
||||||
# Private methods of the Logger class - you never have to use those directly
|
|
||||||
|
|
||||||
def __Logger_collate_messages(self, messages):
|
|
||||||
""" **(private)** Create a single string from a number of messages. """
|
|
||||||
return strip(reduce(lambda x, y: "%s%s" % (x, y), messages))
|
|
||||||
|
|
||||||
def __Logger_tracestack(self):
|
|
||||||
""" **(private)** Analyze traceback stack and set linenumber and functionname. """
|
|
||||||
stack = traceback.extract_stack()
|
|
||||||
self.__Logger_module = stack[-4][0]
|
|
||||||
self.__Logger_linenumber = stack[-4][1]
|
|
||||||
self.__Logger_functionname = stack[-4][2]
|
|
||||||
self.__Logger_filename = stack[-4][0]
|
|
||||||
if (self.__Logger_functionname == "?"):
|
|
||||||
self.__Logger_functionname = "Main"
|
|
||||||
|
|
||||||
def __Logger_setdefaults(self):
|
|
||||||
""" **(private)** Set default values for internal variables. """
|
|
||||||
locale.setlocale(locale.LC_ALL)
|
|
||||||
self.__Logger_classid = None
|
|
||||||
self.__Logger_targets = [ TARGET_SYS_STDOUT ] # default target = sys.stdout
|
|
||||||
self.__Logger_formatstring = FMT_LONG
|
|
||||||
self.__Logger_loglevel = LOGLEVEL_NORMAL
|
|
||||||
self.__Logger_rotation = ROTATE_NONE
|
|
||||||
self.__Logger_useansicodes = FALSE
|
|
||||||
self.__Logger_functionname = ""
|
|
||||||
self.__Logger_filename = ""
|
|
||||||
self.__Logger_linenumber = -1
|
|
||||||
try:
|
|
||||||
self.__Logger_timeformat = "%s %s" % (locale.nl_langinfo(locale.D_FMT), locale.nl_langinfo(locale.T_FMT))
|
|
||||||
except (AttributeError):
|
|
||||||
self.__Logger_timeformat = "%d.%m.%Y %H:%M:%S"
|
|
||||||
self.__Logger_classname = None
|
|
||||||
self.__Logger_configfilename = ""
|
|
||||||
self.__Logger_module = ""
|
|
||||||
self.__Logger_ndc = [] # ndc = Nested Diagnostic Context
|
|
||||||
|
|
||||||
def __Logger_find_config(self):
|
|
||||||
""" **(private)** Search for configuration files. """
|
|
||||||
if (not self.__Logger_configfilename):
|
|
||||||
priorities = CONFIGURATION_FILES.keys()
|
|
||||||
priorities.sort()
|
|
||||||
configfilename = ""
|
|
||||||
for i in range(len(priorities)):
|
|
||||||
filename = CONFIGURATION_FILES[priorities[i]]
|
|
||||||
home_directory = get_homedirectory()
|
|
||||||
if (os.sep == "\\"):
|
|
||||||
home_directory = replace(home_directory, "\\", "\\\\")
|
|
||||||
filename = sub("\$HOME", home_directory, filename)
|
|
||||||
if (os.path.exists(filename)):
|
|
||||||
configfilename = filename
|
|
||||||
break
|
|
||||||
self.__Logger_configfilename = configfilename
|
|
||||||
return self.__Logger_configfilename
|
|
||||||
|
|
||||||
def __Logger_parse_options(self, section = SECTION_DEFAULT):
|
|
||||||
""" **(private)** Parse main options from config file. """
|
|
||||||
configfilename = self.__Logger_find_config()
|
|
||||||
|
|
||||||
if (configfilename != ""):
|
|
||||||
parser = ConfigParser()
|
|
||||||
parser.read(configfilename)
|
|
||||||
self.__Logger_set_instance_options(parser, section, self)
|
|
||||||
return TRUE
|
|
||||||
|
|
||||||
def __Logger_set_instance_options(self, parser, section, instance):
|
|
||||||
""" **(private)** Set the options for a given instance from the parser section """
|
|
||||||
|
|
||||||
for i in range(len(parser.options(section))):
|
|
||||||
option = lower(parser.options(section)[i])
|
|
||||||
value = parser.get(section, option)
|
|
||||||
if (option == "format"):
|
|
||||||
instance.set_formatstring(value)
|
|
||||||
elif (option == "timeformat"):
|
|
||||||
instance.set_time_format(value)
|
|
||||||
elif (option == "ansi"):
|
|
||||||
instance.set_use_ansi_codes(upper(value))
|
|
||||||
elif (option == "loglevel"):
|
|
||||||
instance.set_loglevel(LOG_LEVELS[upper(value)])
|
|
||||||
elif (option == "target"):
|
|
||||||
splitted = split(value, ",")
|
|
||||||
instance.remove_all_targets()
|
|
||||||
for i in range(len(splitted)):
|
|
||||||
instance.add_target(strip(splitted[i]))
|
|
||||||
|
|
||||||
def __Logger_cache_options(self):
|
|
||||||
""" **(private)** Read and cache debug levels for categories from config file. """
|
|
||||||
configfilename = self.__Logger_find_config()
|
|
||||||
|
|
||||||
if (configfilename != ""):
|
|
||||||
parser = ConfigParser()
|
|
||||||
parser.read(configfilename)
|
|
||||||
|
|
||||||
for i in range(len(parser.sections())):
|
|
||||||
section = parser.sections()[i]
|
|
||||||
if (section != SECTION_DEFAULT):
|
|
||||||
instance = self.get_instance(section)
|
|
||||||
self.__Logger_set_instance_options(parser, section, instance)
|
|
||||||
return TRUE
|
|
||||||
|
|
||||||
def __Logger_appendconfigfiles(self, filenames):
|
|
||||||
""" **(private)** Append a filename to the list of configuration files. """
|
|
||||||
filenames.reverse()
|
|
||||||
for i in range(len(filenames)):
|
|
||||||
keys = CONFIGURATION_FILES.keys()
|
|
||||||
CONFIGURATION_FILES[min(keys) - 1] = filenames[i]
|
|
||||||
|
|
||||||
def __Logger_get_ndc(self):
|
|
||||||
""" **(private)** Returns the NDC (nested diagnostic context) joined with single-spaces. """
|
|
||||||
if (len(self.__Logger_ndc)):
|
|
||||||
return join(self.__Logger_ndc)
|
|
||||||
else:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def __Logger_showmessage(self, message, messagesource):
|
|
||||||
""" **(private)** Writes a message to all targets set. """
|
|
||||||
|
|
||||||
if (isinstance(message, Exception)):
|
|
||||||
(exc_type, exc_value, tb) = sys.exc_info()
|
|
||||||
exception_summary = traceback.format_exception(exc_type, exc_value, tb)
|
|
||||||
message = 'Exception caught:\n'
|
|
||||||
for line in exception_summary:
|
|
||||||
message = "%s%s" % (message, line)
|
|
||||||
|
|
||||||
currenttime = time()
|
|
||||||
self.__Logger_tracestack()
|
|
||||||
timedifference = "%.3f" % (currenttime - self.__Logger_timeinit)
|
|
||||||
timedifflaststep = "%.3f" % (currenttime - self.__Logger_timelaststep)
|
|
||||||
self.__Logger_timelaststep = currenttime
|
|
||||||
milliseconds = int(round((currenttime - long(currenttime)) * 1000))
|
|
||||||
timeformat = sub("%S", "%S." + (zfill(milliseconds, 3)), self.__Logger_timeformat)
|
|
||||||
currentformattedtime = strftime(timeformat, localtime(currenttime))
|
|
||||||
|
|
||||||
line = self.__Logger_formatstring
|
|
||||||
line = sub("%C", str(self.__Logger_classname), line)
|
|
||||||
line = sub("%D", timedifference, line)
|
|
||||||
line = sub("%d", timedifflaststep, line)
|
|
||||||
line = sub("%F", self.__Logger_functionname, line)
|
|
||||||
line = sub("%f", self.__Logger_filename, line)
|
|
||||||
line = sub("%U", self.__Logger_module, line)
|
|
||||||
line = sub("%u", os.path.split(self.__Logger_module)[-1], line)
|
|
||||||
ndc = self.__Logger_get_ndc()
|
|
||||||
if (ndc != ""):
|
|
||||||
line = sub("%x", "%s - " % ndc, line)
|
|
||||||
else:
|
|
||||||
line = sub("%x", "", line)
|
|
||||||
message = replace(message, "\\", "\\\\")
|
|
||||||
if (self.__Logger_useansicodes == TRUE):
|
|
||||||
line = sub("%L", self.__Logger_ansi(LOG_MSG[messagesource], messagesource), line)
|
|
||||||
line = sub("%M", self.__Logger_ansi(message, messagesource), line)
|
|
||||||
else:
|
|
||||||
line = sub("%L", LOG_MSG[messagesource], line)
|
|
||||||
line = sub("%M", message, line)
|
|
||||||
line = sub("%N", str(self.__Logger_linenumber), line)
|
|
||||||
line = sub("%T", currentformattedtime, line)
|
|
||||||
line = sub("%t", `currenttime`, line)
|
|
||||||
|
|
||||||
for i in range(len(self.__Logger_targets)):
|
|
||||||
target = self.__Logger_targets[i]
|
|
||||||
if (target == TARGET_MYSQL):
|
|
||||||
sqltime = strftime("'%Y-%m-%d', '%H:%M:%S'", localtime(currenttime))
|
|
||||||
sqlStatement = "INSERT INTO %s (host, facility, level, date, time, program, msg) VALUES ('%s', '%s', '%s', %s, '%s', '%s')" % (self.__Logger_mysql_tablename, self.hostname, self.__Logger_functionname, LOG_MSG[messagesource], sqltime, str(self.__Logger_classname), sub("'", "`", message + " " + ndc))
|
|
||||||
self.__Logger_mysql_cursor.execute(sqlStatement)
|
|
||||||
elif (target == TARGET_SYSLOG):
|
|
||||||
# We don't need time and stuff here
|
|
||||||
syslog.syslog(message)
|
|
||||||
elif (isinstance(target, FileAppender)):
|
|
||||||
target.writeline(line)
|
|
||||||
elif (target == sys.stdout) or (lower(target) == TARGET_SYS_STDOUT) or (lower(target) == TARGET_SYS_STDOUT_ALIAS):
|
|
||||||
sys.stdout.write("%s\n" % line)
|
|
||||||
elif (target == sys.stderr) or (lower(target) == TARGET_SYS_STDERR) or (lower(target) == TARGET_SYS_STDERR_ALIAS):
|
|
||||||
sys.stderr.write("%s\n" % line)
|
|
||||||
else:
|
|
||||||
target.write("%s\n" % line)
|
|
||||||
|
|
||||||
def __Logger_ansi(self, text, messagesource):
|
|
||||||
""" **(private)** Converts plain text to ansi text. """
|
|
||||||
bold = LOG_COLORS[messagesource][2]
|
|
||||||
fg = str(LOG_COLORS[messagesource][0])
|
|
||||||
bg = LOG_COLORS[messagesource][1]
|
|
||||||
if (bold == TRUE):
|
|
||||||
fg = "%s;1" % fg
|
|
||||||
bg = bg + 10
|
|
||||||
text = "\033[%d;%sm%s\033[0m" % (bg, fg, text)
|
|
||||||
return text
|
|
||||||
|
|
||||||
class FileAppender:
|
|
||||||
|
|
||||||
def __init__(self, filename, rotation = ROTATE_NONE):
|
|
||||||
""" **(private)** Class initalization & customization. """
|
|
||||||
self.__FileAppender_filename = sub("\$HOME", get_homedirectory(), filename)
|
|
||||||
self.__FileAppender_filename = os.path.expanduser(self.__FileAppender_filename)
|
|
||||||
self.__FileAppender_filename = os.path.expandvars(self.__FileAppender_filename)
|
|
||||||
self.__FileAppender_rotation = rotation
|
|
||||||
|
|
||||||
def __FileAppender_rotate(self, modification_time):
|
|
||||||
""" **(private)** Check, wether the file has to be rotated yet or not. """
|
|
||||||
if (self.__FileAppender_rotation == ROTATE_DAILY):
|
|
||||||
strftime_mask = "%Y%j"
|
|
||||||
elif (self.__FileAppender_rotation == ROTATE_WEEKLY):
|
|
||||||
strftime_mask = "%Y%W"
|
|
||||||
elif (self.__FileAppender_rotation == ROTATE_MONTHLY):
|
|
||||||
strftime_mask = "%Y%m"
|
|
||||||
return (strftime(strftime_mask, localtime(time())) != strftime(strftime_mask, localtime(modification_time)))
|
|
||||||
|
|
||||||
def __FileAppender_date_string(self, modification_time):
|
|
||||||
""" **(private)** Returns a new filename for the rotated file with the appropriate time included. """
|
|
||||||
if (self.__FileAppender_rotation == ROTATE_DAILY):
|
|
||||||
return strftime("%Y-%m-%d", localtime(modification_time))
|
|
||||||
elif (self.__FileAppender_rotation == ROTATE_WEEKLY):
|
|
||||||
return strftime("%Y-Week %W", localtime(modification_time))
|
|
||||||
elif (self.__FileAppender_rotation == ROTATE_MONTHLY):
|
|
||||||
return strftime("%Y-Month %m", localtime(modification_time))
|
|
||||||
|
|
||||||
def get_rotation(self):
|
|
||||||
""" Returns the current rotation setting. """
|
|
||||||
return self.__FileAppender_rotation
|
|
||||||
|
|
||||||
def set_rotation(self, rotation):
|
|
||||||
""" Set the file rotation mode to one of ROTATE_NONE, ROTATE_DAILY, ROTATE_WEEKLY, ROTATE_MONTHLY """
|
|
||||||
self.__FileAppender_rotation = rotation
|
|
||||||
|
|
||||||
def write(self, text):
|
|
||||||
""" Write some text to the file appender. """
|
|
||||||
if ((os.path.exists(self.__FileAppender_filename)) and (self.__FileAppender_rotation != ROTATE_NONE)):
|
|
||||||
statinfo = stat(self.__FileAppender_filename)
|
|
||||||
if (self.__FileAppender_rotate(statinfo[8])):
|
|
||||||
splitted = os.path.splitext(self.__FileAppender_filename)
|
|
||||||
target_file = "%s-%s%s" % (splitted[0], self.__FileAppender_date_string(statinfo[8]), splitted[1])
|
|
||||||
rename(self.__FileAppender_filename, target_file)
|
|
||||||
file = open(self.__FileAppender_filename, "a")
|
|
||||||
file.write(text)
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
def writeline(self, text):
|
|
||||||
""" Write some text including newline to the file appender. """
|
|
||||||
self.write("%s\n" % text)
|
|
|
@ -1,17 +0,0 @@
|
||||||
To use mysql as logging database, please perform the following steps:
|
|
||||||
|
|
||||||
1. Create a database and table:
|
|
||||||
|
|
||||||
"mysql -u root -p < mysql.sql"
|
|
||||||
|
|
||||||
This will create a new database "syslog" and a table "logs"
|
|
||||||
|
|
||||||
2. Grant access to the log table to one or more users:
|
|
||||||
|
|
||||||
"mysql -u root -p"
|
|
||||||
"use syslog;"
|
|
||||||
"grant insert,select,update,delete on syslog.logs to log4py@localhost;"
|
|
||||||
|
|
||||||
3. If log4py@localhost is a new user, don't forget to set a password:
|
|
||||||
|
|
||||||
"mysqladmin -u log4py -p password mysecretpwd"
|
|
|
@ -1,25 +0,0 @@
|
||||||
# Table structure for table `logs`
|
|
||||||
|
|
||||||
CREATE DATABASE syslog;
|
|
||||||
|
|
||||||
USE syslog;
|
|
||||||
|
|
||||||
CREATE TABLE logs (host varchar(32) default NULL,
|
|
||||||
facility varchar(10) default NULL,
|
|
||||||
priority varchar(10) default NULL,
|
|
||||||
level varchar(10) default NULL,
|
|
||||||
tag varchar(10) default NULL,
|
|
||||||
date date default NULL,
|
|
||||||
time time default NULL,
|
|
||||||
program varchar(15) default NULL,
|
|
||||||
msg text,
|
|
||||||
seq int(10) unsigned NOT NULL auto_increment,
|
|
||||||
PRIMARY KEY (seq),
|
|
||||||
KEY host (host),
|
|
||||||
KEY seq (seq),
|
|
||||||
KEY program (program),
|
|
||||||
KEY time (time),
|
|
||||||
KEY date (date),
|
|
||||||
KEY priority (priority),
|
|
||||||
KEY facility (facility)
|
|
||||||
) TYPE=MyISAM;
|
|
|
@ -1,14 +0,0 @@
|
||||||
Code Maintainer:
|
|
||||||
|
|
||||||
Martin Preishuber <Martin.Preishuber@eclipt.at>
|
|
||||||
|
|
||||||
Developers:
|
|
||||||
|
|
||||||
Martin Preishuber <Martin.Preishuber@eclipt.at>
|
|
||||||
Bruce Kroeze <bruce@zefamily.org>
|
|
||||||
|
|
||||||
Contributors:
|
|
||||||
|
|
||||||
Weiyi Yang <wyyang@mmodal.com>
|
|
||||||
Emily Bache <Emily.Bache@astrazeneca.com>
|
|
||||||
Rico Hendriks <rico@netsco.com>
|
|
|
@ -1 +0,0 @@
|
||||||
See the file LICENSE in this directory.
|
|
|
@ -1,87 +0,0 @@
|
||||||
Version 1.3
|
|
||||||
|
|
||||||
- FileAppender class added (generic file rotation)
|
|
||||||
- log4py uses FileAppender class for logfiles (enables log file rotation)
|
|
||||||
- support for win32 platform
|
|
||||||
- $HOME is replaced correctly on win32 platform
|
|
||||||
|
|
||||||
Version 1.2.1
|
|
||||||
|
|
||||||
- syslog support is only enabled on POSIX operating systems
|
|
||||||
|
|
||||||
Version 1.2
|
|
||||||
|
|
||||||
- syslog support added (very simple by now)
|
|
||||||
- bug fixed with sys.stderr (thanks Alain)
|
|
||||||
- get_targets method added
|
|
||||||
- environment variables in filename targets get expanded now
|
|
||||||
- added %f as format parameter, which is replaced by the current filename
|
|
||||||
(thanks Rémi)
|
|
||||||
- targets which support the write method work now (thanks again Rémi)
|
|
||||||
- Changed to order in info/debug/error message so _collate_messages
|
|
||||||
will only be called if required
|
|
||||||
|
|
||||||
Version 1.1.1
|
|
||||||
|
|
||||||
- new Format parameter %t added (Thanks Emily)
|
|
||||||
- possibility to log exceptions added (Thanks Rico)
|
|
||||||
- possibility to log filenames added (Thanks again Rico)
|
|
||||||
|
|
||||||
Version 1.1
|
|
||||||
|
|
||||||
- README updated
|
|
||||||
- MySQL target added (thanks Weiyi Yang)
|
|
||||||
|
|
||||||
Version 1.0.1
|
|
||||||
|
|
||||||
- Loglevel LOGLEVEL_ERROR added (to show only error messages)
|
|
||||||
|
|
||||||
Version 1.0
|
|
||||||
|
|
||||||
- minor bug fixes
|
|
||||||
|
|
||||||
Version 0.7.1
|
|
||||||
|
|
||||||
- HTML documentation added (generated from doc strings)
|
|
||||||
|
|
||||||
Version 0.7:
|
|
||||||
|
|
||||||
- changed the class name from Category to Logger (log4j 1.2 conform)
|
|
||||||
- bug fixes with environment variables on windows systems (thanks Colin)
|
|
||||||
- fixed some bug with escaping \ (thanks again Colin)
|
|
||||||
- the configuration file may include settings for various instances now.
|
|
||||||
- multiple target support added.
|
|
||||||
|
|
||||||
Version 0.6:
|
|
||||||
|
|
||||||
- nested diagnostic contexts added (Bruce)
|
|
||||||
- application loglevels added to config files (Bruce)
|
|
||||||
|
|
||||||
Version 0.5:
|
|
||||||
|
|
||||||
- included a patch of Bruce Kroeze (bruce@zefamily.org), which improves
|
|
||||||
the performance by reading the config file only once and makes log4py
|
|
||||||
safe for deepcopying.
|
|
||||||
|
|
||||||
Version 0.4:
|
|
||||||
|
|
||||||
- license change from GPL to MIT
|
|
||||||
- the usual minor bugfixes
|
|
||||||
|
|
||||||
Version 0.3:
|
|
||||||
|
|
||||||
- added format parameter %d (duration since last message)
|
|
||||||
- log4py is used for debugging (if available)
|
|
||||||
- some minor bug fixes
|
|
||||||
|
|
||||||
Version 0.2:
|
|
||||||
|
|
||||||
- support for configuration files added
|
|
||||||
- support for user configurable timeformats added
|
|
||||||
- removed some parameters from the class initialization
|
|
||||||
- changed the default target to None (instead of sys.stdout) to make
|
|
||||||
log4py deepcopyable
|
|
||||||
|
|
||||||
Version 0.1:
|
|
||||||
|
|
||||||
- initial release
|
|
|
@ -1,20 +0,0 @@
|
||||||
Copyright (c) 2001 Martin Preishuber
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
@ -1,14 +0,0 @@
|
||||||
|
|
||||||
<HR noshade>
|
|
||||||
|
|
||||||
<TABLE ALIGN="LEFT">
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<A HREF="http://validator.w3.org/check/referer" TARGET="validate"><IMG BORDER=0 SRC="http://validator.w3.org/images/vh40.gif" ALT="Valid HTML 4.0!" HEIGHT=31 WIDTH=88></A>
|
|
||||||
<A HREF="http://www.w3.org/Style/CSS/Buttons"><IMG ALT="Made with CSS" BORDER=0 WIDTH=88 HEIGHT=31 SRC="http://www.w3.org/Style/CSS/Buttons/mwcos"></A>
|
|
||||||
</TD>
|
|
||||||
<TD STYLE="padding-left: 10">
|
|
||||||
<SPAN CLASS="AUTHOR">Martin Preishuber, <a href="mailto:Martin.Preishuber@eclipt.at">Martin.Preishuber@eclipt.at</a></SPAN><BR>
|
|
||||||
<SPAN CLASS="VERSION">Version 1.3</SPAN>
|
|
||||||
</TD>
|
|
||||||
</TABLE>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<span CLASS="ClassHead">
|
|
||||||
<table width="100%" bgcolor="#eeeeee">
|
|
||||||
<tr>
|
|
||||||
<td nowrap><a class="DocLink" HREF="index.html"><span CLASS="ClassName"><b>Table of contents</b></span></A></td>
|
|
||||||
<td> <b>|</b> </td>
|
|
||||||
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
|
|
||||||
<td width="100%"> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</span>
|
|
|
@ -1,47 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
|
|
||||||
<META NAME="GENERATOR" CONTENT="pythondoc 0.7 (Sat Aug 9 16:08:18 2003)">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="log4py.css" type="text/css">
|
|
||||||
|
|
||||||
<title>Contents</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<span CLASS="ClassHead">
|
|
||||||
<table width="100%" bgcolor="#eeeeee">
|
|
||||||
<tr>
|
|
||||||
<td nowrap><a class="DocLink" HREF="index.html"><span CLASS="ClassName"><b>Table of contents</b></span></A></td>
|
|
||||||
<td> <b>|</b> </td>
|
|
||||||
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
|
|
||||||
<td width="100%"> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<H1>Documented Python modules</H1>
|
|
||||||
<P><A HREF="indices.html">Index</A></P>
|
|
||||||
<UL CLASS="Contents">
|
|
||||||
<LI><A HREF="log4py.html">log4py</A>
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
|
|
||||||
<HR noshade>
|
|
||||||
|
|
||||||
<TABLE ALIGN="LEFT">
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<A HREF="http://validator.w3.org/check/referer" TARGET="validate"><IMG BORDER=0 SRC="http://validator.w3.org/images/vh40.gif" ALT="Valid HTML 4.0!" HEIGHT=31 WIDTH=88></A>
|
|
||||||
<A HREF="http://www.w3.org/Style/CSS/Buttons"><IMG ALT="Made with CSS" BORDER=0 WIDTH=88 HEIGHT=31 SRC="http://www.w3.org/Style/CSS/Buttons/mwcos"></A>
|
|
||||||
</TD>
|
|
||||||
<TD STYLE="padding-left: 10">
|
|
||||||
<SPAN CLASS="AUTHOR">Martin Preishuber, <a href="mailto:Martin.Preishuber@eclipt.at">Martin.Preishuber@eclipt.at</a></SPAN><BR>
|
|
||||||
<SPAN CLASS="VERSION">Version 1.3</SPAN>
|
|
||||||
</TD>
|
|
||||||
</TABLE>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,59 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
|
|
||||||
<META NAME="GENERATOR" CONTENT="pythondoc 0.7 (Sat Aug 9 16:08:18 2003)">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="log4py.css" type="text/css">
|
|
||||||
|
|
||||||
<title>Index page</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<span CLASS="ClassHead">
|
|
||||||
<table width="100%" bgcolor="#eeeeee">
|
|
||||||
<tr>
|
|
||||||
<td nowrap><a class="DocLink" HREF="index.html"><span CLASS="ClassName"><b>Table of contents</b></span></A></td>
|
|
||||||
<td> <b>|</b> </td>
|
|
||||||
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
|
|
||||||
<td width="100%"> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<H1>Index page</H1>
|
|
||||||
<P><A HREF="index.html">Table of contents</A></P>
|
|
||||||
<A HREF="#F">F</A> <A HREF="#G">G</A> <A HREF="#L">L</A> <BR>
|
|
||||||
<HR>
|
|
||||||
|
|
||||||
<H2 ID="F">F</H2>
|
|
||||||
<P CLASS="IndexEntry0"><A CLASS="IndexLink" HREF="log4py.FileAppender.html">FileAppender, Class (in Module log4py)</A></P>
|
|
||||||
|
|
||||||
<H2 ID="G">G</H2>
|
|
||||||
<P CLASS="IndexEntry0"><A CLASS="IndexLink" HREF="log4py.get_homedirectory.html">get_homedirectory, Function (in Module log4py)</A></P>
|
|
||||||
|
|
||||||
<H2 ID="L">L</H2>
|
|
||||||
<P CLASS="IndexEntry0"><A CLASS="IndexLink" HREF="log4py.html">log4py, Module</A></P>
|
|
||||||
<P CLASS="IndexEntry1"><A CLASS="IndexLink" HREF="log4py.FileAppender.html">FileAppender, Class</A></P>
|
|
||||||
<P CLASS="IndexEntry1"><A CLASS="IndexLink" HREF="log4py.get_homedirectory.html">get_homedirectory, Function</A></P>
|
|
||||||
<P CLASS="IndexEntry1"><A CLASS="IndexLink" HREF="log4py.Logger.html">Logger, Class</A></P>
|
|
||||||
<P CLASS="IndexEntry0"><A CLASS="IndexLink" HREF="log4py.Logger.html">Logger, Class (in Module log4py)</A></P>
|
|
||||||
|
|
||||||
|
|
||||||
<HR noshade>
|
|
||||||
|
|
||||||
<TABLE ALIGN="LEFT">
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<A HREF="http://validator.w3.org/check/referer" TARGET="validate"><IMG BORDER=0 SRC="http://validator.w3.org/images/vh40.gif" ALT="Valid HTML 4.0!" HEIGHT=31 WIDTH=88></A>
|
|
||||||
<A HREF="http://www.w3.org/Style/CSS/Buttons"><IMG ALT="Made with CSS" BORDER=0 WIDTH=88 HEIGHT=31 SRC="http://www.w3.org/Style/CSS/Buttons/mwcos"></A>
|
|
||||||
</TD>
|
|
||||||
<TD STYLE="padding-left: 10">
|
|
||||||
<SPAN CLASS="AUTHOR">Martin Preishuber, <a href="mailto:Martin.Preishuber@eclipt.at">Martin.Preishuber@eclipt.at</a></SPAN><BR>
|
|
||||||
<SPAN CLASS="VERSION">Version 1.3</SPAN>
|
|
||||||
</TD>
|
|
||||||
</TABLE>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,58 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
|
|
||||||
<META NAME="GENERATOR" CONTENT="pythondoc 0.7 (Sat Aug 9 16:08:18 2003)">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="log4py.css" type="text/css">
|
|
||||||
|
|
||||||
<title>Class FileAppender</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<span CLASS="ClassHead">
|
|
||||||
<table width="100%" bgcolor="#eeeeee">
|
|
||||||
<tr>
|
|
||||||
<td nowrap><a class="DocLink" HREF="index.html"><span CLASS="ClassName"><b>Table of contents</b></span></A></td>
|
|
||||||
<td> <b>|</b> </td>
|
|
||||||
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
|
|
||||||
<td width="100%"> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<H1 CLASS="ClassName">class FileAppender</H1>
|
|
||||||
<P CLASS="DeclaredIn">Declared in module <A HREF="log4py.html">log4py</A></P>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<H2>Synopsis</H2>
|
|
||||||
<PRE CLASS="ClassDeclaration">
|
|
||||||
<SPAN CLASS="PyKeyword">class</SPAN> <SPAN CLASS="ClassName">FileAppender</SPAN>:
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.FileAppender.__FileAppender_date_string</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">modification_time</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Returns a new filename for the rotated file with the appropriate time included. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.FileAppender.__FileAppender_rotate</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">modification_time</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Check, wether the file has to be rotated yet or not. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.FileAppender.__init__</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">filename</SPAN>, <SPAN CLASS="Argument">rotation=0</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Class initalization & customization. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.FileAppender.get_rotation</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Returns the current rotation setting. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.FileAppender.set_rotation</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">rotation</SPAN>)<SPAN CLASS="OneLiner"> # Set the file rotation mode to one of ROTATE_NONE, ROTATE_DAILY, ROTATE_WEEKLY, ROTATE_MONTHLY </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.FileAppender.write</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">text</SPAN>)<SPAN CLASS="OneLiner"> # Write some text to the file appender. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.FileAppender.writeline</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">text</SPAN>)<SPAN CLASS="OneLiner"> # Write some text including newline to the file appender. </SPAN>
|
|
||||||
|
|
||||||
</PRE>
|
|
||||||
|
|
||||||
<HR noshade>
|
|
||||||
|
|
||||||
<TABLE ALIGN="LEFT">
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<A HREF="http://validator.w3.org/check/referer" TARGET="validate"><IMG BORDER=0 SRC="http://validator.w3.org/images/vh40.gif" ALT="Valid HTML 4.0!" HEIGHT=31 WIDTH=88></A>
|
|
||||||
<A HREF="http://www.w3.org/Style/CSS/Buttons"><IMG ALT="Made with CSS" BORDER=0 WIDTH=88 HEIGHT=31 SRC="http://www.w3.org/Style/CSS/Buttons/mwcos"></A>
|
|
||||||
</TD>
|
|
||||||
<TD STYLE="padding-left: 10">
|
|
||||||
<SPAN CLASS="AUTHOR">Martin Preishuber, <a href="mailto:Martin.Preishuber@eclipt.at">Martin.Preishuber@eclipt.at</a></SPAN><BR>
|
|
||||||
<SPAN CLASS="VERSION">Version 1.3</SPAN>
|
|
||||||
</TD>
|
|
||||||
</TABLE>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,98 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
|
|
||||||
<META NAME="GENERATOR" CONTENT="pythondoc 0.7 (Sat Aug 9 16:08:18 2003)">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="log4py.css" type="text/css">
|
|
||||||
|
|
||||||
<title>Class Logger</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<span CLASS="ClassHead">
|
|
||||||
<table width="100%" bgcolor="#eeeeee">
|
|
||||||
<tr>
|
|
||||||
<td nowrap><a class="DocLink" HREF="index.html"><span CLASS="ClassName"><b>Table of contents</b></span></A></td>
|
|
||||||
<td> <b>|</b> </td>
|
|
||||||
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
|
|
||||||
<td width="100%"> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<H1 CLASS="ClassName">class Logger</H1>
|
|
||||||
<P CLASS="DeclaredIn">Declared in module <A HREF="log4py.html">log4py</A></P>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<H2>Synopsis</H2>
|
|
||||||
<PRE CLASS="ClassDeclaration">
|
|
||||||
<SPAN CLASS="PyKeyword">class</SPAN> <SPAN CLASS="ClassName">Logger</SPAN>:
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_ansi</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">text</SPAN>, <SPAN CLASS="Argument">messagesource</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Converts plain text to ansi text. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_appendconfigfiles</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">filenames</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Append a filename to the list of configuration files. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_cache_options</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Read and cache debug levels for categories from config file. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_collate_messages</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">messages</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Create a single string from a number of messages. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_find_config</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Search for configuration files. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_get_ndc</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Returns the NDC (nested diagnostic context) joined with single-spaces. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_parse_options</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">section='Default'</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Parse main options from config file. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_set_instance_options</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">parser</SPAN>, <SPAN CLASS="Argument">section</SPAN>, <SPAN CLASS="Argument">instance</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Set the options for a given instance from the parser section </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_setdefaults</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Set default values for internal variables. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_showmessage</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">message</SPAN>, <SPAN CLASS="Argument">messagesource</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Writes a message to all targets set. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__Logger_tracestack</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Analyze traceback stack and set linenumber and functionname. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.__init__</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">useconfigfiles='TRUE'</SPAN>, <SPAN CLASS="Argument">customconfigfiles=None</SPAN>)<SPAN CLASS="OneLiner"> # <STRONG>(private)</STRONG> Class initalization & customization. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.add_target</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">target</SPAN>, <SPAN CLASS="Argument">*args</SPAN>)<SPAN CLASS="OneLiner"> # Add a target to the logger targets. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.clear_ndc</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Clears all NDC messages. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.debug</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">*messages</SPAN>)<SPAN CLASS="OneLiner"> # Write a debug message. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.error</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">*messages</SPAN>)<SPAN CLASS="OneLiner"> # Write a error message. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.get_formatstring</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Returns the current format string. </SPAN>
|
|
||||||
<A CLASS="DocLink" HREF="#log4py.Logger.get_instance"><SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.get_instance</SPAN></A>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">classid='Main'</SPAN>, <SPAN CLASS="Argument">use_cache='TRUE'</SPAN>)<SPAN CLASS="OneLiner"> # Either get the cached logger instance or create a new one</SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.get_loglevel</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Returns the current loglevel. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.get_root</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Provides a way to change the base logger object's properties. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.get_rotation</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Returns the current rotation setting. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.get_targets</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Returns all defined targets. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.get_time_format</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Returns the current time format. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.get_use_ansi_codes</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Returns, wether ansi codes are being used or not. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.info</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">*messages</SPAN>)<SPAN CLASS="OneLiner"> # Write a info message. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.pop</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Remove the topmost trace message. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.push</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">message</SPAN>)<SPAN CLASS="OneLiner"> # Add a trace message. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.remove_all_targets</SPAN>(<SPAN CLASS="Argument">self</SPAN>)<SPAN CLASS="OneLiner"> # Remove all targets from the logger targets. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.remove_target</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">target</SPAN>)<SPAN CLASS="OneLiner"> # Remove a target from the logger targets. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.set_formatstring</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">formatstring</SPAN>)<SPAN CLASS="OneLiner"> # Set a format string. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.set_loglevel</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">loglevel</SPAN>)<SPAN CLASS="OneLiner"> # Set the loglevel for the current instance. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.set_rotation</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">rotation</SPAN>)<SPAN CLASS="OneLiner"> # Set the file rotation mode to one of ROTATE_NONE, ROTATE_DAILY, ROTATE_WEEKLY, ROTATE_MONTHLY </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.set_target</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">target</SPAN>)<SPAN CLASS="OneLiner"> # Set a single target. </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.set_time_format</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">timeformat</SPAN>)<SPAN CLASS="OneLiner"> # Set the time format (default: loaded from the system locale). </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.set_use_ansi_codes</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">useansicodes</SPAN>)<SPAN CLASS="OneLiner"> # Use ansi codes for output to the console (TRUE or FALSE). </SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">log4py.Logger.warn</SPAN>(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">*messages</SPAN>)<SPAN CLASS="OneLiner"> # Write a warning message. </SPAN>
|
|
||||||
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">dictionary</SPAN> <SPAN CLASS="VariableName">cache</SPAN> = <SPAN CLASS="VariableValue">{}</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">list</SPAN> <SPAN CLASS="VariableName">configfiles</SPAN> = <SPAN CLASS="VariableValue">[]</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">hostname</SPAN> = <SPAN CLASS="VariableValue">'travelmate'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">None</SPAN> <SPAN CLASS="VariableName">instance</SPAN> = <SPAN CLASS="VariableValue">None</SPAN></SPAN>
|
|
||||||
</PRE><H2 ID="log4py.Logger.get_instance" CLASS="Method">log4py.Logger.get_instance(<SPAN CLASS="Argument">self</SPAN>, <SPAN CLASS="Argument">classid='Main'</SPAN>, <SPAN CLASS="Argument">use_cache='TRUE'</SPAN>)</H2>
|
|
||||||
<P> Either get the cached logger instance or create a new one</P>
|
|
||||||
|
|
||||||
<P>
|
|
||||||
Note that this is safe, even if you have your target set to sys.stdout
|
|
||||||
or sys.stderr
|
|
||||||
</P>
|
|
||||||
|
|
||||||
|
|
||||||
<HR noshade>
|
|
||||||
|
|
||||||
<TABLE ALIGN="LEFT">
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<A HREF="http://validator.w3.org/check/referer" TARGET="validate"><IMG BORDER=0 SRC="http://validator.w3.org/images/vh40.gif" ALT="Valid HTML 4.0!" HEIGHT=31 WIDTH=88></A>
|
|
||||||
<A HREF="http://www.w3.org/Style/CSS/Buttons"><IMG ALT="Made with CSS" BORDER=0 WIDTH=88 HEIGHT=31 SRC="http://www.w3.org/Style/CSS/Buttons/mwcos"></A>
|
|
||||||
</TD>
|
|
||||||
<TD STYLE="padding-left: 10">
|
|
||||||
<SPAN CLASS="AUTHOR">Martin Preishuber, <a href="mailto:Martin.Preishuber@eclipt.at">Martin.Preishuber@eclipt.at</a></SPAN><BR>
|
|
||||||
<SPAN CLASS="VERSION">Version 1.3</SPAN>
|
|
||||||
</TD>
|
|
||||||
</TABLE>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,86 +0,0 @@
|
||||||
//
|
|
||||||
// $Header: /cvsroot/log4py/log4py/doc/html/log4py.css,v 1.1 2003/04/09 19:02:06 preisl Exp $
|
|
||||||
//
|
|
||||||
// Default style sheet for pythondoc HTML4 mode.
|
|
||||||
//
|
|
||||||
// Written by Daniel Larsson.
|
|
||||||
//
|
|
||||||
// $History: $
|
|
||||||
//
|
|
||||||
|
|
||||||
H1, H2, H3 {
|
|
||||||
font-family: Tahoma, Verdana, Arial, Helvetica;
|
|
||||||
font-style: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
H1 {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
H2 {
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
H3 {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
//H1.ModuleName, H1.FunctionName, H1.ClassName {
|
|
||||||
// font-size: 18pt;
|
|
||||||
//}
|
|
||||||
|
|
||||||
.ClassHead {
|
|
||||||
}
|
|
||||||
|
|
||||||
BODY, TD {
|
|
||||||
font-family: Tahoma, Verdana, Arial, Helvetica;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Body {
|
|
||||||
}
|
|
||||||
|
|
||||||
SPAN.PyKeyword, SPAN.VariableType {
|
|
||||||
color: indigo;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPAN.ClassName {
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPAN.FunctionName, SPAN.VariableName, SPAN.AliasName {
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Argument {
|
|
||||||
color: brown;
|
|
||||||
}
|
|
||||||
|
|
||||||
.OneLiner {
|
|
||||||
color: darkgreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
.IndexEntry0, .IndexEntry1, .IndexEntry2, .IndexEntry3 {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.IndexEntry1 {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.IndexEntry2 {
|
|
||||||
margin-left: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.IndexEntry3 {
|
|
||||||
margin-left: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
A.DocLink, A.IndexLink {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
A:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
|
@ -1,160 +0,0 @@
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
|
|
||||||
<META NAME="GENERATOR" CONTENT="pythondoc 0.7 (Sat Aug 9 16:08:18 2003)">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="log4py.css" type="text/css">
|
|
||||||
|
|
||||||
<title>Module log4py</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<span CLASS="ClassHead">
|
|
||||||
<table width="100%" bgcolor="#eeeeee">
|
|
||||||
<tr>
|
|
||||||
<td nowrap><a class="DocLink" HREF="index.html"><span CLASS="ClassName"><b>Table of contents</b></span></A></td>
|
|
||||||
<td> <b>|</b> </td>
|
|
||||||
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
|
|
||||||
<td width="100%"> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<H1 CLASS="ModuleName">Module log4py</H1>
|
|
||||||
<PRE><SPAN CLASS="ClassHead"><A CLASS="DocLink" HREF="log4py.FileAppender.html"><SPAN CLASS="PyKeyword">class</SPAN> <SPAN CLASS="ClassName">FileAppender</SPAN></A></SPAN>
|
|
||||||
<SPAN CLASS="ClassHead"><A CLASS="DocLink" HREF="log4py.Logger.html"><SPAN CLASS="PyKeyword">class</SPAN> <SPAN CLASS="ClassName">Logger</SPAN></A></SPAN>
|
|
||||||
<SPAN CLASS="FunctionHead"><SPAN CLASS="PyKeyword">def</SPAN> <SPAN CLASS="FunctionName">get_homedirectory</SPAN>()</SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">AQUA</SPAN> = <SPAN CLASS="VariableValue">36</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">BLACK</SPAN> = <SPAN CLASS="VariableValue">30</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">BLUE</SPAN> = <SPAN CLASS="VariableValue">34</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">dictionary</SPAN> <SPAN CLASS="VariableName">CONFIGURATION_FILES</SPAN> = <SPAN CLASS="VariableValue">{1: 'log4py.conf', 2: '$HOME/.log4py.conf', 3: '/etc/log4py.conf'}</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">FALSE</SPAN> = <SPAN CLASS="VariableValue">'FALSE'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">FMT_DEBUG</SPAN> = <SPAN CLASS="VariableValue">'%T [%D (%d)] %L %C [%F (%N)] %x%M'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">FMT_LONG</SPAN> = <SPAN CLASS="VariableValue">'%T %L %C [%F] %x%M'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">FMT_MEDIUM</SPAN> = <SPAN CLASS="VariableValue">'[ %C.%F ] %D: %M'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">FMT_SHORT</SPAN> = <SPAN CLASS="VariableValue">'%M'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">GREEN</SPAN> = <SPAN CLASS="VariableValue">32</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">LOGLEVEL_DEBUG</SPAN> = <SPAN CLASS="VariableValue">16</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">LOGLEVEL_ERROR</SPAN> = <SPAN CLASS="VariableValue">2</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">LOGLEVEL_NONE</SPAN> = <SPAN CLASS="VariableValue">1</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">LOGLEVEL_NORMAL</SPAN> = <SPAN CLASS="VariableValue">4</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">LOGLEVEL_VERBOSE</SPAN> = <SPAN CLASS="VariableValue">8</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">dictionary</SPAN> <SPAN CLASS="VariableName">LOG_COLORS</SPAN> = <SPAN CLASS="VariableValue">{1: [37, 30, 'FALSE'], 2: [37, 30, 'FALSE'], 4: [37, 30, 'TRUE'], 8: [37, 30, 'FALSE']}</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">dictionary</SPAN> <SPAN CLASS="VariableName">LOG_LEVELS</SPAN> = <SPAN CLASS="VariableValue">{'DEBUG': 16, 'ERROR': 2, 'NONE': 1, 'NORMAL': 4}</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">dictionary</SPAN> <SPAN CLASS="VariableName">LOG_MSG</SPAN> = <SPAN CLASS="VariableValue">{1: 'DEBUG', 2: 'WARNING', 4: 'ERROR', 8: 'INFO'}</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">MSG_DEBUG</SPAN> = <SPAN CLASS="VariableValue">1</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">MSG_ERROR</SPAN> = <SPAN CLASS="VariableValue">4</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">MSG_INFO</SPAN> = <SPAN CLASS="VariableValue">8</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">MSG_WARN</SPAN> = <SPAN CLASS="VariableValue">2</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">PURPLE</SPAN> = <SPAN CLASS="VariableValue">35</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">RED</SPAN> = <SPAN CLASS="VariableValue">31</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">ROTATE_DAILY</SPAN> = <SPAN CLASS="VariableValue">1</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">ROTATE_MONTHLY</SPAN> = <SPAN CLASS="VariableValue">3</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">ROTATE_NONE</SPAN> = <SPAN CLASS="VariableValue">0</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">ROTATE_WEEKLY</SPAN> = <SPAN CLASS="VariableValue">2</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">SECTION_DEFAULT</SPAN> = <SPAN CLASS="VariableValue">'Default'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">list</SPAN> <SPAN CLASS="VariableName">SPECIAL_TARGETS</SPAN> = <SPAN CLASS="VariableValue">['MySQL', 'Postgres', 'Syslog', 'sys.stdout', 'sys.stderr', 'stdout', ...]</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">TARGET_MYSQL</SPAN> = <SPAN CLASS="VariableValue">'MySQL'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">TARGET_POSTGRES</SPAN> = <SPAN CLASS="VariableValue">'Postgres'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">TARGET_SYSLOG</SPAN> = <SPAN CLASS="VariableValue">'Syslog'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">TARGET_SYS_STDERR</SPAN> = <SPAN CLASS="VariableValue">'sys.stderr'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">TARGET_SYS_STDERR_ALIAS</SPAN> = <SPAN CLASS="VariableValue">'stderr'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">TARGET_SYS_STDOUT</SPAN> = <SPAN CLASS="VariableValue">'sys.stdout'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">TARGET_SYS_STDOUT_ALIAS</SPAN> = <SPAN CLASS="VariableValue">'stdout'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">TRUE</SPAN> = <SPAN CLASS="VariableValue">'TRUE'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">WHITE</SPAN> = <SPAN CLASS="VariableValue">37</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">int</SPAN> <SPAN CLASS="VariableName">YELLOW</SPAN> = <SPAN CLASS="VariableValue">33</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">__file__</SPAN> = <SPAN CLASS="VariableValue">'/home/preisl/Software/Log4Py/log4py.py'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="VariableHead"><SPAN CLASS="VariableType">string</SPAN> <SPAN CLASS="VariableName">mysql_available</SPAN> = <SPAN CLASS="VariableValue">'FALSE'</SPAN></SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">alias</SPAN> <SPAN CLASS="AliasName">ClassType</SPAN> = <SPAN CLASS="AliasFor">class (type type)</SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">alias</SPAN> <SPAN CLASS="AliasName">FileType</SPAN> = <SPAN CLASS="AliasFor">file (type type)</SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">alias</SPAN> <SPAN CLASS="AliasName">InstanceType</SPAN> = <SPAN CLASS="AliasFor">instance (type type)</SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">alias</SPAN> <SPAN CLASS="AliasName">StringType</SPAN> = <SPAN CLASS="AliasFor">string (type type)</SPAN>
|
|
||||||
<SPAN CLASS="PyKeyword">alias</SPAN> <SPAN CLASS="AliasName">TupleType</SPAN> = <SPAN CLASS="AliasFor">tuple (type type)</SPAN>
|
|
||||||
</PRE><H2>Description</H2><P>
|
|
||||||
Python logging module - Version 1.3</P>
|
|
||||||
|
|
||||||
<H3>Loglevels:</H3>
|
|
||||||
LOGLEVEL_NONE, LOGLEVEL_ERROR, LOGLEVEL_NORMAL, LOGLEVEL_VERBOSE, LOGLEVEL_DEBUG
|
|
||||||
<H3>Format-Parameters:</H3>
|
|
||||||
|
|
||||||
<DL>
|
|
||||||
|
|
||||||
<DT>
|
|
||||||
%C
|
|
||||||
<DD>The name of the current class.
|
|
||||||
<DT>
|
|
||||||
%D
|
|
||||||
<DD>Program duration since program start.
|
|
||||||
<DT>
|
|
||||||
%d
|
|
||||||
<DD>Program duration for the last step (last output).
|
|
||||||
<DT>
|
|
||||||
%F
|
|
||||||
<DD>The name of the current function.
|
|
||||||
<DT>
|
|
||||||
%f
|
|
||||||
<DD>Current filename
|
|
||||||
<DT>
|
|
||||||
%L
|
|
||||||
<DD>Log type (Error, Warning, Debug or Info)
|
|
||||||
<DT>
|
|
||||||
%M
|
|
||||||
<DD>The actual message.
|
|
||||||
<DT>
|
|
||||||
%N
|
|
||||||
<DD>The current line number.
|
|
||||||
<DT>
|
|
||||||
%T
|
|
||||||
<DD>Current time (human readable).
|
|
||||||
<DT>
|
|
||||||
%t
|
|
||||||
<DD>Current time (machine readable)
|
|
||||||
<DT>
|
|
||||||
%U
|
|
||||||
<DD>Current fully qualified module/file.
|
|
||||||
<DT>
|
|
||||||
%u
|
|
||||||
<DD>Current module/file.
|
|
||||||
<DT>
|
|
||||||
%x
|
|
||||||
<DD>NDC (nested diagnostic contexts).
|
|
||||||
</DL>
|
|
||||||
|
|
||||||
<H3>Pre-defined Formats:</H3>
|
|
||||||
|
|
||||||
<DL>
|
|
||||||
|
|
||||||
<DT>
|
|
||||||
FMT_SHORT
|
|
||||||
<DD>%M
|
|
||||||
<DT>
|
|
||||||
FMT_MEDIUM
|
|
||||||
<DD>[ %C.%F ] %D: %M
|
|
||||||
<DT>
|
|
||||||
FMT_LONG
|
|
||||||
<DD>%T %L %C [%F] %x%M
|
|
||||||
<DT>
|
|
||||||
FMT_DEBUG
|
|
||||||
<DD>%T [%D (%d)] %L %C [%F (%N)] %x%M
|
|
||||||
</DL>
|
|
||||||
|
|
||||||
|
|
||||||
<HR noshade>
|
|
||||||
|
|
||||||
<TABLE ALIGN="LEFT">
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<A HREF="http://validator.w3.org/check/referer" TARGET="validate"><IMG BORDER=0 SRC="http://validator.w3.org/images/vh40.gif" ALT="Valid HTML 4.0!" HEIGHT=31 WIDTH=88></A>
|
|
||||||
<A HREF="http://www.w3.org/Style/CSS/Buttons"><IMG ALT="Made with CSS" BORDER=0 WIDTH=88 HEIGHT=31 SRC="http://www.w3.org/Style/CSS/Buttons/mwcos"></A>
|
|
||||||
</TD>
|
|
||||||
<TD STYLE="padding-left: 10">
|
|
||||||
<SPAN CLASS="AUTHOR">Martin Preishuber, <a href="mailto:Martin.Preishuber@eclipt.at">Martin.Preishuber@eclipt.at</a></SPAN><BR>
|
|
||||||
<SPAN CLASS="VERSION">Version 1.3</SPAN>
|
|
||||||
</TD>
|
|
||||||
</TABLE>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,39 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
"""Test class for log4py.
|
|
||||||
|
|
||||||
You should get output like this:
|
|
||||||
--------
|
|
||||||
20-10-2001 21:19 sharedlog.__init__ [DEBUG]- Shared log instantiated
|
|
||||||
20-10-2001 21:19 Main.get_instance [DEBUG]- Instantiated
|
|
||||||
20-10-2001 21:19 Main.Main [INFO]- in main
|
|
||||||
20-10-2001 21:19 c1.get_instance [DEBUG]- Instantiated
|
|
||||||
20-10-2001 21:19 c1.__init__ [INFO]- in c1
|
|
||||||
20-10-2001 21:19 c2.get_instance [DEBUG]- Instantiated
|
|
||||||
20-10-2001 21:19 c2.__init__ [INFO]- in c2
|
|
||||||
20-10-2001 21:19 c1.__init__ [INFO]- in c1
|
|
||||||
--------
|
|
||||||
|
|
||||||
Author: Bruce Kroeze <bruce@zefamily.org>
|
|
||||||
"""
|
|
||||||
|
|
||||||
from log4py import Logger, LOGLEVEL_DEBUG
|
|
||||||
|
|
||||||
class c1:
|
|
||||||
def __init__(self):
|
|
||||||
log = Logger().get_instance(self)
|
|
||||||
log.info("in c1")
|
|
||||||
|
|
||||||
class c2:
|
|
||||||
def __init__(self):
|
|
||||||
log = Logger().get_instance(self)
|
|
||||||
log.info("in c2")
|
|
||||||
|
|
||||||
if (__name__ == '__main__'):
|
|
||||||
log = Logger("$HOME/log4py.conf").get_instance()
|
|
||||||
log.get_root().set_loglevel(LOGLEVEL_DEBUG)
|
|
||||||
log.info("in main")
|
|
||||||
|
|
||||||
a = c1()
|
|
||||||
b = c2()
|
|
||||||
c = c1()
|
|
|
@ -1,86 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
import log4py
|
|
||||||
import sys
|
|
||||||
from os import utime
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
class Log4PyTest:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.log4py = log4py.Logger().get_instance(self)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.log4py.error("error")
|
|
||||||
self.log4py.warn("warn")
|
|
||||||
self.log4py.info("info")
|
|
||||||
self.log4py.debug("debug")
|
|
||||||
|
|
||||||
def output(self, message):
|
|
||||||
self.log4py.info(message)
|
|
||||||
|
|
||||||
mytest = Log4PyTest()
|
|
||||||
|
|
||||||
print "\nSettings from log4py.conf\n"
|
|
||||||
mytest.run()
|
|
||||||
|
|
||||||
print "\nNormal level - Long format (written to $HOME/log4py-test.log)"
|
|
||||||
mytest.log4py.set_target("$HOME/log4py-test.log")
|
|
||||||
mytest.run()
|
|
||||||
mytest.log4py.set_target(sys.stdout)
|
|
||||||
|
|
||||||
print "\nNormal level - Long format (ansi color)\n"
|
|
||||||
mytest.log4py.set_use_ansi_codes(log4py.TRUE)
|
|
||||||
mytest.run()
|
|
||||||
mytest.log4py.set_use_ansi_codes(log4py.FALSE)
|
|
||||||
|
|
||||||
print "\nDebug level - Debug format\n"
|
|
||||||
mytest.log4py.set_formatstring(log4py.FMT_DEBUG)
|
|
||||||
mytest.log4py.set_loglevel(log4py.LOGLEVEL_DEBUG)
|
|
||||||
mytest.run()
|
|
||||||
|
|
||||||
print "\nVerbose level - Medium format\n"
|
|
||||||
mytest.log4py.set_formatstring(log4py.FMT_MEDIUM)
|
|
||||||
mytest.log4py.set_loglevel(log4py.LOGLEVEL_VERBOSE)
|
|
||||||
mytest.run()
|
|
||||||
|
|
||||||
print "\nVerbose level - User defined format\n"
|
|
||||||
mytest.log4py.set_formatstring("[ %u (%F) ] %D: %M")
|
|
||||||
mytest.log4py.set_loglevel(log4py.LOGLEVEL_VERBOSE)
|
|
||||||
mytest.run()
|
|
||||||
|
|
||||||
print "\nNormal, long format - Testing Nested Diagnostic Context\n"
|
|
||||||
mytest.log4py.set_formatstring(log4py.FMT_LONG)
|
|
||||||
mytest.log4py.set_loglevel(log4py.LOGLEVEL_VERBOSE)
|
|
||||||
mytest.log4py.push("ndc1")
|
|
||||||
mytest.output("Should say \"ndc1\"");
|
|
||||||
mytest.log4py.push("ndc2")
|
|
||||||
mytest.output("Should say \"ndc1 ndc2\"");
|
|
||||||
mytest.log4py.pop()
|
|
||||||
mytest.output("Should say \"ndc1\"");
|
|
||||||
mytest.log4py.push("ndc3")
|
|
||||||
mytest.output("Should say \"ndc1 ndc3\"");
|
|
||||||
mytest.log4py.clear_ndc();
|
|
||||||
mytest.output("Should not have any ndc items");
|
|
||||||
|
|
||||||
print "\nTesting MySQL target\n"
|
|
||||||
mytest.log4py.add_target(log4py.TARGET_MYSQL, "localhost", "syslog", "log4py", "mysecretpwd", "logs")
|
|
||||||
mytest.output("hello world")
|
|
||||||
mytest.log4py.remove_target(log4py.TARGET_MYSQL)
|
|
||||||
|
|
||||||
print "\nTesting Syslog target\n"
|
|
||||||
mytest.log4py.add_target(log4py.TARGET_SYSLOG)
|
|
||||||
mytest.run()
|
|
||||||
mytest.log4py.remove_target(log4py.TARGET_SYSLOG)
|
|
||||||
|
|
||||||
print "\nGetting all available targets\n"
|
|
||||||
print mytest.log4py.get_targets()
|
|
||||||
|
|
||||||
print "\nTesting log-file rotation (log4py-rotation.log)\n"
|
|
||||||
mytest.log4py.set_target("log4py-rotation.log")
|
|
||||||
mytest.run()
|
|
||||||
mytest.log4py.set_rotation(log4py.ROTATE_DAILY)
|
|
||||||
yesterday = time() - 60 * 60 * 24
|
|
||||||
utime("log4py-rotation.log", (yesterday, yesterday))
|
|
||||||
mytest.run()
|
|
||||||
mytest.log4py.set_target(sys.stdout)
|
|
|
@ -1,65 +0,0 @@
|
||||||
# Log4Py configuration file
|
|
||||||
#
|
|
||||||
# The "Default" Sections contains default settings which can be overwritten
|
|
||||||
# by settings for different instances (see bottom of file)
|
|
||||||
|
|
||||||
[Default]
|
|
||||||
|
|
||||||
# Format is the output format of the lines.
|
|
||||||
#
|
|
||||||
# Possible parameters are:
|
|
||||||
#
|
|
||||||
# %C ..... class-name
|
|
||||||
# %D ..... program duration
|
|
||||||
# %d ..... duration for the last step (last output)
|
|
||||||
# %F ..... function name
|
|
||||||
# %L ..... logtype (Error, Warning, ...)
|
|
||||||
# %M ..... message
|
|
||||||
# %N ..... Line-number
|
|
||||||
# %T ..... current time
|
|
||||||
#
|
|
||||||
# Example formats are:
|
|
||||||
#
|
|
||||||
# Short: %M
|
|
||||||
# Medium: [ %C.%F ] %D: %M
|
|
||||||
# Long (default): %T %L %C [%F] - %M
|
|
||||||
# Debug: %T [%D (%d)] %L %C [%F (%N)] - %M
|
|
||||||
|
|
||||||
Format: %T %L %C [%F] - %M
|
|
||||||
|
|
||||||
# Target controls the output medium of the logging
|
|
||||||
#
|
|
||||||
# Possible values are:
|
|
||||||
#
|
|
||||||
# stdout (default): Standard output stream
|
|
||||||
# stderr: Error stream
|
|
||||||
# <filename> Any other filename
|
|
||||||
#
|
|
||||||
# Multiple targets can be specified as comma seperated list
|
|
||||||
|
|
||||||
Target: stdout
|
|
||||||
|
|
||||||
# Use ansi colors. Possible values are True or False (default)
|
|
||||||
|
|
||||||
Ansi: False
|
|
||||||
|
|
||||||
# TimeFormat is the format of the date and time as used by the
|
|
||||||
# Python strftime() function
|
|
||||||
|
|
||||||
# TimeFormat: %d.%m.%Y %H:%M:%S
|
|
||||||
|
|
||||||
# LogLevel controls the level of what you want to see
|
|
||||||
#
|
|
||||||
# Possible values are:
|
|
||||||
#
|
|
||||||
# None: No output (silent mode)
|
|
||||||
# Normal (default): Information- and Errormessages
|
|
||||||
# Verbose: Information-, Error- and Warningmessages
|
|
||||||
# Debug: Information-, Error-, Warning- and Debugmessages
|
|
||||||
|
|
||||||
LogLevel: Normal
|
|
||||||
|
|
||||||
# This is a section for the Log4PyTest class.
|
|
||||||
|
|
||||||
[Log4PyTest]
|
|
||||||
LogLevel: Debug
|
|
|
@ -1,593 +0,0 @@
|
||||||
"""
|
|
||||||
|
|
||||||
Python logging module - Version 1.3
|
|
||||||
|
|
||||||
Loglevels:
|
|
||||||
|
|
||||||
LOGLEVEL_NONE, LOGLEVEL_ERROR, LOGLEVEL_NORMAL, LOGLEVEL_VERBOSE, LOGLEVEL_DEBUG
|
|
||||||
|
|
||||||
Format-Parameters:
|
|
||||||
|
|
||||||
%C -- The name of the current class.
|
|
||||||
%D -- Program duration since program start.
|
|
||||||
%d -- Program duration for the last step (last output).
|
|
||||||
%F -- The name of the current function.
|
|
||||||
%f -- Current filename
|
|
||||||
%L -- Log type (Error, Warning, Debug or Info)
|
|
||||||
%M -- The actual message.
|
|
||||||
%N -- The current line number.
|
|
||||||
%T -- Current time (human readable).
|
|
||||||
%t -- Current time (machine readable)
|
|
||||||
%U -- Current fully qualified module/file.
|
|
||||||
%u -- Current module/file.
|
|
||||||
%x -- NDC (nested diagnostic contexts).
|
|
||||||
|
|
||||||
Pre-defined Formats:
|
|
||||||
|
|
||||||
FMT_SHORT -- %M
|
|
||||||
FMT_MEDIUM -- [ %C.%F ] %D: %M
|
|
||||||
FMT_LONG -- %T %L %C [%F] %x%M
|
|
||||||
FMT_DEBUG -- %T [%D (%d)] %L %C [%F (%N)] %x%M
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Logging levels
|
|
||||||
LOGLEVEL_NONE = 1 << 0
|
|
||||||
LOGLEVEL_ERROR = 1 << 1
|
|
||||||
LOGLEVEL_NORMAL = 1 << 2
|
|
||||||
LOGLEVEL_VERBOSE = 1 << 3
|
|
||||||
LOGLEVEL_DEBUG = 1 << 4
|
|
||||||
|
|
||||||
# Pre-defined format strings
|
|
||||||
FMT_SHORT = "%M"
|
|
||||||
FMT_MEDIUM = "[ %C.%F ] %D: %M"
|
|
||||||
FMT_LONG = "%T %L %C [%F] %x%M"
|
|
||||||
FMT_DEBUG = "%T [%D (%d)] %L %C [%F (%N)] %x%M"
|
|
||||||
|
|
||||||
# Special logging targets
|
|
||||||
TARGET_MYSQL = "MySQL"
|
|
||||||
TARGET_POSTGRES = "Postgres"
|
|
||||||
TARGET_SYSLOG = "Syslog"
|
|
||||||
TARGET_SYS_STDOUT = "sys.stdout"
|
|
||||||
TARGET_SYS_STDERR = "sys.stderr"
|
|
||||||
TARGET_SYS_STDOUT_ALIAS = "stdout"
|
|
||||||
TARGET_SYS_STDERR_ALIAS = "stderr"
|
|
||||||
|
|
||||||
SPECIAL_TARGETS = [ TARGET_MYSQL, TARGET_POSTGRES, TARGET_SYSLOG, TARGET_SYS_STDOUT, TARGET_SYS_STDERR, TARGET_SYS_STDOUT_ALIAS, TARGET_SYS_STDERR_ALIAS ]
|
|
||||||
|
|
||||||
# Configuration files
|
|
||||||
CONFIGURATION_FILES = {}
|
|
||||||
CONFIGURATION_FILES[1] = "log4py.conf" # local directory
|
|
||||||
CONFIGURATION_FILES[2] = "$HOME/.log4py.conf" # hidden file in the home directory
|
|
||||||
CONFIGURATION_FILES[3] = "/etc/log4py.conf" # system wide file
|
|
||||||
|
|
||||||
# Constants for the FileAppender
|
|
||||||
ROTATE_NONE = 0
|
|
||||||
ROTATE_DAILY = 1
|
|
||||||
ROTATE_WEEKLY = 2
|
|
||||||
ROTATE_MONTHLY = 3
|
|
||||||
|
|
||||||
# The following constants are of internal interest only
|
|
||||||
|
|
||||||
# Message constants (used for ansi colors and for logtype %L)
|
|
||||||
MSG_DEBUG = 1 << 0
|
|
||||||
MSG_WARN = 1 << 1
|
|
||||||
MSG_ERROR = 1 << 2
|
|
||||||
MSG_INFO = 1 << 3
|
|
||||||
|
|
||||||
# Boolean constants
|
|
||||||
TRUE = "TRUE"
|
|
||||||
FALSE = "FALSE"
|
|
||||||
|
|
||||||
# Color constants
|
|
||||||
BLACK = 30
|
|
||||||
RED = 31
|
|
||||||
GREEN = 32
|
|
||||||
YELLOW = 33
|
|
||||||
BLUE = 34
|
|
||||||
PURPLE = 35
|
|
||||||
AQUA = 36
|
|
||||||
WHITE = 37
|
|
||||||
|
|
||||||
LOG_MSG = { MSG_DEBUG: "DEBUG", MSG_WARN: "WARNING", MSG_ERROR: "ERROR", MSG_INFO: "INFO"}
|
|
||||||
LOG_COLORS = { MSG_DEBUG: [WHITE, BLACK, FALSE], MSG_WARN: [WHITE, BLACK, FALSE], MSG_ERROR: [WHITE, BLACK, TRUE], MSG_INFO: [WHITE, BLACK, FALSE]}
|
|
||||||
LOG_LEVELS = { "DEBUG": LOGLEVEL_DEBUG, "VERBOSE": LOGLEVEL_VERBOSE, "NORMAL": LOGLEVEL_NORMAL, "NONE": LOGLEVEL_NONE, "ERROR": LOGLEVEL_ERROR }
|
|
||||||
|
|
||||||
SECTION_DEFAULT = "Default"
|
|
||||||
|
|
||||||
from time import time, strftime, localtime
|
|
||||||
from types import StringType, ClassType, InstanceType, FileType, TupleType
|
|
||||||
from string import zfill, atoi, lower, upper, join, replace, split, strip
|
|
||||||
from re import sub
|
|
||||||
from ConfigParser import ConfigParser, NoOptionError
|
|
||||||
from os import stat, rename
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
import os
|
|
||||||
import copy
|
|
||||||
import socket
|
|
||||||
import locale
|
|
||||||
if (os.name == "posix"):
|
|
||||||
import syslog
|
|
||||||
|
|
||||||
try:
|
|
||||||
import MySQLdb
|
|
||||||
mysql_available = TRUE
|
|
||||||
except:
|
|
||||||
mysql_available = FALSE
|
|
||||||
|
|
||||||
def get_homedirectory():
|
|
||||||
if (sys.platform == "win32"):
|
|
||||||
if (os.environ.has_key("USERPROFILE")):
|
|
||||||
return os.environ["USERPROFILE"]
|
|
||||||
else:
|
|
||||||
return "C:\\"
|
|
||||||
else:
|
|
||||||
if (os.environ.has_key("HOME")):
|
|
||||||
return os.environ["HOME"]
|
|
||||||
else:
|
|
||||||
# No home directory set
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# This is the main class for the logging module
|
|
||||||
|
|
||||||
class Logger:
|
|
||||||
|
|
||||||
cache = {}
|
|
||||||
instance = None
|
|
||||||
configfiles = []
|
|
||||||
hostname = socket.gethostname()
|
|
||||||
|
|
||||||
def __init__(self, useconfigfiles = TRUE, customconfigfiles = None):
|
|
||||||
""" **(private)** Class initalization & customization. """
|
|
||||||
if (customconfigfiles):
|
|
||||||
if (type(customconfigfiles) == StringType):
|
|
||||||
customconfigfiles = [customconfigfiles]
|
|
||||||
Logger.configfiles = customconfigfiles
|
|
||||||
|
|
||||||
if (not Logger.instance):
|
|
||||||
self.__Logger_setdefaults()
|
|
||||||
if (useconfigfiles == TRUE):
|
|
||||||
self.__Logger_appendconfigfiles(Logger.configfiles)
|
|
||||||
# read the default options
|
|
||||||
self.__Logger_parse_options()
|
|
||||||
|
|
||||||
self.__Logger_timeinit = time()
|
|
||||||
self.__Logger_timelaststep = self.__Logger_timeinit
|
|
||||||
|
|
||||||
Logger.instance = self
|
|
||||||
|
|
||||||
if (useconfigfiles == TRUE):
|
|
||||||
# read and pre-cache settings for named classids
|
|
||||||
self.__Logger_cache_options()
|
|
||||||
|
|
||||||
def get_root(self):
|
|
||||||
""" Provides a way to change the base logger object's properties. """
|
|
||||||
return Logger.instance
|
|
||||||
|
|
||||||
def get_instance(self, classid = "Main", use_cache = TRUE):
|
|
||||||
""" Either get the cached logger instance or create a new one
|
|
||||||
|
|
||||||
Note that this is safe, even if you have your target set to sys.stdout
|
|
||||||
or sys.stderr
|
|
||||||
"""
|
|
||||||
|
|
||||||
cache = Logger.cache
|
|
||||||
|
|
||||||
if (type(classid) == ClassType):
|
|
||||||
classid = classid.__name__
|
|
||||||
elif (type(classid) == InstanceType):
|
|
||||||
classid = classid.__class__.__name__
|
|
||||||
|
|
||||||
# classid has to be lowercase, because the ConfigParser returns sections lowercase
|
|
||||||
classid = lower(classid)
|
|
||||||
|
|
||||||
if ((cache.has_key(classid)) and (use_cache == TRUE)):
|
|
||||||
cat = Logger.cache[classid]
|
|
||||||
else:
|
|
||||||
instance = Logger.instance
|
|
||||||
|
|
||||||
# test for targets which won't deep copy
|
|
||||||
targets = instance.__Logger_targets
|
|
||||||
deepcopyable = TRUE
|
|
||||||
for i in range(len(targets)):
|
|
||||||
if (type(targets[i]) == FileType):
|
|
||||||
deepcopyable = FALSE
|
|
||||||
if (deepcopyable == FALSE):
|
|
||||||
# swap the non-copyable target out for a moment
|
|
||||||
del instance.__Logger_targets
|
|
||||||
cat = copy.deepcopy(instance)
|
|
||||||
instance.__Logger_targets = targets
|
|
||||||
cat.__Logger_targets = targets
|
|
||||||
else:
|
|
||||||
cat = copy.deepcopy(instance)
|
|
||||||
|
|
||||||
cat.__Logger_classname = classid
|
|
||||||
# new categories have their own private Nested Diagnostic Contexts
|
|
||||||
self.__Logger_ndc = []
|
|
||||||
self.__Logger_classid = classid
|
|
||||||
|
|
||||||
cat.debug("Class %s instantiated" % classid)
|
|
||||||
if (use_cache == TRUE):
|
|
||||||
cache[classid] = cat
|
|
||||||
|
|
||||||
return cat
|
|
||||||
|
|
||||||
# Log-target handling (add, remove, set, remove_all)
|
|
||||||
|
|
||||||
def add_target(self, target, *args):
|
|
||||||
""" Add a target to the logger targets. """
|
|
||||||
if (not target in self.__Logger_targets):
|
|
||||||
if (target == TARGET_MYSQL):
|
|
||||||
if (mysql_available == TRUE):
|
|
||||||
# Required parameters: dbhost, dbname, dbuser, dbpass, dbtable
|
|
||||||
try:
|
|
||||||
self.__Logger_mysql_connection = MySQLdb.connect(host=args[0], db=args[1], user=args[2], passwd=args[3])
|
|
||||||
self.__Logger_mysql_cursor = self.__Logger_mysql_connection.cursor()
|
|
||||||
self.__Logger_mysql_tablename = args[4]
|
|
||||||
self.__Logger_targets.append(target)
|
|
||||||
except MySQLdb.OperationalError, detail:
|
|
||||||
self.error("MySQL connection failed: %s" % detail)
|
|
||||||
else:
|
|
||||||
self.error("MySQL target not added - Python-mysql not available")
|
|
||||||
else:
|
|
||||||
if (type(target) == StringType):
|
|
||||||
if (target not in SPECIAL_TARGETS):
|
|
||||||
# This is a filename
|
|
||||||
target = FileAppender(target, self.__Logger_rotation)
|
|
||||||
if ((target == TARGET_SYSLOG) and (os.name != "posix")):
|
|
||||||
self.warn("TARGET_SYSLOG is not available on non-posix platforms!")
|
|
||||||
else:
|
|
||||||
self.__Logger_targets.append(target)
|
|
||||||
|
|
||||||
def remove_target(self, target):
|
|
||||||
""" Remove a target from the logger targets. """
|
|
||||||
if (target in self.__Logger_targets):
|
|
||||||
if (target == TARGET_MYSQL):
|
|
||||||
self.__Logger_mysql_connection.close()
|
|
||||||
self.__Logger_targets.remove(target)
|
|
||||||
|
|
||||||
def set_target(self, target):
|
|
||||||
""" Set a single target. """
|
|
||||||
if (type(target) == StringType):
|
|
||||||
if (target not in SPECIAL_TARGETS):
|
|
||||||
# File target
|
|
||||||
target = FileAppender(target, self.__Logger_rotation)
|
|
||||||
self.__Logger_targets = [ target ]
|
|
||||||
|
|
||||||
def remove_all_targets(self):
|
|
||||||
""" Remove all targets from the logger targets. """
|
|
||||||
self.__Logger_targets=[]
|
|
||||||
|
|
||||||
def get_targets(self):
|
|
||||||
""" Returns all defined targets. """
|
|
||||||
return self.__Logger_targets
|
|
||||||
|
|
||||||
# Methods to set properties
|
|
||||||
|
|
||||||
def set_loglevel(self, loglevel):
|
|
||||||
""" Set the loglevel for the current instance. """
|
|
||||||
self.__Logger_loglevel = loglevel
|
|
||||||
|
|
||||||
def set_formatstring(self, formatstring):
|
|
||||||
""" Set a format string. """
|
|
||||||
self.__Logger_formatstring = formatstring
|
|
||||||
|
|
||||||
def set_use_ansi_codes(self, useansicodes):
|
|
||||||
""" Use ansi codes for output to the console (TRUE or FALSE). """
|
|
||||||
self.__Logger_useansicodes = useansicodes
|
|
||||||
|
|
||||||
def set_time_format(self, timeformat):
|
|
||||||
""" Set the time format (default: loaded from the system locale). """
|
|
||||||
self.__Logger_timeformat = timeformat
|
|
||||||
|
|
||||||
def set_rotation(self, rotation):
|
|
||||||
""" Set the file rotation mode to one of ROTATE_NONE, ROTATE_DAILY, ROTATE_WEEKLY, ROTATE_MONTHLY """
|
|
||||||
self.__Logger_rotation = rotation
|
|
||||||
for i in range(len(self.__Logger_targets)):
|
|
||||||
target = self.__Logger_targets[i]
|
|
||||||
if (isinstance(target, FileAppender)):
|
|
||||||
target.set_rotation(rotation)
|
|
||||||
|
|
||||||
# Method to get properties
|
|
||||||
|
|
||||||
def get_loglevel(self):
|
|
||||||
""" Returns the current loglevel. """
|
|
||||||
return self.__Logger_loglevel
|
|
||||||
|
|
||||||
def get_formatstring(self):
|
|
||||||
""" Returns the current format string. """
|
|
||||||
return self.__Logger_formatstring
|
|
||||||
|
|
||||||
def get_use_ansi_codes(self):
|
|
||||||
""" Returns, wether ansi codes are being used or not. """
|
|
||||||
return self.__Logger_useansicodes
|
|
||||||
|
|
||||||
def get_time_format(self):
|
|
||||||
""" Returns the current time format. """
|
|
||||||
return self.__Logger_timeformat
|
|
||||||
|
|
||||||
def get_rotation(self):
|
|
||||||
""" Returns the current rotation setting. """
|
|
||||||
return self.__Logger_rotation
|
|
||||||
|
|
||||||
# Methods to push and pop trace messages for nested contexts
|
|
||||||
|
|
||||||
def push(self, message):
|
|
||||||
""" Add a trace message. """
|
|
||||||
self.__Logger_ndc.append(message)
|
|
||||||
|
|
||||||
def pop(self):
|
|
||||||
""" Remove the topmost trace message. """
|
|
||||||
ct = len(self.__Logger_ndc)
|
|
||||||
if (ct):
|
|
||||||
del(self.__Logger_ndc[ct-1])
|
|
||||||
|
|
||||||
def clear_ndc(self):
|
|
||||||
""" Clears all NDC messages. """
|
|
||||||
self.__Logger_ndc = []
|
|
||||||
|
|
||||||
# Methods to actually print messages
|
|
||||||
|
|
||||||
def debug(self, *messages):
|
|
||||||
""" Write a debug message. """
|
|
||||||
if (self.__Logger_loglevel >= LOGLEVEL_DEBUG):
|
|
||||||
message = self.__Logger_collate_messages(messages)
|
|
||||||
self.__Logger_showmessage(message, MSG_DEBUG)
|
|
||||||
|
|
||||||
def warn(self, *messages):
|
|
||||||
""" Write a warning message. """
|
|
||||||
if (self.__Logger_loglevel >= LOGLEVEL_VERBOSE):
|
|
||||||
message = self.__Logger_collate_messages(messages)
|
|
||||||
self.__Logger_showmessage(message, MSG_WARN)
|
|
||||||
|
|
||||||
def error(self, *messages):
|
|
||||||
""" Write a error message. """
|
|
||||||
if (self.__Logger_loglevel >= LOGLEVEL_ERROR):
|
|
||||||
message = self.__Logger_collate_messages(messages)
|
|
||||||
self.__Logger_showmessage(message, MSG_ERROR)
|
|
||||||
|
|
||||||
def info(self, *messages):
|
|
||||||
""" Write a info message. """
|
|
||||||
if (self.__Logger_loglevel >= LOGLEVEL_NORMAL):
|
|
||||||
message = self.__Logger_collate_messages(messages)
|
|
||||||
self.__Logger_showmessage(message, MSG_INFO)
|
|
||||||
|
|
||||||
# Private methods of the Logger class - you never have to use those directly
|
|
||||||
|
|
||||||
def __Logger_collate_messages(self, messages):
|
|
||||||
""" **(private)** Create a single string from a number of messages. """
|
|
||||||
return strip(reduce(lambda x, y: "%s%s" % (x, y), messages))
|
|
||||||
|
|
||||||
def __Logger_tracestack(self):
|
|
||||||
""" **(private)** Analyze traceback stack and set linenumber and functionname. """
|
|
||||||
stack = traceback.extract_stack()
|
|
||||||
self.__Logger_module = stack[-4][0]
|
|
||||||
self.__Logger_linenumber = stack[-4][1]
|
|
||||||
self.__Logger_functionname = stack[-4][2]
|
|
||||||
self.__Logger_filename = stack[-4][0]
|
|
||||||
if (self.__Logger_functionname == "?"):
|
|
||||||
self.__Logger_functionname = "Main"
|
|
||||||
|
|
||||||
def __Logger_setdefaults(self):
|
|
||||||
""" **(private)** Set default values for internal variables. """
|
|
||||||
locale.setlocale(locale.LC_ALL)
|
|
||||||
self.__Logger_classid = None
|
|
||||||
self.__Logger_targets = [ TARGET_SYS_STDOUT ] # default target = sys.stdout
|
|
||||||
self.__Logger_formatstring = FMT_LONG
|
|
||||||
self.__Logger_loglevel = LOGLEVEL_NORMAL
|
|
||||||
self.__Logger_rotation = ROTATE_NONE
|
|
||||||
self.__Logger_useansicodes = FALSE
|
|
||||||
self.__Logger_functionname = ""
|
|
||||||
self.__Logger_filename = ""
|
|
||||||
self.__Logger_linenumber = -1
|
|
||||||
try:
|
|
||||||
self.__Logger_timeformat = "%s %s" % (locale.nl_langinfo(locale.D_FMT), locale.nl_langinfo(locale.T_FMT))
|
|
||||||
except (AttributeError):
|
|
||||||
self.__Logger_timeformat = "%d.%m.%Y %H:%M:%S"
|
|
||||||
self.__Logger_classname = None
|
|
||||||
self.__Logger_configfilename = ""
|
|
||||||
self.__Logger_module = ""
|
|
||||||
self.__Logger_ndc = [] # ndc = Nested Diagnostic Context
|
|
||||||
|
|
||||||
def __Logger_find_config(self):
|
|
||||||
""" **(private)** Search for configuration files. """
|
|
||||||
if (not self.__Logger_configfilename):
|
|
||||||
priorities = CONFIGURATION_FILES.keys()
|
|
||||||
priorities.sort()
|
|
||||||
configfilename = ""
|
|
||||||
for i in range(len(priorities)):
|
|
||||||
filename = CONFIGURATION_FILES[priorities[i]]
|
|
||||||
home_directory = get_homedirectory()
|
|
||||||
if (os.sep == "\\"):
|
|
||||||
home_directory = replace(home_directory, "\\", "\\\\")
|
|
||||||
filename = sub("\$HOME", home_directory, filename)
|
|
||||||
if (os.path.exists(filename)):
|
|
||||||
configfilename = filename
|
|
||||||
break
|
|
||||||
self.__Logger_configfilename = configfilename
|
|
||||||
return self.__Logger_configfilename
|
|
||||||
|
|
||||||
def __Logger_parse_options(self, section = SECTION_DEFAULT):
|
|
||||||
""" **(private)** Parse main options from config file. """
|
|
||||||
configfilename = self.__Logger_find_config()
|
|
||||||
|
|
||||||
if (configfilename != ""):
|
|
||||||
parser = ConfigParser()
|
|
||||||
parser.read(configfilename)
|
|
||||||
self.__Logger_set_instance_options(parser, section, self)
|
|
||||||
return TRUE
|
|
||||||
|
|
||||||
def __Logger_set_instance_options(self, parser, section, instance):
|
|
||||||
""" **(private)** Set the options for a given instance from the parser section """
|
|
||||||
|
|
||||||
for i in range(len(parser.options(section))):
|
|
||||||
option = lower(parser.options(section)[i])
|
|
||||||
value = parser.get(section, option)
|
|
||||||
if (option == "format"):
|
|
||||||
instance.set_formatstring(value)
|
|
||||||
elif (option == "timeformat"):
|
|
||||||
instance.set_time_format(value)
|
|
||||||
elif (option == "ansi"):
|
|
||||||
instance.set_use_ansi_codes(upper(value))
|
|
||||||
elif (option == "loglevel"):
|
|
||||||
instance.set_loglevel(LOG_LEVELS[upper(value)])
|
|
||||||
elif (option == "target"):
|
|
||||||
splitted = split(value, ",")
|
|
||||||
instance.remove_all_targets()
|
|
||||||
for i in range(len(splitted)):
|
|
||||||
instance.add_target(strip(splitted[i]))
|
|
||||||
|
|
||||||
def __Logger_cache_options(self):
|
|
||||||
""" **(private)** Read and cache debug levels for categories from config file. """
|
|
||||||
configfilename = self.__Logger_find_config()
|
|
||||||
|
|
||||||
if (configfilename != ""):
|
|
||||||
parser = ConfigParser()
|
|
||||||
parser.read(configfilename)
|
|
||||||
|
|
||||||
for i in range(len(parser.sections())):
|
|
||||||
section = parser.sections()[i]
|
|
||||||
if (section != SECTION_DEFAULT):
|
|
||||||
instance = self.get_instance(section)
|
|
||||||
self.__Logger_set_instance_options(parser, section, instance)
|
|
||||||
return TRUE
|
|
||||||
|
|
||||||
def __Logger_appendconfigfiles(self, filenames):
|
|
||||||
""" **(private)** Append a filename to the list of configuration files. """
|
|
||||||
filenames.reverse()
|
|
||||||
for i in range(len(filenames)):
|
|
||||||
keys = CONFIGURATION_FILES.keys()
|
|
||||||
CONFIGURATION_FILES[min(keys) - 1] = filenames[i]
|
|
||||||
|
|
||||||
def __Logger_get_ndc(self):
|
|
||||||
""" **(private)** Returns the NDC (nested diagnostic context) joined with single-spaces. """
|
|
||||||
if (len(self.__Logger_ndc)):
|
|
||||||
return join(self.__Logger_ndc)
|
|
||||||
else:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def __Logger_showmessage(self, message, messagesource):
|
|
||||||
""" **(private)** Writes a message to all targets set. """
|
|
||||||
|
|
||||||
if (isinstance(message, Exception)):
|
|
||||||
(exc_type, exc_value, tb) = sys.exc_info()
|
|
||||||
exception_summary = traceback.format_exception(exc_type, exc_value, tb)
|
|
||||||
message = 'Exception caught:\n'
|
|
||||||
for line in exception_summary:
|
|
||||||
message = "%s%s" % (message, line)
|
|
||||||
|
|
||||||
currenttime = time()
|
|
||||||
self.__Logger_tracestack()
|
|
||||||
timedifference = "%.3f" % (currenttime - self.__Logger_timeinit)
|
|
||||||
timedifflaststep = "%.3f" % (currenttime - self.__Logger_timelaststep)
|
|
||||||
self.__Logger_timelaststep = currenttime
|
|
||||||
milliseconds = int(round((currenttime - long(currenttime)) * 1000))
|
|
||||||
timeformat = sub("%S", "%S." + (zfill(milliseconds, 3)), self.__Logger_timeformat)
|
|
||||||
currentformattedtime = strftime(timeformat, localtime(currenttime))
|
|
||||||
|
|
||||||
line = self.__Logger_formatstring
|
|
||||||
line = sub("%C", str(self.__Logger_classname), line)
|
|
||||||
line = sub("%D", timedifference, line)
|
|
||||||
line = sub("%d", timedifflaststep, line)
|
|
||||||
line = sub("%F", self.__Logger_functionname, line)
|
|
||||||
line = sub("%f", self.__Logger_filename, line)
|
|
||||||
line = sub("%U", self.__Logger_module, line)
|
|
||||||
line = sub("%u", os.path.split(self.__Logger_module)[-1], line)
|
|
||||||
ndc = self.__Logger_get_ndc()
|
|
||||||
if (ndc != ""):
|
|
||||||
line = sub("%x", "%s - " % ndc, line)
|
|
||||||
else:
|
|
||||||
line = sub("%x", "", line)
|
|
||||||
message = replace(message, "\\", "\\\\")
|
|
||||||
if (self.__Logger_useansicodes == TRUE):
|
|
||||||
line = sub("%L", self.__Logger_ansi(LOG_MSG[messagesource], messagesource), line)
|
|
||||||
line = sub("%M", self.__Logger_ansi(message, messagesource), line)
|
|
||||||
else:
|
|
||||||
line = sub("%L", LOG_MSG[messagesource], line)
|
|
||||||
line = sub("%M", message, line)
|
|
||||||
line = sub("%N", str(self.__Logger_linenumber), line)
|
|
||||||
line = sub("%T", currentformattedtime, line)
|
|
||||||
line = sub("%t", `currenttime`, line)
|
|
||||||
|
|
||||||
for i in range(len(self.__Logger_targets)):
|
|
||||||
target = self.__Logger_targets[i]
|
|
||||||
if (target == TARGET_MYSQL):
|
|
||||||
sqltime = strftime("'%Y-%m-%d', '%H:%M:%S'", localtime(currenttime))
|
|
||||||
sqlStatement = "INSERT INTO %s (host, facility, level, date, time, program, msg) VALUES ('%s', '%s', '%s', %s, '%s', '%s')" % (self.__Logger_mysql_tablename, self.hostname, self.__Logger_functionname, LOG_MSG[messagesource], sqltime, str(self.__Logger_classname), sub("'", "`", message + " " + ndc))
|
|
||||||
self.__Logger_mysql_cursor.execute(sqlStatement)
|
|
||||||
elif (target == TARGET_SYSLOG):
|
|
||||||
# We don't need time and stuff here
|
|
||||||
syslog.syslog(message)
|
|
||||||
elif (isinstance(target, FileAppender)):
|
|
||||||
target.writeline(line)
|
|
||||||
elif (target == sys.stdout) or (lower(target) == TARGET_SYS_STDOUT) or (lower(target) == TARGET_SYS_STDOUT_ALIAS):
|
|
||||||
sys.stdout.write("%s\n" % line)
|
|
||||||
elif (target == sys.stderr) or (lower(target) == TARGET_SYS_STDERR) or (lower(target) == TARGET_SYS_STDERR_ALIAS):
|
|
||||||
sys.stderr.write("%s\n" % line)
|
|
||||||
else:
|
|
||||||
target.write("%s\n" % line)
|
|
||||||
|
|
||||||
def __Logger_ansi(self, text, messagesource):
|
|
||||||
""" **(private)** Converts plain text to ansi text. """
|
|
||||||
bold = LOG_COLORS[messagesource][2]
|
|
||||||
fg = str(LOG_COLORS[messagesource][0])
|
|
||||||
bg = LOG_COLORS[messagesource][1]
|
|
||||||
if (bold == TRUE):
|
|
||||||
fg = "%s;1" % fg
|
|
||||||
bg = bg + 10
|
|
||||||
text = "\033[%d;%sm%s\033[0m" % (bg, fg, text)
|
|
||||||
return text
|
|
||||||
|
|
||||||
class FileAppender:
|
|
||||||
|
|
||||||
def __init__(self, filename, rotation = ROTATE_NONE):
|
|
||||||
""" **(private)** Class initalization & customization. """
|
|
||||||
self.__FileAppender_filename = sub("\$HOME", get_homedirectory(), filename)
|
|
||||||
self.__FileAppender_filename = os.path.expanduser(self.__FileAppender_filename)
|
|
||||||
self.__FileAppender_filename = os.path.expandvars(self.__FileAppender_filename)
|
|
||||||
self.__FileAppender_rotation = rotation
|
|
||||||
|
|
||||||
def __FileAppender_rotate(self, modification_time):
|
|
||||||
""" **(private)** Check, wether the file has to be rotated yet or not. """
|
|
||||||
if (self.__FileAppender_rotation == ROTATE_DAILY):
|
|
||||||
strftime_mask = "%Y%j"
|
|
||||||
elif (self.__FileAppender_rotation == ROTATE_WEEKLY):
|
|
||||||
strftime_mask = "%Y%W"
|
|
||||||
elif (self.__FileAppender_rotation == ROTATE_MONTHLY):
|
|
||||||
strftime_mask = "%Y%m"
|
|
||||||
return (strftime(strftime_mask, localtime(time())) != strftime(strftime_mask, localtime(modification_time)))
|
|
||||||
|
|
||||||
def __FileAppender_date_string(self, modification_time):
|
|
||||||
""" **(private)** Returns a new filename for the rotated file with the appropriate time included. """
|
|
||||||
if (self.__FileAppender_rotation == ROTATE_DAILY):
|
|
||||||
return strftime("%Y-%m-%d", localtime(modification_time))
|
|
||||||
elif (self.__FileAppender_rotation == ROTATE_WEEKLY):
|
|
||||||
return strftime("%Y-Week %W", localtime(modification_time))
|
|
||||||
elif (self.__FileAppender_rotation == ROTATE_MONTHLY):
|
|
||||||
return strftime("%Y-Month %m", localtime(modification_time))
|
|
||||||
|
|
||||||
def get_rotation(self):
|
|
||||||
""" Returns the current rotation setting. """
|
|
||||||
return self.__FileAppender_rotation
|
|
||||||
|
|
||||||
def set_rotation(self, rotation):
|
|
||||||
""" Set the file rotation mode to one of ROTATE_NONE, ROTATE_DAILY, ROTATE_WEEKLY, ROTATE_MONTHLY """
|
|
||||||
self.__FileAppender_rotation = rotation
|
|
||||||
|
|
||||||
def write(self, text):
|
|
||||||
""" Write some text to the file appender. """
|
|
||||||
if ((os.path.exists(self.__FileAppender_filename)) and (self.__FileAppender_rotation != ROTATE_NONE)):
|
|
||||||
statinfo = stat(self.__FileAppender_filename)
|
|
||||||
if (self.__FileAppender_rotate(statinfo[8])):
|
|
||||||
splitted = os.path.splitext(self.__FileAppender_filename)
|
|
||||||
target_file = "%s-%s%s" % (splitted[0], self.__FileAppender_date_string(statinfo[8]), splitted[1])
|
|
||||||
rename(self.__FileAppender_filename, target_file)
|
|
||||||
file = open(self.__FileAppender_filename, "a")
|
|
||||||
file.write(text)
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
def writeline(self, text):
|
|
||||||
""" Write some text including newline to the file appender. """
|
|
||||||
self.write("%s\n" % text)
|
|
|
@ -1,30 +0,0 @@
|
||||||
Log4Py ReadMe:
|
|
||||||
|
|
||||||
Log4Py is a Python logging module similar to log4j. It supports multiple levels
|
|
||||||
of logging and configurable output (either to stdout/stderr or to files). A
|
|
||||||
list of available format strings and ouput parameters can be found at the
|
|
||||||
beginning of log4py.py.
|
|
||||||
|
|
||||||
Installation:
|
|
||||||
|
|
||||||
Automatic:
|
|
||||||
Using Python's Distutils, you can execute:
|
|
||||||
"python setup.py install"
|
|
||||||
|
|
||||||
Manually:
|
|
||||||
Either copy log4py.py into your project directory or to your site-packages directory.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
from log4py import Logger
|
|
||||||
|
|
||||||
class foo:
|
|
||||||
def __init__(self):
|
|
||||||
cat = Logger().get_instance(self)
|
|
||||||
|
|
||||||
Have a look at log4py-test.py and log4py-classtest.py for examples.
|
|
||||||
For logging to databases, please have a look at the database/ directory
|
|
||||||
|
|
||||||
If you have any comments or questions, don't hesitate to contact me ;-)
|
|
||||||
|
|
||||||
Martin <Martin.Preishuber@eclipt.at>
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
from distutils.core import setup
|
|
||||||
|
|
||||||
setup(name = "log4py",
|
|
||||||
version = "1.3",
|
|
||||||
description = "Python Logging Module",
|
|
||||||
py_modules = ["log4py"],
|
|
||||||
author = "Martin Preishuber <Martin.Preishuber@eclipt.at>"
|
|
||||||
)
|
|
Loading…
Reference in a new issue