1
0
Fork 0

- 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:
Jan Dittberner 2006-02-21 20:22:54 +00:00
parent b7e63e7984
commit 5d6938910c
25 changed files with 16 additions and 2122 deletions

View File

@ -4,10 +4,11 @@
# (c) 2006 Jan Dittberner <jan@dittberner.info>
# $Id$
#
from SOAPpy import SOAPServer
import SOAPpy
import logging
from gvadm import Settings
class GnuviechAdminSOAPServer(SOAPServer):
class SOAPServer(SOAPpy.SOAPServer):
"""
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
available to connected SOAP clients.
"""
SOAPServer.__init__(self, ("127.0.0.1", 8080))
SOAPpy.SOAPServer.__init__(self, Settings.soapaddress)
self.logger = logging.getLogger('GnuviechAdminSOAPServer')
hdlr = logging.FileHandler('soapserver.log')
hdlr.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
@ -41,5 +42,5 @@ class GnuviechAdminSOAPServer(SOAPServer):
self.serve_forever()
if __name__ == "__main__":
server = GnuviechAdminSOAPServer()
server = SOAPServer()
server.main()

View 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.
"""

View File

@ -16,3 +16,6 @@ mailreceiver = 'root@gnuviech.info'
popgroup = 'poponly'
popgroup = 'poponly'
pophome = '/home/mail/'
webhome = '/home/www/'
soapaddress = ('127.0.0.1', 8080);

View File

@ -1,6 +0,0 @@
[Default]
Ansi: false
LogLevel: Normal
[Test]
LogLevel: Debug

View File

@ -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)

View File

@ -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"

View File

@ -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;

View File

@ -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>

View File

@ -1 +0,0 @@
See the file LICENSE in this directory.

View File

@ -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

View File

@ -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.

View File

@ -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>

View File

@ -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>&nbsp;<b>|</b>&nbsp;</td>
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
<td width="100%">&nbsp;</td>
</tr>
</table>
</span>

View File

@ -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>&nbsp;<b>|</b>&nbsp;</td>
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
<td width="100%">&nbsp;</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>

View File

@ -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>&nbsp;<b>|</b>&nbsp;</td>
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
<td width="100%">&nbsp;</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>

View File

@ -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>&nbsp;<b>|</b>&nbsp;</td>
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
<td width="100%">&nbsp;</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 &amp; 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>

View File

@ -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>&nbsp;<b>|</b>&nbsp;</td>
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
<td width="100%">&nbsp;</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 &amp; 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>

View File

@ -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;
}

View File

@ -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>&nbsp;<b>|</b>&nbsp;</td>
<td nowrap><A class="DocLink" HREF="indices.html"><span CLASS="ClassName"><b>Index</b></span></A></td>
<td width="100%">&nbsp;</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>

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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>

View File

@ -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>"
)