~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to nova/log.py

  • Committer: Justin Santa Barbara
  • Date: 2011-02-23 01:21:32 UTC
  • mfrom: (700.3.17 fix-fake-rabbit)
  • Revision ID: justin@fathomdb.com-20110223012132-9sl6jq28a3adtju6
Merged with fake-rabbit fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
flags.DEFINE_list('default_log_levels',
66
66
                  ['amqplib=WARN',
67
67
                   'sqlalchemy=WARN',
 
68
                   'boto=WARN',
68
69
                   'eventlet.wsgi.server=WARN'],
69
70
                  'list of logger=LEVEL pairs')
70
71
 
117
118
    return os.path.basename(inspect.stack()[-1][1])
118
119
 
119
120
 
120
 
def get_log_file_path(binary=None):
 
121
def _get_log_file_path(binary=None):
121
122
    if FLAGS.logfile:
122
123
        return FLAGS.logfile
123
124
    if FLAGS.logdir:
125
126
        return '%s.log' % (os.path.join(FLAGS.logdir, binary),)
126
127
 
127
128
 
128
 
def basicConfig():
129
 
    logging.basicConfig()
130
 
    for handler in logging.root.handlers:
131
 
        handler.setFormatter(_formatter)
132
 
    if FLAGS.verbose:
133
 
        logging.root.setLevel(logging.DEBUG)
134
 
    else:
135
 
        logging.root.setLevel(logging.INFO)
136
 
    if FLAGS.use_syslog:
137
 
        syslog = SysLogHandler(address='/dev/log')
138
 
        syslog.setFormatter(_formatter)
139
 
        logging.root.addHandler(syslog)
140
 
    logpath = get_log_file_path()
141
 
    if logpath:
142
 
        logfile = WatchedFileHandler(logpath)
143
 
        logfile.setFormatter(_formatter)
144
 
        logging.root.addHandler(logfile)
145
 
 
146
 
 
147
129
class NovaLogger(logging.Logger):
148
130
    """
149
131
    NovaLogger manages request context and formatting.
151
133
    This becomes the class that is instanciated by logging.getLogger.
152
134
    """
153
135
    def __init__(self, name, level=NOTSET):
154
 
        level_name = self._get_level_from_flags(name, FLAGS)
155
 
        level = globals()[level_name]
156
136
        logging.Logger.__init__(self, name, level)
 
137
        self.setup_from_flags()
157
138
 
158
 
    def _get_level_from_flags(self, name, FLAGS):
159
 
        # if exactly "nova", or a child logger, honor the verbose flag
160
 
        if (name == "nova" or name.startswith("nova.")) and FLAGS.verbose:
161
 
            return 'DEBUG'
 
139
    def setup_from_flags(self):
 
140
        """Setup logger from flags"""
 
141
        level = NOTSET
162
142
        for pair in FLAGS.default_log_levels:
163
 
            logger, _sep, level = pair.partition('=')
 
143
            logger, _sep, level_name = pair.partition('=')
164
144
            # NOTE(todd): if we set a.b, we want a.b.c to have the same level
165
145
            #             (but not a.bc, so we check the dot)
166
 
            if name == logger:
167
 
                return level
168
 
            if name.startswith(logger) and name[len(logger)] == '.':
169
 
                return level
170
 
        return 'INFO'
 
146
            if self.name == logger or self.name.startswith("%s." % logger):
 
147
                level = globals()[level_name]
 
148
        self.setLevel(level)
171
149
 
172
150
    def _log(self, level, msg, args, exc_info=None, extra=None, context=None):
173
151
        """Extract context from any log call"""
176
154
        if context:
177
155
            extra.update(_dictify_context(context))
178
156
        extra.update({"nova_version": version.version_string_with_vcs()})
179
 
        logging.Logger._log(self, level, msg, args, exc_info, extra)
 
157
        return logging.Logger._log(self, level, msg, args, exc_info, extra)
180
158
 
181
159
    def addHandler(self, handler):
182
160
        """Each handler gets our custom formatter"""
183
161
        handler.setFormatter(_formatter)
184
 
        logging.Logger.addHandler(self, handler)
 
162
        return logging.Logger.addHandler(self, handler)
185
163
 
186
164
    def audit(self, msg, *args, **kwargs):
187
165
        """Shortcut for our AUDIT level"""
208
186
            self.error(message, **kwargs)
209
187
 
210
188
 
211
 
def handle_exception(type, value, tb):
212
 
    logging.root.critical(str(value), exc_info=(type, value, tb))
213
 
 
214
 
 
215
 
sys.excepthook = handle_exception
216
 
logging.setLoggerClass(NovaLogger)
217
 
 
218
 
 
219
 
class NovaRootLogger(NovaLogger):
220
 
    pass
221
 
 
222
 
if not isinstance(logging.root, NovaRootLogger):
223
 
    logging.root = NovaRootLogger("nova.root", WARNING)
224
 
    NovaLogger.root = logging.root
225
 
    NovaLogger.manager.root = logging.root
226
 
 
227
 
 
228
189
class NovaFormatter(logging.Formatter):
229
190
    """
230
191
    A nova.context.RequestContext aware formatter configured through flags.
271
232
_formatter = NovaFormatter()
272
233
 
273
234
 
 
235
class NovaRootLogger(NovaLogger):
 
236
    def __init__(self, name, level=NOTSET):
 
237
        self.logpath = None
 
238
        self.filelog = None
 
239
        self.syslog = SysLogHandler(address='/dev/log')
 
240
        self.streamlog = StreamHandler()
 
241
        NovaLogger.__init__(self, name, level)
 
242
 
 
243
    def setup_from_flags(self):
 
244
        """Setup logger from flags"""
 
245
        global _filelog
 
246
        if FLAGS.use_syslog:
 
247
            self.addHandler(self.syslog)
 
248
        else:
 
249
            self.removeHandler(self.syslog)
 
250
        logpath = _get_log_file_path()
 
251
        if logpath:
 
252
            self.removeHandler(self.streamlog)
 
253
            if logpath != self.logpath:
 
254
                self.removeHandler(self.filelog)
 
255
                self.filelog = WatchedFileHandler(logpath)
 
256
                self.addHandler(self.filelog)
 
257
                self.logpath = logpath
 
258
        else:
 
259
            self.removeHandler(self.filelog)
 
260
            self.addHandler(self.streamlog)
 
261
        if FLAGS.verbose:
 
262
            self.setLevel(DEBUG)
 
263
        else:
 
264
            self.setLevel(INFO)
 
265
 
 
266
 
 
267
def handle_exception(type, value, tb):
 
268
    logging.root.critical(str(value), exc_info=(type, value, tb))
 
269
 
 
270
 
 
271
def reset():
 
272
    """Resets logging handlers.  Should be called if FLAGS changes."""
 
273
    for logger in NovaLogger.manager.loggerDict.itervalues():
 
274
        if isinstance(logger, NovaLogger):
 
275
            logger.setup_from_flags()
 
276
 
 
277
 
 
278
def setup():
 
279
    """Setup nova logging."""
 
280
    if not isinstance(logging.root, NovaRootLogger):
 
281
        logging._acquireLock()
 
282
        for handler in logging.root.handlers:
 
283
            logging.root.removeHandler(handler)
 
284
        logging.root = NovaRootLogger("nova")
 
285
        NovaLogger.root = logging.root
 
286
        NovaLogger.manager.root = logging.root
 
287
        for logger in NovaLogger.manager.loggerDict.itervalues():
 
288
            logger.root = logging.root
 
289
            if isinstance(logger, logging.Logger):
 
290
                NovaLogger.manager._fixupParents(logger)
 
291
        NovaLogger.manager.loggerDict["nova"] = logging.root
 
292
        logging._releaseLock()
 
293
        sys.excepthook = handle_exception
 
294
        reset()
 
295
 
 
296
 
 
297
root = logging.root
 
298
logging.setLoggerClass(NovaLogger)
 
299
 
 
300
 
274
301
def audit(msg, *args, **kwargs):
275
302
    """Shortcut for logging to root log with sevrity 'AUDIT'."""
276
 
    if len(logging.root.handlers) == 0:
277
 
        basicConfig()
278
303
    logging.root.log(AUDIT, msg, *args, **kwargs)