1 # -----------------------------------------------------------------------
2 # Copyright (C) 2007 Georgia Public Library Service
3 # Bill Erickson <billserickson@gmail.com>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 # -----------------------------------------------------------------------
16 import traceback, sys, os, re, threading
17 from osrf.const import *
18 LOG_SEMAPHORE = threading.BoundedSemaphore(value=1)
21 LOG_LEVEL = OSRF_LOG_DEBUG
22 LOG_TYPE = OSRF_LOG_TYPE_STDERR
24 FRGX = re.compile('/.*/')
27 def initialize(level, facility=None, logfile=None):
28 """Initialize the logging subsystem."""
29 global LOG_LEVEL, LOG_TYPE, LOG_FILE
37 sys.stderr.write("syslog not found, logging to stderr\n")
40 LOG_TYPE = OSRF_LOG_TYPE_SYSLOG
41 initialize_syslog(facility, level)
45 LOG_TYPE = OSRF_LOG_TYPE_FILE
49 # -----------------------------------------------------------------------
50 # Define wrapper functions for the log levels
51 # -----------------------------------------------------------------------
53 __log(OSRF_LOG_INTERNAL, s)
55 __log(OSRF_LOG_DEBUG, s)
57 __log(OSRF_LOG_INFO, s)
59 __log(OSRF_LOG_WARN, s)
61 __log(OSRF_LOG_ERR, s)
63 def __log(level, msg):
64 """Builds the log message and passes the message off to the logger."""
65 global LOG_LEVEL, LOG_TYPE
70 if level == OSRF_LOG_ERR:
71 sys.stderr.write('ERR ' + msg)
74 if int(level) > int(LOG_LEVEL): return
76 # find the caller info for logging the file and line number
77 tb = traceback.extract_stack(limit=3)
81 if level == OSRF_LOG_INTERNAL:
83 if level == OSRF_LOG_INFO:
85 if level == OSRF_LOG_WARN:
87 if level == OSRF_LOG_ERR:
90 filename = FRGX.sub('', tb[0])
91 msg = '[%s:%d:%s:%s:%s] %s' % (lvl, os.getpid(), filename, tb[1], threading.currentThread().getName(), msg)
93 if LOG_TYPE == OSRF_LOG_TYPE_SYSLOG:
94 __log_syslog(level, msg)
96 if LOG_TYPE == OSRF_LOG_TYPE_FILE:
99 sys.stderr.write("%s\n" % msg)
101 if level == OSRF_LOG_ERR and LOG_TYPE != OSRF_LOG_TYPE_STDERR:
102 sys.stderr.write(msg + '\n')
104 def __log_syslog(level, msg):
105 ''' Logs the message to syslog '''
108 slvl = syslog.LOG_DEBUG
109 if level == OSRF_LOG_INTERNAL:
110 slvl = syslog.LOG_DEBUG
111 if level == OSRF_LOG_INFO:
112 slvl = syslog.LOG_INFO
113 if level == OSRF_LOG_WARN:
114 slvl = syslog.LOG_WARNING
115 if level == OSRF_LOG_ERR:
116 slvl = syslog.LOG_ERR
118 syslog.syslog(slvl, msg)
121 ''' Logs the message to a file. '''
123 global LOG_FILE, LOG_TYPE
127 logfile = open(LOG_FILE, 'a')
129 sys.stderr.write("cannot open log file for writing: %s\n", LOG_FILE)
130 LOG_TYPE = OSRF_LOG_TYPE_STDERR
133 LOG_SEMAPHORE.acquire()
134 logfile.write("%s\n" % msg)
136 LOG_SEMAPHORE.release()
140 def initialize_syslog(facility, level):
141 """Connect to syslog and set the logmask based on the level provided."""
146 if facility == 'local0':
147 facility = syslog.LOG_LOCAL0
148 if facility == 'local1':
149 facility = syslog.LOG_LOCAL1
150 if facility == 'local2':
151 facility = syslog.LOG_LOCAL2
152 if facility == 'local3':
153 facility = syslog.LOG_LOCAL3
154 if facility == 'local4':
155 facility = syslog.LOG_LOCAL4
156 if facility == 'local5':
157 facility = syslog.LOG_LOCAL5
158 if facility == 'local6':
159 facility = syslog.LOG_LOCAL6
160 # add other facility maps if necessary...
162 syslog.openlog(sys.argv[0], 0, facility)