Browse Source

add standard python logging

main
Julien Iguchi-Cartigny 10 years ago
parent
commit
5738c94170
3 changed files with 4 additions and 302 deletions
  1. +2
    -2
      wstools/Utility.py
  2. +2
    -2
      wstools/XMLSchema.py
  3. +0
    -298
      wstools/logging.py

+ 2
- 2
wstools/Utility.py View File

@@ -108,8 +108,8 @@ class DOMException(Exception):

class Base:
"""Base class for instance level Logging"""
def __init__(self, module=__name__):
self.logger = logging.getLogger('%s-%s(%s)' % (module, self.__class__, _get_idstr(self)))
def __init__(self, logger = None):
self.logger = logger or logging.getLogger(__name__)


class HTTPResponse:


+ 2
- 2
wstools/XMLSchema.py View File

@@ -1029,7 +1029,7 @@ class XMLSchema(XMLSchemaComponent):
empty_namespace = ''
tag = 'schema'

def __init__(self, parent=None):
def __init__(self, parent=None, logger=None):
"""parent --
instance variables:
targetNamespace -- schema's declared targetNamespace, or empty string.
@@ -1067,7 +1067,7 @@ class XMLSchema(XMLSchemaComponent):
self._imported_schemas = {}
self._included_schemas = {}
self._base_url = None
self.logger = logging.getLogger('wstools')
self.logger = logger or logging.getLogger(__name__)

def getNode(self):
"""


+ 0
- 298
wstools/logging.py View File

@@ -1,298 +0,0 @@
# Copyright (c) 2003, The Regents of the University of California,
# through Lawrence Berkeley National Laboratory (subject to receipt of
# any required approvals from the U.S. Dept. of Energy). All rights
# reserved.
#
"""Logging"""
ident = "$Id$"
import os
import sys

WARN = 1
DEBUG = 2


class ILogger:
'''Logger interface, by default this class
will be used and logging calls are no-ops.
'''
level = 0

def __init__(self, msg):
return

def warning(self, *args, **kw):
return

def debug(self, *args, **kw):
return

def error(self, *args, **kw):
return

def setLevel(cls, level):
cls.level = level
setLevel = classmethod(setLevel)

debugOn = lambda self: self.level >= DEBUG
warnOn = lambda self: self.level >= WARN


class BasicLogger(ILogger):
last = ''

def __init__(self, msg, out=sys.stdout):
self.msg, self.out = msg, out

def warning(self, msg, *args, **kw):
if self.warnOn() is False:
return
if BasicLogger.last != self.msg:
BasicLogger.last = self.msg
print >>self, "---- ", self.msg, " ----"
print >>self, " %s " % self.WARN,
print >>self, msg % args
WARN = '[WARN]'

def debug(self, msg, *args, **kw):
if self.debugOn() is False:
return
if BasicLogger.last != self.msg:
BasicLogger.last = self.msg
print >>self, "---- ", self.msg, " ----"
print >>self, " %s " % self.DEBUG,
print >>self, msg % args
DEBUG = '[DEBUG]'

def error(self, msg, *args, **kw):
if BasicLogger.last != self.msg:
BasicLogger.last = self.msg
print >>self, "---- ", self.msg, " ----"
print >>self, " %s " % self.ERROR,
print >>self, msg % args
ERROR = '[ERROR]'

def write(self, *args):
'''Write convenience function; writes strings.
'''
for s in args:
self.out.write(s)
event = ''.join(*args)


_LoggerClass = BasicLogger


class GridLogger(ILogger):
def debug(self, msg, *args, **kw):
kw['component'] = self.msg
gridLog(event=msg % args, level='DEBUG', **kw)

def warning(self, msg, *args, **kw):
kw['component'] = self.msg
gridLog(event=msg % args, level='WARNING', **kw)

def error(self, msg, *args, **kw):
kw['component'] = self.msg
gridLog(event=msg % args, level='ERROR', **kw)


#
# Registry of send functions for gridLog
#
GLRegistry = {}


class GLRecord(dict):
"""Grid Logging Best Practices Record, Distributed Logging Utilities

The following names are reserved:

event -- log event name
Below is EBNF for the event name part of a log message.
name = <nodot> ( "." <name> )?
nodot = {RFC3896-chars except "."}

Suffixes:
start: Immediately before the first action in a task.
end: Immediately after the last action in a task (that succeeded).
error: an error condition that does not correspond to an end event.

ts -- timestamp
level -- logging level (see levels below)
status -- integer status code
gid -- global grid identifier
gid, cgid -- parent/child identifiers
prog -- program name


More info: http://www.cedps.net/wiki/index.php/LoggingBestPractices#Python

reserved -- list of reserved names,
omitname -- list of reserved names, output only values ('ts', 'event',)
levels -- dict of levels and description
"""
reserved = ('ts', 'event', 'level', 'status', 'gid', 'prog')
omitname = ()
levels = dict(FATAL='Component cannot continue, or system is unusable.',
ALERT='Action must be taken immediately.',
CRITICAL='Critical conditions (on the system).',
ERROR='Errors in the component; not errors from elsewhere.',
WARNING='Problems that are recovered from, usually.',
NOTICE='Normal but significant condition.',
INFO='Informational messages that would be useful to a deployer or administrator.',
DEBUG='Lower level information concerning program logic decisions, internal state, etc.',
TRACE='Finest granularity, similar to "stepping through" the component or system.',)

def __init__(self, date=None, **kw):
kw['ts'] = date or self.GLDate()
kw['gid'] = kw.get('gid') or os.getpid()
dict.__init__(self, kw)

def __str__(self):
"""
"""
from cStringIO import StringIO
s = StringIO()
n = " "
reserved = self.reserved
omitname = self.omitname
levels = self.levels

for k in (list(filter(lambda i: i in self, reserved)) +
list(filter(lambda i: i not in reserved, self.keys()))
):
v = self[k]
if k in omitname:
s.write("%s " % self.format[type(v)](v))
continue

if k == reserved[2] and v not in levels:
pass

s.write("%s=%s " % (k, self.format[type(v)](v)))

s.write("\n")
return s.getvalue()

class GLDate(str):
"""Grid logging Date Format
all timestamps should all be in the same time zone (UTC).
Grid timestamp value format that is a highly readable variant of the ISO8601 time standard [1]:

YYYY-MM-DDTHH:MM:SS.SSSSSSZ

"""
def __new__(self, args=None):
"""args -- datetime (year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
"""
import datetime
args = args or datetime.datetime.utcnow()
l = (args.year, args.month, args.day, args.hour, args.minute, args.second,
args.microsecond, args.tzinfo or 'Z')

return str.__new__(self, "%04d-%02d-%02dT%02d:%02d:%02d.%06d%s" % l)

format = {int: str, float: lambda x: "%lf" % x, long: str, str: lambda x: x,
unicode: str, GLDate: str, }


def gridLog(**kw):
"""Send GLRecord, Distributed Logging Utilities
If the scheme is passed as a keyword parameter
the value is expected to be a callable function
that takes 2 parameters: url, outputStr

GRIDLOG_ON -- turn grid logging on
GRIDLOG_DEST -- provide URL destination
"""
import os

if not bool(int(os.environ.get('GRIDLOG_ON', 0))):
return

url = os.environ.get('GRIDLOG_DEST')
if url is None:
return

## NOTE: urlparse problem w/customized schemes
try:
scheme = url[:url.find('://')]
send = GLRegistry[scheme]
send(url, str(GLRecord(**kw)), )
except Exception, ex:
print >>sys.stderr, "*** gridLog failed -- %s" % (str(kw))


def sendUDP(url, outputStr):
from socket import socket, AF_INET, SOCK_DGRAM
idx1 = url.find('://') + 3
idx2 = url.find('/', idx1)
if idx2 < idx1:
idx2 = len(url)
netloc = url[idx1:idx2]
host, port = (netloc.split(':') + [80])[0:2]
socket(AF_INET, SOCK_DGRAM).sendto(outputStr, (host, int(port)), )


def writeToFile(url, outputStr):
print >> open(url.split('://')[1], 'a+'), outputStr

GLRegistry["gridlog-udp"] = sendUDP
GLRegistry["file"] = writeToFile


def setBasicLogger():
'''Use Basic Logger.
'''
setLoggerClass(BasicLogger)
BasicLogger.setLevel(0)


def setGridLogger():
'''Use GridLogger for all logging events.
'''
setLoggerClass(GridLogger)


def setBasicLoggerWARN():
'''Use Basic Logger.
'''
setLoggerClass(BasicLogger)
BasicLogger.setLevel(WARN)


def setBasicLoggerDEBUG():
'''Use Basic Logger.
'''
setLoggerClass(BasicLogger)
BasicLogger.setLevel(DEBUG)


def setLoggerClass(loggingClass):
'''Set Logging Class.
'''


def setLoggerClass(loggingClass):
'''Set Logging Class.
'''
assert issubclass(loggingClass, ILogger), 'loggingClass must subclass ILogger'
global _LoggerClass
_LoggerClass = loggingClass


def setLevel(level=0):
'''Set Global Logging Level.
'''
ILogger.level = level


def getLevel():
return ILogger.level


def getLogger(msg):
'''Return instance of Logging class.
'''
return _LoggerClass(msg)

Loading…
Cancel
Save