[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/Logger - FileLogger.py:1.1.2.1 ILogger.py:1.1.2.1 MultiLogger.py:1.1.2.1 ResolvingLogger.py:1.1.2.1 RotatingFileLogger.py:1.1.2.1 SocketLogger.py:1.1.2.1 SyslogLogger.py:1.1.2.1 TailLogger.py:1.1.2.1 UnresolvingLogger.py:1.1.2.1 __init__.py:1.1.2.1 m_syslog.py:1.1.2.1
Stephan Richter
srichter@cbu.edu
Tue, 2 Apr 2002 00:08:09 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/Server/Logger
In directory cvs.zope.org:/tmp/cvs-serv6290/lib/python/Zope/Server/Logger
Added Files:
Tag: Zope3-Server-Branch
FileLogger.py ILogger.py MultiLogger.py ResolvingLogger.py
RotatingFileLogger.py SocketLogger.py SyslogLogger.py
TailLogger.py UnresolvingLogger.py __init__.py m_syslog.py
Log Message:
Issue 53: Comment
- Created a bunch of interfaces that let us know what is going on.
- Split, updated and zopefied the Logger code.
- Reorganized dir structure in Zope.Server
- HTTP component split up in files (HTTP server works)
- Inserted Shane's skeleton FTP code (since I like his better than mine)
- Took a first cut at the Virtual File System (VFS) by copying and updating
medusa'a old filesys.py code.
=== Added File Zope3/lib/python/Zope/Server/Logger/FileLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: FileLogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
from types import StringType
from ILogger import ILogger
class FileLogger:
"""Simple File Logger
"""
__implements__ = ILogger
def __init__ (self, file, flush=1, mode='a'):
"""pass this either a path or a file object."""
if type(file) is StringType:
if (file == '-'):
import sys
self.file = sys.stdout
else:
self.file = open (file, mode)
else:
self.file = file
self.do_flush = flush
def __repr__ (self):
return '<file logger: %s>' % self.file
def write (self, data):
self.file.write (data)
self.maybe_flush()
def writeline (self, line):
self.file.writeline (line)
self.maybe_flush()
def writelines (self, lines):
self.file.writelines (lines)
self.maybe_flush()
def maybe_flush (self):
if self.do_flush:
self.file.flush()
def flush (self):
self.file.flush()
def softspace (self, *args):
pass
############################################################
# Implementation methods for interface
# Zope.Server.Logger.ILogger
def log(self, message):
'See Zope.Server.Logger.ILogger.ILogger'
if message[-1] not in ('\r', '\n'):
self.write (message + '\n')
else:
self.write (message)
#
############################################################
=== Added File Zope3/lib/python/Zope/Server/Logger/ILogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: ILogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
from Interface import Interface
class ILogger(Interface):
"""This interface describes the methods any Logging object has to
implement.
"""
def log(message):
"""Logs the passed message at the appropriate place."""
=== Added File Zope3/lib/python/Zope/Server/Logger/MultiLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: MultiLogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
import asynchat
import socket
import time # these three are for the rotating logger
import os # |
import stat # v
from types import StringType
class MultiLogger:
"""Log to multiple places."""
def __init__ (self, loggers):
self.loggers = loggers
def __repr__ (self):
return '<multi logger: %s>' % (repr(self.loggers))
def log (self, message):
for logger in self.loggers:
logger.log (message)
class ResolvingLogger:
"""Feed (ip, message) combinations into this logger to get a
resolved hostname in front of the message. The message will not
be logged until the PTR request finishes (or fails)."""
def __init__ (self, resolver, logger):
self.resolver = resolver
self.logger = logger
class logger_thunk:
def __init__ (self, message, logger):
self.message = message
self.logger = logger
def __call__ (self, host, ttl, answer):
if not answer:
answer = host
self.logger.log ('%s%s' % (answer, self.message))
def log (self, ip, message):
self.resolver.resolve_ptr (
ip,
self.logger_thunk (
message,
self.logger
)
)
class UnresolvingLogger:
"""Just in case you don't want to resolve"""
def __init__ (self, logger):
self.logger = logger
def log (self, ip, message):
self.logger.log ('%s%s' % (ip, message))
def strip_eol (line):
while line and line[-1] in '\r\n':
line = line[:-1]
return line
class TailLogger:
"""Keep track of the last <size> log messages"""
def __init__ (self, logger, size=500):
self.size = size
self.logger = logger
self.messages = []
def log (self, message):
self.messages.append (strip_eol (message))
if len (self.messages) > self.size:
del self.messages[0]
self.logger.log (message)
=== Added File Zope3/lib/python/Zope/Server/Logger/ResolvingLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: ResolvingLogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
from ILogger import ILogger
class ResolvingLogger:
"""Feed (ip, message) combinations into this logger to get a
resolved hostname in front of the message. The message will not
be logged until the PTR request finishes (or fails)."""
__implements__ = ILogger
def __init__ (self, resolver, logger):
self.resolver = resolver
self.logger = logger
class logger_thunk:
def __init__ (self, message, logger):
self.message = message
self.logger = logger
def __call__ (self, host, ttl, answer):
if not answer:
answer = host
self.logger.log ('%s: %s' % (answer, self.message))
############################################################
# Implementation methods for interface
# Zope.Server.Logger.ILogger
def log(self, ip, message):
'See Zope.Server.Logger.ILogger.ILogger'
self.resolver.resolve_ptr (
ip,
self.logger_thunk (
message,
self.logger
)
)
#
############################################################
=== Added File Zope3/lib/python/Zope/Server/Logger/RotatingFileLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: RotatingFileLogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
import time
import os
import stat
from FileLogger import FileLogger
class RotatingFileLogger(FileLogger):
""" If freq is non-None we back up 'daily', 'weekly', or
'monthly'. Else if maxsize is non-None we back up whenever
the log gets to big. If both are None we never back up.
Like a FileLogger, but it must be attached to a filename.
When the log gets too full, or a certain time has passed, it
backs up the log and starts a new one. Note that backing up
the log is done via 'mv' because anything else (cp, gzip)
would take time, during which medusa would do nothing else.
"""
__implements__ = FileLogger.__implements__
def __init__ (self, file, freq=None, maxsize=None, flush=1, mode='a'):
self.filename = file
self.mode = mode
self.file = open (file, mode)
self.freq = freq
self.maxsize = maxsize
self.rotate_when = self.next_backup(self.freq)
self.do_flush = flush
def __repr__ (self):
return '<rotating-file logger: %s>' % self.file
# We back up at midnight every 1) day, 2) monday, or 3) 1st of month
def next_backup (self, freq):
(yr, mo, day, hr, min, sec, wd, jday, dst) = \
time.localtime(time.time())
if freq == 'daily':
return time.mktime((yr,mo,day+1, 0,0,0, 0,0,-1))
elif freq == 'weekly':
# wd(monday)==0
return time.mktime((yr,mo,day-wd+7, 0,0,0, 0,0,-1))
elif freq == 'monthly':
return time.mktime((yr,mo+1,1, 0,0,0, 0,0,-1))
else:
return None # not a date-based backup
def maybe_flush (self): # rotate first if necessary
self.maybe_rotate()
if self.do_flush: # from file_logger()
self.file.flush()
def maybe_rotate (self):
if self.freq and time.time() > self.rotate_when:
self.rotate()
self.rotate_when = self.next_backup(self.freq)
elif self.maxsize: # rotate when we get too big
try:
if os.stat(self.filename)[stat.ST_SIZE] > self.maxsize:
self.rotate()
except os.error: # file not found, probably
self.rotate() # will create a new file
def rotate (self):
(yr, mo, day, hr, min, sec, wd, jday, dst) = \
time.localtime(time.time())
try:
self.file.close()
newname = '%s.ends%04d%02d%02d' % (self.filename, yr, mo, day)
try:
open(newname, "r").close() # check if file exists
newname = newname + "-%02d%02d%02d" % (hr, min, sec)
except: # YEARMODY is unique
pass
os.rename(self.filename, newname)
self.file = open(self.filename, self.mode)
except:
pass
=== Added File Zope3/lib/python/Zope/Server/Logger/SocketLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: SocketLogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
import asynchat
import socket
from ILogger import ILogger
class SocketLogger (asynchat.async_chat):
"""Log to a stream socket, asynchronously."""
__implements__ = ILogger
def __init__ (self, address):
if type(address) == type(''):
self.create_socket (socket.AF_UNIX, socket.SOCK_STREAM)
else:
self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
self.connect (address)
self.address = address
def __repr__ (self):
return '<socket logger: address=%s>' % (self.address)
############################################################
# Implementation methods for interface
# Zope.Server.Logger.ILogger
def log(self, message):
'See Zope.Server.Logger.ILogger.ILogger'
if message[-2:] != '\r\n':
self.socket.push (message + '\r\n')
else:
self.socket.push (message)
#
############################################################
=== Added File Zope3/lib/python/Zope/Server/Logger/SyslogLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: SyslogLogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
import os
import m_syslog
from ILogger import ILogger
class SyslogLogger(m_syslog.syslog_client):
"""syslog is a line-oriented log protocol - this class would be
appropriate for FTP or HTTP logs, but not for dumping stderr
to.
XXX: a simple safety wrapper that will ensure that the line
sent to syslog is reasonable.
XXX: async version of syslog_client: now, log entries use
blocking send()
"""
__implements__ = ILogger
svc_name = 'zope'
pid_str = str(os.getpid())
def __init__ (self, address, facility='user'):
m_syslog.syslog_client.__init__ (self, address)
self.facility = m_syslog.facility_names[facility]
self.address=address
def __repr__ (self):
return '<syslog logger address=%s>' % (repr(self.address))
############################################################
# Implementation methods for interface
# Zope.Server.Logger.ILogger
def log(self, message):
'See Zope.Server.Logger.ILogger.ILogger'
m_syslog.syslog_client.log (
self,
'%s[%s]: %s' % (self.svc_name, self.pid_str, message),
facility=self.facility,
priority=m_syslog.LOG_INFO
)
#
############################################################
=== Added File Zope3/lib/python/Zope/Server/Logger/TailLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: TailLogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
from ILogger import ILogger
class TailLogger:
"""Keep track of the last <size> log messages"""
__implements__ = ILogger
def __init__ (self, logger, size=500):
self.size = size
self.logger = logger
self.messages = []
############################################################
# Implementation methods for interface
# Zope.Server.Logger.ILogger
def log(self, message):
'See Zope.Server.Logger.ILogger.ILogger'
self.messages.append (strip_eol (message))
if len (self.messages) > self.size:
del self.messages[0]
self.logger.log (message)
#
############################################################
def strip_eol (line):
while line and line[-1] in '\r\n':
line = line[:-1]
return line
=== Added File Zope3/lib/python/Zope/Server/Logger/UnresolvingLogger.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: UnresolvingLogger.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
from ILogger import ILogger
class UnresolvingLogger:
"""Just in case you don't want to resolve"""
__implements__ = ILogger
def __init__ (self, logger):
self.logger = logger
############################################################
# Implementation methods for interface
# Zope.Server.Logger.ILogger
def log(self, ip, message):
'See Zope.Server.Logger.ILogger.ILogger'
self.logger.log ('%s: %s' % (ip, message))
#
############################################################
=== Added File Zope3/lib/python/Zope/Server/Logger/__init__.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: __init__.py,v 1.1.2.1 2002/04/02 05:08:07 srichter Exp $
"""
=== Added File Zope3/lib/python/Zope/Server/Logger/m_syslog.py ===
# -*- Mode: Python; tab-width: 4 -*-
# ======================================================================
# Copyright 1997 by Sam Rushing
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
# copies and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of Sam
# Rushing not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission.
#
# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# ======================================================================
"""socket interface to unix syslog.
On Unix, there are usually two ways of getting to syslog: via a
local unix-domain socket, or via the TCP service.
Usually "/dev/log" is the unix domain socket. This may be different
for other systems.
>>> my_client = syslog_client ('/dev/log')
Otherwise, just use the UDP version, port 514.
>>> my_client = syslog_client (('my_log_host', 514))
On win32, you will have to use the UDP version. Note that
you can use this to log to other hosts (and indeed, multiple
hosts).
This module is not a drop-in replacement for the python
<syslog> extension module - the interface is different.
Usage:
>>> c = syslog_client()
>>> c = syslog_client ('/strange/non_standard_log_location')
>>> c = syslog_client (('other_host.com', 514))
>>> c.log ('testing', facility='local0', priority='debug')
"""
# TODO: support named-pipe syslog.
# [see ftp://sunsite.unc.edu/pub/Linux/system/Daemons/syslog-fifo.tar.z]
# from <linux/sys/syslog.h>:
# ===========================================================================
# priorities/facilities are encoded into a single 32-bit quantity, where the
# bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
# (0-big number). Both the priorities and the facilities map roughly
# one-to-one to strings in the syslogd(8) source code. This mapping is
# included in this file.
#
# priorities (these are ordered)
LOG_EMERG = 0 # system is unusable
LOG_ALERT = 1 # action must be taken immediately
LOG_CRIT = 2 # critical conditions
LOG_ERR = 3 # error conditions
LOG_WARNING = 4 # warning conditions
LOG_NOTICE = 5 # normal but significant condition
LOG_INFO = 6 # informational
LOG_DEBUG = 7 # debug-level messages
# facility codes
LOG_KERN = 0 # kernel messages
LOG_USER = 1 # random user-level messages
LOG_MAIL = 2 # mail system
LOG_DAEMON = 3 # system daemons
LOG_AUTH = 4 # security/authorization messages
LOG_SYSLOG = 5 # messages generated internally by syslogd
LOG_LPR = 6 # line printer subsystem
LOG_NEWS = 7 # network news subsystem
LOG_UUCP = 8 # UUCP subsystem
LOG_CRON = 9 # clock daemon
LOG_AUTHPRIV = 10 # security/authorization messages (private)
# other codes through 15 reserved for system use
LOG_LOCAL0 = 16 # reserved for local use
LOG_LOCAL1 = 17 # reserved for local use
LOG_LOCAL2 = 18 # reserved for local use
LOG_LOCAL3 = 19 # reserved for local use
LOG_LOCAL4 = 20 # reserved for local use
LOG_LOCAL5 = 21 # reserved for local use
LOG_LOCAL6 = 22 # reserved for local use
LOG_LOCAL7 = 23 # reserved for local use
priority_names = {
"alert": LOG_ALERT,
"crit": LOG_CRIT,
"debug": LOG_DEBUG,
"emerg": LOG_EMERG,
"err": LOG_ERR,
"error": LOG_ERR, # DEPRECATED
"info": LOG_INFO,
"notice": LOG_NOTICE,
"panic": LOG_EMERG, # DEPRECATED
"warn": LOG_WARNING, # DEPRECATED
"warning": LOG_WARNING,
}
facility_names = {
"auth": LOG_AUTH,
"authpriv": LOG_AUTHPRIV,
"cron": LOG_CRON,
"daemon": LOG_DAEMON,
"kern": LOG_KERN,
"lpr": LOG_LPR,
"mail": LOG_MAIL,
"news": LOG_NEWS,
"security": LOG_AUTH, # DEPRECATED
"syslog": LOG_SYSLOG,
"user": LOG_USER,
"uucp": LOG_UUCP,
"local0": LOG_LOCAL0,
"local1": LOG_LOCAL1,
"local2": LOG_LOCAL2,
"local3": LOG_LOCAL3,
"local4": LOG_LOCAL4,
"local5": LOG_LOCAL5,
"local6": LOG_LOCAL6,
"local7": LOG_LOCAL7,
}
import socket
class syslog_client:
def __init__ (self, address='/dev/log'):
self.address = address
if type (address) == type(''):
try: # APUE 13.4.2 specifes /dev/log as datagram socket
self.socket = socket.socket( socket.AF_UNIX
, socket.SOCK_DGRAM)
self.socket.connect (address)
except: # older linux may create as stream socket
self.socket = socket.socket( socket.AF_UNIX
, socket.SOCK_STREAM)
self.socket.connect (address)
self.unix = 1
else:
self.socket = socket.socket( socket.AF_INET
, socket.SOCK_DGRAM)
self.unix = 0
log_format_string = '<%d>%s\000'
def log (self, message, facility=LOG_USER, priority=LOG_INFO):
message = self.log_format_string % (
self.encode_priority (facility, priority),
message
)
if self.unix:
self.socket.send (message)
else:
self.socket.sendto (message, self.address)
def encode_priority (self, facility, priority):
if type(facility) == type(''):
facility = facility_names[facility]
if type(priority) == type(''):
priority = priority_names[priority]
return (facility<<3) | priority
def close (self):
if self.unix:
self.socket.close()