Statistics
| Branch: | Tag: | Revision:

root / lib / logger.py @ b74159ee

History | View | Annotate | Download (5.8 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Logging for Ganeti
23 a8083063 Iustin Pop

24 a8083063 Iustin Pop
This module abstracts the logging handling away from the rest of the
25 a8083063 Iustin Pop
Ganeti code. It offers some utility functions for easy logging.
26 a8083063 Iustin Pop
"""
27 a8083063 Iustin Pop
28 a8083063 Iustin Pop
# pylint: disable-msg=W0603,C0103
29 a8083063 Iustin Pop
30 a8083063 Iustin Pop
import sys
31 a8083063 Iustin Pop
import logging
32 a8083063 Iustin Pop
import os, os.path
33 a8083063 Iustin Pop
34 a8083063 Iustin Pop
from ganeti import constants
35 a8083063 Iustin Pop
36 a8083063 Iustin Pop
_program = '(unknown)'
37 a8083063 Iustin Pop
_errlog = None
38 a8083063 Iustin Pop
_inflog = None
39 a8083063 Iustin Pop
_dbglog = None
40 a8083063 Iustin Pop
_stdout = None
41 a8083063 Iustin Pop
_stderr = None
42 a8083063 Iustin Pop
_debug = False
43 a8083063 Iustin Pop
44 a8083063 Iustin Pop
45 a8083063 Iustin Pop
def _SetDestination(name, filename, stream=None):
46 a8083063 Iustin Pop
  """Configure the destination for a given logger
47 a8083063 Iustin Pop

48 a8083063 Iustin Pop
  This function configures the logging destination for a given loger.
49 a8083063 Iustin Pop
  Parameters:
50 a8083063 Iustin Pop
    - name: the logger name
51 a8083063 Iustin Pop
    - filename: if not empty, log messages will be written (also) to this file
52 a8083063 Iustin Pop
    - stream: if not none, log messages will be output (also) to this stream
53 a8083063 Iustin Pop

54 a8083063 Iustin Pop
  Returns:
55 a8083063 Iustin Pop
    - the logger identified by the `name` argument
56 a8083063 Iustin Pop
  """
57 a8083063 Iustin Pop
  ret = logging.getLogger(name)
58 a8083063 Iustin Pop
59 a8083063 Iustin Pop
  if filename:
60 a8083063 Iustin Pop
    fmtr = logging.Formatter('%(asctime)s %(message)s')
61 a8083063 Iustin Pop
62 a8083063 Iustin Pop
    hdlr = logging.FileHandler(filename)
63 a8083063 Iustin Pop
    hdlr.setFormatter(fmtr)
64 a8083063 Iustin Pop
    ret.addHandler(hdlr)
65 a8083063 Iustin Pop
66 a8083063 Iustin Pop
  if stream:
67 a8083063 Iustin Pop
    if name in ('error', 'info', 'debug'):
68 a8083063 Iustin Pop
      fmtr = logging.Formatter('%(asctime)s %(message)s')
69 a8083063 Iustin Pop
    else:
70 a8083063 Iustin Pop
      fmtr = logging.Formatter('%(message)s')
71 a8083063 Iustin Pop
    hdlr = logging.StreamHandler(stream)
72 a8083063 Iustin Pop
    hdlr.setFormatter(fmtr)
73 a8083063 Iustin Pop
    ret.addHandler(hdlr)
74 a8083063 Iustin Pop
75 a8083063 Iustin Pop
  ret.setLevel(logging.INFO)
76 a8083063 Iustin Pop
77 a8083063 Iustin Pop
  return ret
78 a8083063 Iustin Pop
79 a8083063 Iustin Pop
80 a8083063 Iustin Pop
def _GenericSetup(program, errfile, inffile, dbgfile,
81 a8083063 Iustin Pop
                  twisted_workaround=False):
82 a8083063 Iustin Pop
  """Configure logging based on arguments
83 a8083063 Iustin Pop

84 a8083063 Iustin Pop
  Arguments:
85 a8083063 Iustin Pop
    - name of program
86 a8083063 Iustin Pop
    - error log filename
87 a8083063 Iustin Pop
    - info log filename
88 a8083063 Iustin Pop
    - debug log filename
89 a8083063 Iustin Pop
    - twisted_workaround: if true, emit all messages to stderr
90 a8083063 Iustin Pop
  """
91 a8083063 Iustin Pop
  global _program
92 a8083063 Iustin Pop
  global _errlog
93 a8083063 Iustin Pop
  global _inflog
94 a8083063 Iustin Pop
  global _dbglog
95 a8083063 Iustin Pop
  global _stdout
96 a8083063 Iustin Pop
  global _stderr
97 a8083063 Iustin Pop
98 a8083063 Iustin Pop
  _program = program
99 a8083063 Iustin Pop
  if twisted_workaround:
100 a8083063 Iustin Pop
    _errlog = _SetDestination('error', None, sys.stderr)
101 a8083063 Iustin Pop
    _inflog = _SetDestination('info', None, sys.stderr)
102 a8083063 Iustin Pop
    _dbglog = _SetDestination('debug', None, sys.stderr)
103 a8083063 Iustin Pop
  else:
104 a8083063 Iustin Pop
    _errlog = _SetDestination('error', errfile)
105 a8083063 Iustin Pop
    _inflog = _SetDestination('info', inffile)
106 a8083063 Iustin Pop
    _dbglog = _SetDestination('debug', dbgfile)
107 a8083063 Iustin Pop
108 a8083063 Iustin Pop
  _stdout = _SetDestination('user', None, sys.stdout)
109 a8083063 Iustin Pop
  _stderr = _SetDestination('stderr', None, sys.stderr)
110 a8083063 Iustin Pop
111 a8083063 Iustin Pop
112 a8083063 Iustin Pop
def SetupLogging(twisted_workaround=False, debug=False, program='ganeti'):
113 a8083063 Iustin Pop
  """Setup logging for ganeti
114 a8083063 Iustin Pop

115 a8083063 Iustin Pop
  On failure, a check is made whether process is run by root or not,
116 a8083063 Iustin Pop
  and an appropriate error message is printed on stderr, then process
117 a8083063 Iustin Pop
  exits.
118 a8083063 Iustin Pop

119 a8083063 Iustin Pop
  This function is just a wraper over `_GenericSetup()` using specific
120 a8083063 Iustin Pop
  arguments.
121 a8083063 Iustin Pop

122 a8083063 Iustin Pop
  Parameter:
123 a8083063 Iustin Pop
    twisted_workaround: passed to `_GenericSetup()`
124 a8083063 Iustin Pop

125 a8083063 Iustin Pop
  """
126 a8083063 Iustin Pop
  try:
127 a8083063 Iustin Pop
    _GenericSetup(program,
128 a8083063 Iustin Pop
                  os.path.join(constants.LOG_DIR, "errors"),
129 a8083063 Iustin Pop
                  os.path.join(constants.LOG_DIR, "info"),
130 a8083063 Iustin Pop
                  os.path.join(constants.LOG_DIR, "debug"),
131 a8083063 Iustin Pop
                  twisted_workaround)
132 a8083063 Iustin Pop
  except IOError:
133 a8083063 Iustin Pop
    # The major reason to end up here is that we're being run as a
134 a8083063 Iustin Pop
    # non-root user.  We might also get here if xen has not been
135 a8083063 Iustin Pop
    # installed properly.  This is not the correct place to enforce
136 a8083063 Iustin Pop
    # being run by root; nevertheless, here makes sense because here
137 a8083063 Iustin Pop
    # is where we first notice it.
138 a8083063 Iustin Pop
    if os.getuid() != 0:
139 a8083063 Iustin Pop
      sys.stderr.write('This program must be run by the superuser.\n')
140 a8083063 Iustin Pop
    else:
141 a8083063 Iustin Pop
      sys.stderr.write('Unable to open log files.  Incomplete system?\n')
142 a8083063 Iustin Pop
143 a8083063 Iustin Pop
    sys.exit(2)
144 a8083063 Iustin Pop
145 a8083063 Iustin Pop
  global _debug
146 a8083063 Iustin Pop
  _debug = debug
147 a8083063 Iustin Pop
148 a8083063 Iustin Pop
149 a8083063 Iustin Pop
def _WriteEntry(log, txt):
150 a8083063 Iustin Pop
  """
151 a8083063 Iustin Pop
  Write a message to a given log.
152 a8083063 Iustin Pop
  Splits multi-line messages up into a series of log writes, to
153 a8083063 Iustin Pop
  keep consistent format on lines in file.
154 a8083063 Iustin Pop

155 a8083063 Iustin Pop
  Parameters:
156 a8083063 Iustin Pop
    - log: the destination log
157 a8083063 Iustin Pop
    - txt: the message
158 a8083063 Iustin Pop

159 a8083063 Iustin Pop
  """
160 a8083063 Iustin Pop
  if log is None:
161 a8083063 Iustin Pop
    sys.stderr.write("Logging system not initialized while processing"
162 a8083063 Iustin Pop
                     " message:\n")
163 a8083063 Iustin Pop
    sys.stderr.write("%s\n" % txt)
164 a8083063 Iustin Pop
    return
165 a8083063 Iustin Pop
166 a8083063 Iustin Pop
  lines = txt.split('\n')
167 a8083063 Iustin Pop
168 a8083063 Iustin Pop
  spaces = ' ' * len(_program) + '| '
169 a8083063 Iustin Pop
170 a8083063 Iustin Pop
  lines = ([ _program + ': ' + lines[0] ] +
171 a8083063 Iustin Pop
           map(lambda a: spaces + a, lines[1:]))
172 a8083063 Iustin Pop
173 a8083063 Iustin Pop
  for line in lines:
174 a8083063 Iustin Pop
    log.log(logging.INFO, line)
175 a8083063 Iustin Pop
176 a8083063 Iustin Pop
177 a8083063 Iustin Pop
def ToStdout(txt):
178 a8083063 Iustin Pop
  """Write a message to stdout only, bypassing the logging system
179 a8083063 Iustin Pop

180 a8083063 Iustin Pop
  Parameters:
181 a8083063 Iustin Pop
    - txt: the message
182 a8083063 Iustin Pop

183 a8083063 Iustin Pop
  """
184 a8083063 Iustin Pop
  sys.stdout.write(txt + '\n')
185 a8083063 Iustin Pop
  sys.stdout.flush()
186 a8083063 Iustin Pop
187 a8083063 Iustin Pop
188 a8083063 Iustin Pop
def ToStderr(txt):
189 a8083063 Iustin Pop
  """Write a message to stderr only, bypassing the logging system
190 a8083063 Iustin Pop

191 a8083063 Iustin Pop
  Parameters:
192 a8083063 Iustin Pop
    - txt: the message
193 a8083063 Iustin Pop

194 a8083063 Iustin Pop
  """
195 a8083063 Iustin Pop
  sys.stderr.write(txt + '\n')
196 a8083063 Iustin Pop
  sys.stderr.flush()
197 a8083063 Iustin Pop
198 a8083063 Iustin Pop
199 a8083063 Iustin Pop
def Error(txt):
200 a8083063 Iustin Pop
  """Write a message to our error log
201 a8083063 Iustin Pop

202 a8083063 Iustin Pop
  Parameters:
203 a8083063 Iustin Pop
    - dbg: if true, the message will also be output to stderr
204 a8083063 Iustin Pop
    - txt: the log message
205 a8083063 Iustin Pop

206 a8083063 Iustin Pop
  """
207 a8083063 Iustin Pop
  _WriteEntry(_errlog, txt)
208 a8083063 Iustin Pop
  sys.stderr.write(txt + '\n')
209 a8083063 Iustin Pop
210 a8083063 Iustin Pop
211 a8083063 Iustin Pop
def Info(txt):
212 a8083063 Iustin Pop
  """Write a message to our general messages log
213 a8083063 Iustin Pop

214 a8083063 Iustin Pop
  If the global debug flag is true, the log message will also be
215 a8083063 Iustin Pop
  output to stderr.
216 a8083063 Iustin Pop

217 a8083063 Iustin Pop
  Parameters:
218 a8083063 Iustin Pop
    - txt: the log message
219 a8083063 Iustin Pop

220 a8083063 Iustin Pop
  """
221 a8083063 Iustin Pop
  _WriteEntry(_inflog, txt)
222 a8083063 Iustin Pop
  if _debug:
223 a8083063 Iustin Pop
    _WriteEntry(_stderr, txt)
224 a8083063 Iustin Pop
225 a8083063 Iustin Pop
226 a8083063 Iustin Pop
def Debug(txt):
227 a8083063 Iustin Pop
  """Write a message to the debug log
228 a8083063 Iustin Pop

229 a8083063 Iustin Pop
  If the global debug flag is true, the log message will also be
230 a8083063 Iustin Pop
  output to stderr.
231 a8083063 Iustin Pop

232 a8083063 Iustin Pop
  Parameters:
233 a8083063 Iustin Pop
    - txt: the log message
234 a8083063 Iustin Pop

235 a8083063 Iustin Pop
  """
236 a8083063 Iustin Pop
  _WriteEntry(_dbglog, txt)
237 a8083063 Iustin Pop
  if _debug:
238 a8083063 Iustin Pop
    _WriteEntry(_stderr, txt)