]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/python/osrf/log.py
6d6df3c16b3d1ce5113398405037821912bb7389
[OpenSRF.git] / src / python / osrf / log.py
1 # -----------------------------------------------------------------------
2 # Copyright (C) 2007  Georgia Public Library Service
3 # Bill Erickson <billserickson@gmail.com>
4
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.
9
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 # -----------------------------------------------------------------------
15
16 import traceback, sys, os, re, threading
17 from osrf.const import *
18 LOG_SEMAPHORE = threading.BoundedSemaphore(value=1)
19
20
21 LOG_LEVEL = OSRF_LOG_DEBUG
22 LOG_TYPE = OSRF_LOG_TYPE_STDERR
23 LOG_FILE = None
24 FRGX = re.compile('/.*/')
25
26
27 def initialize(level, facility=None, logfile=None):
28     """Initialize the logging subsystem."""
29     global LOG_LEVEL, LOG_TYPE, LOG_FILE
30
31     LOG_LEVEL = level
32
33     if facility: 
34         try:
35             import syslog
36         except ImportError:
37             sys.stderr.write("syslog not found, logging to stderr\n")
38             return
39
40         LOG_TYPE = OSRF_LOG_TYPE_SYSLOG
41         initialize_syslog(facility, level)
42         return
43         
44     if logfile:
45         LOG_TYPE = OSRF_LOG_TYPE_FILE
46         LOG_FILE = logfile
47
48
49 # -----------------------------------------------------------------------
50 # Define wrapper functions for the log levels
51 # -----------------------------------------------------------------------
52 def osrfLogInternal(s):
53     __osrfLog(OSRF_LOG_INTERNAL, s)
54 def logDebug(s):
55     __osrfLog(OSRF_LOG_DEBUG, s)
56 def osrfLogInfo(s):
57     __osrfLog(OSRF_LOG_INFO, s)
58 def osrfLogWarn(s):
59     __osrfLog(OSRF_LOG_WARN, s)
60 def logError(s):
61     __osrfLog(OSRF_LOG_ERR, s)
62
63 def __osrfLog(level, msg):
64     """Builds the log message and passes the message off to the logger."""
65     global LOG_LEVEL, LOG_TYPE
66
67     try:
68         import syslog
69     except:
70         if level == OSRF_LOG_ERR:
71             sys.stderr.write('ERR ' + msg)
72         return
73         
74     if int(level) > int(LOG_LEVEL): return
75
76     # find the caller info for logging the file and line number
77     tb = traceback.extract_stack(limit=3)
78     tb = tb[0]
79     lvl = 'DEBG'
80
81     if level == OSRF_LOG_INTERNAL:
82         lvl = 'INT '
83     if level == OSRF_LOG_INFO:
84         lvl = 'INFO'
85     if level == OSRF_LOG_WARN:
86         lvl = 'WARN'
87     if level == OSRF_LOG_ERR:
88         lvl = 'ERR '
89
90     filename = FRGX.sub('', tb[0])
91     msg = '[%s:%d:%s:%s:%s] %s' % (lvl, os.getpid(), filename, tb[1], threading.currentThread().getName(), msg)
92
93     if LOG_TYPE == OSRF_LOG_TYPE_SYSLOG:
94         __log_syslog(level, msg)
95     else:
96         if LOG_TYPE == OSRF_LOG_TYPE_FILE:
97             __log_file(msg)
98         else:
99             sys.stderr.write("%s\n" % msg)
100
101     if level == OSRF_LOG_ERR and LOG_TYPE != OSRF_LOG_TYPE_STDERR:
102         sys.stderr.write(msg + '\n')
103
104 def __log_syslog(level, msg):
105     ''' Logs the message to syslog '''
106     import syslog
107
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
117
118     syslog.syslog(slvl, msg)
119
120 def __log_file(msg):
121     ''' Logs the message to a file. '''
122
123     global LOG_FILE, LOG_TYPE
124
125     logfile = None
126     try:
127         logfile = open(LOG_FILE, 'a')
128     except:
129         sys.stderr.write("cannot open log file for writing: %s\n", LOG_FILE)
130         LOG_TYPE = OSRF_LOG_TYPE_STDERR
131         return
132     try:
133         LOG_SEMAPHORE.acquire()
134         logfile.write("%s\n" % msg)
135     finally:
136         LOG_SEMAPHORE.release()
137         
138     logfile.close()
139
140 def initialize_syslog(facility, level):
141     """Connect to syslog and set the logmask based on the level provided."""
142
143     import syslog
144     level = int(level)
145
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...
161
162     syslog.openlog(sys.argv[0], 0, facility)
163