9ba9a126d40075afa02af6fc2455ab4d37157dd2
[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
17 from osrf.const import *
18
19 loglevel = 4
20
21 def osrfInitLog(level, facility=None, file=None):
22     """Initialize the logging subsystem."""
23     import syslog
24     global loglevel
25     if facility: 
26         osrfInitSyslog(facility, level)
27         syslog.syslog(syslog.LOG_DEBUG, "syslog initialized")
28     else:
29         if file:
30             sys.stderr.write("\n * file-based logging not implemented yet\n")
31             
32     loglevel = level
33
34
35 # -----------------------------------------------------------------------
36 # Define wrapper functions for the log levels
37 # -----------------------------------------------------------------------
38 def osrfLogInternal(s): __osrfLog(OSRF_LOG_INTERNAL,s)
39 def osrfLogDebug(s): __osrfLog(OSRF_LOG_DEBUG,s)
40 def osrfLogInfo(s): __osrfLog(OSRF_LOG_INFO,s)
41 def osrfLogWarn(s): __osrfLog(OSRF_LOG_WARN,s)
42 def osrfLogErr(s): __osrfLog(OSRF_LOG_ERR,s)
43
44
45 frgx = re.compile('/.*/')
46
47 def __osrfLog(level, msg):
48     """Builds the log message and passes the message off to the logger."""
49
50     try:
51         import syslog
52     except:
53         if level == OSRF_LOG_ERR:
54             sys.stderr.write('ERR ' + msg)
55         return
56         
57     global loglevel
58     if int(level) > int(loglevel): return
59
60     # find the caller info for logging the file and line number
61     tb = traceback.extract_stack(limit=3)
62     tb = tb[0]
63     lvl = 'DEBG'
64     slvl = syslog.LOG_DEBUG
65
66     if level == OSRF_LOG_INTERNAL: lvl = 'INT '; slvl=syslog.LOG_DEBUG
67     if level == OSRF_LOG_INFO: lvl = 'INFO'; slvl=syslog.LOG_INFO
68     if level == OSRF_LOG_WARN: lvl = 'WARN'; slvl=syslog.LOG_WARNING
69     if level == OSRF_LOG_ERR:  lvl = 'ERR '; slvl=syslog.LOG_ERR
70
71
72     # XXX when file logging is implemented, wrap io in a semaphore for thread safety
73
74     file = frgx.sub('',tb[0])
75     msg = '[%s:%d:%s:%s] %s' % (lvl, os.getpid(), file, tb[1], msg)
76     syslog.syslog(slvl, msg)
77
78     if level == OSRF_LOG_ERR:
79         sys.stderr.write(msg + '\n')
80
81
82 def osrfInitSyslog(facility, level):
83     """Connect to syslog and set the logmask based on the level provided."""
84
85     import syslog
86
87     level = int(level)
88
89     if facility == 'local0': facility = syslog.LOG_LOCAL0
90     if facility == 'local1': facility = syslog.LOG_LOCAL1
91     if facility == 'local2': facility = syslog.LOG_LOCAL2
92     if facility == 'local3': facility = syslog.LOG_LOCAL3
93     if facility == 'local4': facility = syslog.LOG_LOCAL4
94     if facility == 'local5': facility = syslog.LOG_LOCAL5
95     if facility == 'local6': facility = syslog.LOG_LOCAL6
96     # XXX add other facility maps if necessary
97     syslog.openlog(sys.argv[0], 0, facility)
98
99     # this is redundant...
100     mask = syslog.LOG_UPTO(syslog.LOG_ERR)
101     if level >= 1: mask |= syslog.LOG_MASK(syslog.LOG_WARNING)
102     if level >= 2: mask |= syslog.LOG_MASK(syslog.LOG_NOTICE)
103     if level >= 3: mask |= syslog.LOG_MASK(syslog.LOG_INFO)
104     if level >= 4: mask |= syslog.LOG_MASK(syslog.LOG_DEBUG)
105     syslog.setlogmask(mask)
106