]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/python/osrf/log.py
1d7ea712c0c695f107fe5bbea03e89dfcde892bf
[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 logSema = threading.BoundedSemaphore(value=1)
19
20
21 loglevel = OSRF_LOG_DEBUG
22 logtype = OSRF_LOG_TYPE_STDERR
23 logfile = None
24
25 def osrfInitLog(level, facility=None, file=None):
26     """Initialize the logging subsystem."""
27     global loglevel, logtype, logfile
28
29     loglevel = level
30
31     if facility: 
32         try:
33             import syslog
34         except ImportError:
35             sys.stderr.write("syslog not found, logging to stderr\n")
36             return
37
38         logtype = OSRF_LOG_TYPE_SYSLOG
39         osrfInitSyslog(facility, level)
40         return
41         
42     if file:
43         logtype = OSRF_LOG_TYPE_FILE
44         logfile = file
45
46
47 # -----------------------------------------------------------------------
48 # Define wrapper functions for the log levels
49 # -----------------------------------------------------------------------
50 def osrfLogInternal(s): __osrfLog(OSRF_LOG_INTERNAL,s)
51 def osrfLogDebug(s): __osrfLog(OSRF_LOG_DEBUG,s)
52 def osrfLogInfo(s): __osrfLog(OSRF_LOG_INFO,s)
53 def osrfLogWarn(s): __osrfLog(OSRF_LOG_WARN,s)
54 def osrfLogErr(s): __osrfLog(OSRF_LOG_ERR,s)
55
56
57 frgx = re.compile('/.*/')
58
59 def __osrfLog(level, msg):
60     """Builds the log message and passes the message off to the logger."""
61     global loglevel, logtype
62
63     try:
64         import syslog
65     except:
66         if level == OSRF_LOG_ERR:
67             sys.stderr.write('ERR ' + msg)
68         return
69         
70     if int(level) > int(loglevel): return
71
72     # find the caller info for logging the file and line number
73     tb = traceback.extract_stack(limit=3)
74     tb = tb[0]
75     lvl = 'DEBG'
76
77     if level == OSRF_LOG_INTERNAL: lvl = 'INT '
78     if level == OSRF_LOG_INFO: lvl = 'INFO'
79     if level == OSRF_LOG_WARN: lvl = 'WARN'
80     if level == OSRF_LOG_ERR:  lvl = 'ERR '
81
82     file = frgx.sub('',tb[0])
83     msg = '[%s:%d:%s:%s:%s] %s' % (lvl, os.getpid(), file, tb[1], threading.currentThread().getName(), msg)
84
85     if logtype == OSRF_LOG_TYPE_SYSLOG:
86         __logSyslog(level, msg)
87     else:
88         if logtype == OSRF_LOG_TYPE_FILE:
89             __logFile(msg)
90         else:
91             sys.stderr.write("%s\n" % msg)
92
93     if level == OSRF_LOG_ERR and logtype != OSRF_LOG_TYPE_STDERR:
94         sys.stderr.write(msg + '\n')
95
96 def __logSyslog(level, msg):
97     ''' Logs the message to syslog '''
98     import syslog
99
100     slvl = syslog.LOG_DEBUG
101     if level == OSRF_LOG_INTERNAL: slvl=syslog.LOG_DEBUG
102     if level == OSRF_LOG_INFO: slvl = syslog.LOG_INFO
103     if level == OSRF_LOG_WARN: slvl = syslog.LOG_WARNING
104     if level == OSRF_LOG_ERR:  slvl = syslog.LOG_ERR
105
106     syslog.syslog(slvl, msg)
107
108 def __logFile(msg):
109     ''' Logs the message to a file. '''
110
111     global logfile, logtype
112
113     f = None
114     try:
115         f = open(logfile, 'a')
116     except:
117         sys.stderr.write("cannot open log file for writing: %s\n", logfile)
118         logtype = OSRF_LOG_TYPE_STDERR
119         return
120     try:
121         logSema.acquire()
122         f.write("%s\n" % msg)
123     finally:
124         logSema.release()
125         
126     f.close()
127     
128
129
130 def osrfInitSyslog(facility, level):
131     """Connect to syslog and set the logmask based on the level provided."""
132
133     import syslog
134     level = int(level)
135
136     if facility == 'local0': facility = syslog.LOG_LOCAL0
137     if facility == 'local1': facility = syslog.LOG_LOCAL1
138     if facility == 'local2': facility = syslog.LOG_LOCAL2
139     if facility == 'local3': facility = syslog.LOG_LOCAL3
140     if facility == 'local4': facility = syslog.LOG_LOCAL4
141     if facility == 'local5': facility = syslog.LOG_LOCAL5
142     if facility == 'local6': facility = syslog.LOG_LOCAL6
143     # add other facility maps if necessary...
144
145     syslog.openlog(sys.argv[0], 0, facility)
146