From 34cb392ffef3d9ddff1bd5b97d4255f937eb51bd Mon Sep 17 00:00:00 2001 From: James Yang Date: Tue, 5 Aug 2008 16:23:14 +0000 Subject: applied logging->logger patch git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@4852 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Logger.py | 155 ++++++++++++++++++++++++++++++++++++++++++ src/lib/Logging.py | 155 ------------------------------------------ src/lib/Server/Admin/Query.py | 4 +- src/lib/__init__.py | 2 +- src/sbin/bcfg2 | 4 +- src/sbin/bcfg2-admin | 4 +- src/sbin/bcfg2-info | 4 +- src/sbin/bcfg2-remote | 4 +- src/sbin/bcfg2-server | 6 +- 9 files changed, 169 insertions(+), 169 deletions(-) create mode 100644 src/lib/Logger.py delete mode 100644 src/lib/Logging.py (limited to 'src') diff --git a/src/lib/Logger.py b/src/lib/Logger.py new file mode 100644 index 000000000..429538090 --- /dev/null +++ b/src/lib/Logger.py @@ -0,0 +1,155 @@ +'''Bcfg2 logging support''' +__revision__ = '$Revision$' + +import copy, fcntl, logging, logging.handlers, math, socket, struct, sys, termios, types + +logging.raiseExceptions=0 + +def print_attributes(attrib): + ''' Add the attributes for an element''' + return ' '.join(['%s="%s"' % data for data in attrib.iteritems()]) + +def print_text(text): + ''' Add text to the output (which will need normalising ''' + charmap = {'<':'<', '>':'>', '&':'&'} + return ''.join([charmap.get(char, char) for char in text]) + '\n' + +def xml_print(element, running_indent=0, indent=4): + ''' Add an element and its children to the return string ''' + if (len(element.getchildren()) == 0) and (not element.text): + ret = (' ' * running_indent) + ret += '<%s %s/>\n' % (element.tag, print_attributes(element.attrib)) + else: + child_indent = running_indent + indent + ret = (' ' * running_indent) + ret += '<%s%s>\n' % (element.tag, print_attributes(element)) + if element.text: + ret += (' '* child_indent) + print_text(element.text) + for child in element.getchildren(): + ret += xml_print(child, child_indent, indent) + ret += (' ' * running_indent) + '\n' % (element.tag) + if element.tail: + ret += (' ' * child_indent) + print_text(element.tail) + return ret + +class TermiosFormatter(logging.Formatter): + '''The termios formatter displays output in a terminal-sensitive fashion''' + + def __init__(self, fmt=None, datefmt=None): + logging.Formatter.__init__(self, fmt, datefmt) + if sys.stdout.isatty(): + # now get termios info + try: + self.width = struct.unpack('hhhh', fcntl.ioctl(0, termios.TIOCGWINSZ, + "\000"*8))[1] + if self.width == 0: + self.width = 80 + except: + self.width = 80 + else: + # output to a pipe + self.width = 32768 + + def format(self, record): + '''format a record for display''' + returns = [] + line_len = self.width + if type(record.msg) in types.StringTypes: + for line in record.msg.split('\n'): + if len(line) <= line_len: + returns.append(line) + else: + inner_lines = int(math.floor(float(len(line)) / line_len))+1 + for i in xrange(inner_lines): + returns.append("%s" % (line[i*line_len:(i+1)*line_len])) + elif type(record.msg) == types.ListType: + if not record.msg: + return '' + record.msg.sort() + msgwidth = self.width + columnWidth = max([len(item) for item in record.msg]) + columns = int(math.floor(float(msgwidth) / (columnWidth+2))) + lines = int(math.ceil(float(len(record.msg)) / columns)) + for lineNumber in xrange(lines): + indices = [idx for idx in [(colNum * lines) + lineNumber + for colNum in range(columns)] if idx < len(record.msg)] + format = (len(indices) * (" %%-%ds " % columnWidth)) + returns.append(format % tuple([record.msg[idx] for idx in indices])) + #elif type(record.msg) == lxml.etree._Element: + # returns.append(str(xml_print(record.msg))) + else: + returns.append(str(record.msg)) + if record.exc_info: + returns.append(self.formatException(record.exc_info)) + return '\n'.join(returns) + +class FragmentingSysLogHandler(logging.handlers.SysLogHandler): + '''This handler fragments messages into chunks smaller than 250 characters''' + + def __init__(self, procname, path, facility): + self.procname = procname + self.unixsocket = False + logging.handlers.SysLogHandler.__init__(self, path, facility) + + def emit(self, record): + '''chunk and deliver records''' + record.name = self.procname + if str(record.msg) > 250: + msgs = [] + error = record.exc_info + record.exc_info = None + msgdata = record.msg + while msgdata: + newrec = copy.deepcopy(record) + newrec.msg = msgdata[:250] + msgs.append(newrec) + msgdata = msgdata[250:] + msgs[0].exc_info = error + else: + msgs = [record] + while msgs: + newrec = msgs.pop() + msg = self.log_format_string % (self.encodePriority(self.facility, + newrec.levelname.lower()), self.format(newrec)) + try: + self.socket.send(msg) + except socket.error: + while True: + try: + if isinstance(self.address, types.TupleType): + self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + else: + self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) + self.socket.connect(self.address) + break + except socket.error: + continue + self.socket.send("Reconnected to syslog") + self.socket.send(msg) + +def setup_logging(procname, to_console=True, to_syslog=True, syslog_facility='daemon', level=0): + '''setup logging for bcfg2 software''' + if hasattr(logging, 'already_setup'): + return + # add the handler to the root logger + if to_console: + console = logging.StreamHandler(sys.stdout) + console.setLevel(logging.DEBUG) + # tell the handler to use this format + console.setFormatter(TermiosFormatter()) + logging.root.addHandler(console) + if to_syslog: + try: + try: + syslog = FragmentingSysLogHandler(procname, '/dev/log', syslog_facility) + except socket.error: + syslog = FragmentingSysLogHandler(procname, ('localhost', 514), syslog_facility) + syslog.setLevel(logging.DEBUG) + syslog.setFormatter(logging.Formatter('%(name)s[%(process)d]: %(message)s')) + logging.root.addHandler(syslog) + except socket.error: + logging.root.error("failed to activate syslogging") + except: + print "Failed to activate syslogging" + logging.root.setLevel(level) + logging.already_setup = True diff --git a/src/lib/Logging.py b/src/lib/Logging.py deleted file mode 100644 index 429538090..000000000 --- a/src/lib/Logging.py +++ /dev/null @@ -1,155 +0,0 @@ -'''Bcfg2 logging support''' -__revision__ = '$Revision$' - -import copy, fcntl, logging, logging.handlers, math, socket, struct, sys, termios, types - -logging.raiseExceptions=0 - -def print_attributes(attrib): - ''' Add the attributes for an element''' - return ' '.join(['%s="%s"' % data for data in attrib.iteritems()]) - -def print_text(text): - ''' Add text to the output (which will need normalising ''' - charmap = {'<':'<', '>':'>', '&':'&'} - return ''.join([charmap.get(char, char) for char in text]) + '\n' - -def xml_print(element, running_indent=0, indent=4): - ''' Add an element and its children to the return string ''' - if (len(element.getchildren()) == 0) and (not element.text): - ret = (' ' * running_indent) - ret += '<%s %s/>\n' % (element.tag, print_attributes(element.attrib)) - else: - child_indent = running_indent + indent - ret = (' ' * running_indent) - ret += '<%s%s>\n' % (element.tag, print_attributes(element)) - if element.text: - ret += (' '* child_indent) + print_text(element.text) - for child in element.getchildren(): - ret += xml_print(child, child_indent, indent) - ret += (' ' * running_indent) + '\n' % (element.tag) - if element.tail: - ret += (' ' * child_indent) + print_text(element.tail) - return ret - -class TermiosFormatter(logging.Formatter): - '''The termios formatter displays output in a terminal-sensitive fashion''' - - def __init__(self, fmt=None, datefmt=None): - logging.Formatter.__init__(self, fmt, datefmt) - if sys.stdout.isatty(): - # now get termios info - try: - self.width = struct.unpack('hhhh', fcntl.ioctl(0, termios.TIOCGWINSZ, - "\000"*8))[1] - if self.width == 0: - self.width = 80 - except: - self.width = 80 - else: - # output to a pipe - self.width = 32768 - - def format(self, record): - '''format a record for display''' - returns = [] - line_len = self.width - if type(record.msg) in types.StringTypes: - for line in record.msg.split('\n'): - if len(line) <= line_len: - returns.append(line) - else: - inner_lines = int(math.floor(float(len(line)) / line_len))+1 - for i in xrange(inner_lines): - returns.append("%s" % (line[i*line_len:(i+1)*line_len])) - elif type(record.msg) == types.ListType: - if not record.msg: - return '' - record.msg.sort() - msgwidth = self.width - columnWidth = max([len(item) for item in record.msg]) - columns = int(math.floor(float(msgwidth) / (columnWidth+2))) - lines = int(math.ceil(float(len(record.msg)) / columns)) - for lineNumber in xrange(lines): - indices = [idx for idx in [(colNum * lines) + lineNumber - for colNum in range(columns)] if idx < len(record.msg)] - format = (len(indices) * (" %%-%ds " % columnWidth)) - returns.append(format % tuple([record.msg[idx] for idx in indices])) - #elif type(record.msg) == lxml.etree._Element: - # returns.append(str(xml_print(record.msg))) - else: - returns.append(str(record.msg)) - if record.exc_info: - returns.append(self.formatException(record.exc_info)) - return '\n'.join(returns) - -class FragmentingSysLogHandler(logging.handlers.SysLogHandler): - '''This handler fragments messages into chunks smaller than 250 characters''' - - def __init__(self, procname, path, facility): - self.procname = procname - self.unixsocket = False - logging.handlers.SysLogHandler.__init__(self, path, facility) - - def emit(self, record): - '''chunk and deliver records''' - record.name = self.procname - if str(record.msg) > 250: - msgs = [] - error = record.exc_info - record.exc_info = None - msgdata = record.msg - while msgdata: - newrec = copy.deepcopy(record) - newrec.msg = msgdata[:250] - msgs.append(newrec) - msgdata = msgdata[250:] - msgs[0].exc_info = error - else: - msgs = [record] - while msgs: - newrec = msgs.pop() - msg = self.log_format_string % (self.encodePriority(self.facility, - newrec.levelname.lower()), self.format(newrec)) - try: - self.socket.send(msg) - except socket.error: - while True: - try: - if isinstance(self.address, types.TupleType): - self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - else: - self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) - self.socket.connect(self.address) - break - except socket.error: - continue - self.socket.send("Reconnected to syslog") - self.socket.send(msg) - -def setup_logging(procname, to_console=True, to_syslog=True, syslog_facility='daemon', level=0): - '''setup logging for bcfg2 software''' - if hasattr(logging, 'already_setup'): - return - # add the handler to the root logger - if to_console: - console = logging.StreamHandler(sys.stdout) - console.setLevel(logging.DEBUG) - # tell the handler to use this format - console.setFormatter(TermiosFormatter()) - logging.root.addHandler(console) - if to_syslog: - try: - try: - syslog = FragmentingSysLogHandler(procname, '/dev/log', syslog_facility) - except socket.error: - syslog = FragmentingSysLogHandler(procname, ('localhost', 514), syslog_facility) - syslog.setLevel(logging.DEBUG) - syslog.setFormatter(logging.Formatter('%(name)s[%(process)d]: %(message)s')) - logging.root.addHandler(syslog) - except socket.error: - logging.root.error("failed to activate syslogging") - except: - print "Failed to activate syslogging" - logging.root.setLevel(level) - logging.already_setup = True diff --git a/src/lib/Server/Admin/Query.py b/src/lib/Server/Admin/Query.py index 999bde5c2..67484083d 100644 --- a/src/lib/Server/Admin/Query.py +++ b/src/lib/Server/Admin/Query.py @@ -1,11 +1,11 @@ -import Bcfg2.Server.Admin, Bcfg2.Logging, logging +import Bcfg2.Server.Admin, Bcfg2.Logger, logging class Query(Bcfg2.Server.Admin.Mode): __shorthelp__ = 'bcfg2-admin query [-n] [-c] [-f filename] g=group p=profile' __longhelp__ = __shorthelp__ + '\n\tQuery clients' def __init__(self, cfile): logging.root.setLevel(100) - Bcfg2.Logging.setup_logging(100, to_console=False, to_syslog=False) + Bcfg2.Logger.setup_logging(100, to_console=False, to_syslog=False) Bcfg2.Server.Admin.Mode.__init__(self, cfile) try: self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(), [], diff --git a/src/lib/__init__.py b/src/lib/__init__.py index 7f771da6f..a6300af89 100644 --- a/src/lib/__init__.py +++ b/src/lib/__init__.py @@ -1,4 +1,4 @@ '''base modules definition''' __revision__ = '$Revision$' -__all__ = ['Server', 'Client', 'Component', 'Logging', 'Options', 'Proxy'] +__all__ = ['Server', 'Client', 'Component', 'Logger', 'Options', 'Proxy'] diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2 index 4757c129d..6f7612b0b 100755 --- a/src/sbin/bcfg2 +++ b/src/sbin/bcfg2 @@ -21,7 +21,7 @@ from Bcfg2.Component import SimpleXMLRPCServer, ComponentInitError, ComponentKey from Bcfg2.tlslite.errors import TLSNoAuthenticationError, TLSFingerprintError import Bcfg2.Proxy -import Bcfg2.Logging +import Bcfg2.Logger logger = logging.getLogger('bcfg2') @@ -134,7 +134,7 @@ class Client: level = 20 if self.setup['debug']: level = 0 - Bcfg2.Logging.setup_logging('bcfg2', to_syslog=False, level=level) + Bcfg2.Logger.setup_logging('bcfg2', to_syslog=False, level=level) self.logger = logging.getLogger('bcfg2') self.logger.debug(self.setup) if 'drivers' in self.setup and self.setup['drivers'] == 'help': diff --git a/src/sbin/bcfg2-admin b/src/sbin/bcfg2-admin index bb44bbc3f..1cc8ca288 100755 --- a/src/sbin/bcfg2-admin +++ b/src/sbin/bcfg2-admin @@ -2,7 +2,7 @@ '''bcfg2-admin is a script that helps to administrate a bcfg2 deployment''' import getopt, logging, sys -import Bcfg2.Server.Core, Bcfg2.Logging, Bcfg2.Options +import Bcfg2.Server.Core, Bcfg2.Logger, Bcfg2.Options log = logging.getLogger('bcfg-admin') @@ -16,7 +16,7 @@ def mode_import(modename): return getattr(mod, modname) if __name__ == '__main__': - Bcfg2.Logging.setup_logging('bcfg2-admin', to_console=True) + Bcfg2.Logger.setup_logging('bcfg2-admin', to_console=True) # Get config file path configfile = Bcfg2.Options.CFILE.default try: diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info index a7163a5fb..96da82bf7 100755 --- a/src/sbin/bcfg2-info +++ b/src/sbin/bcfg2-info @@ -3,7 +3,7 @@ __revision__ = '$Revision$' import copy, logging, lxml.etree, sys, time, cmd -import Bcfg2.Logging, Bcfg2.Server.Core, os +import Bcfg2.Logger, Bcfg2.Server.Core, os import Bcfg2.Server.Plugins.Metadata, Bcfg2.Server.Plugin import Bcfg2.Options @@ -289,7 +289,7 @@ Usage: [quit|exit]""" print cand[0].name if __name__ == '__main__': - Bcfg2.Logging.setup_logging('bcfg2-info', to_syslog=False) + Bcfg2.Logger.setup_logging('bcfg2-info', to_syslog=False) optinfo = { 'configfile': Bcfg2.Options.CFILE, 'help': Bcfg2.Options.HELP, diff --git a/src/sbin/bcfg2-remote b/src/sbin/bcfg2-remote index c33fcfbfe..ee52d6201 100755 --- a/src/sbin/bcfg2-remote +++ b/src/sbin/bcfg2-remote @@ -4,7 +4,7 @@ __revision__ = '$Revision$' from Bcfg2.tlslite.api import parsePEMKey, X509, X509CertChain from xmlrpclib import ServerProxy from Bcfg2.tlslite.integration.XMLRPCTransport import XMLRPCTransport -import Bcfg2.Options, Bcfg2.Logging, logging, socket, sys +import Bcfg2.Options, Bcfg2.Logger, logging, socket, sys if __name__ == '__main__': opts = { @@ -16,7 +16,7 @@ if __name__ == '__main__': } setup = Bcfg2.Options.OptionParser(opts) setup.parse(sys.argv[1:]) - Bcfg2.Logging.setup_logging('bcfg2-remote', + Bcfg2.Logger.setup_logging('bcfg2-remote', to_syslog=False, level=int(setup['debug'])) logger = logging.getLogger('bcfg2-remote') diff --git a/src/sbin/bcfg2-server b/src/sbin/bcfg2-server index 18091d55c..d58c8b45e 100755 --- a/src/sbin/bcfg2-server +++ b/src/sbin/bcfg2-server @@ -10,7 +10,7 @@ from xmlrpclib import Fault from lxml.etree import XML, Element, tostring import logging, select, socket, sys -import Bcfg2.Logging, Bcfg2.Options, Bcfg2.Component, Bcfg2.Daemon +import Bcfg2.Logger, Bcfg2.Options, Bcfg2.Component, Bcfg2.Daemon logger = logging.getLogger('bcfg2-server') @@ -217,10 +217,10 @@ if __name__ == '__main__': level = 0 if setup['daemon']: - Bcfg2.Logging.setup_logging('bcfg2-server', to_console=False, level=level) + Bcfg2.Logger.setup_logging('bcfg2-server', to_console=False, level=level) Bcfg2.Daemon.daemonize(setup['daemon']) else: - Bcfg2.Logging.setup_logging('bcfg2-server', level=level) + Bcfg2.Logger.setup_logging('bcfg2-server', level=level) if not setup['key']: print "No key specified in '%s'" % setup['configfile'] -- cgit v1.2.3-1-g7c22