1# Copyright 2018 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Shared logging functions for autotest drone services 6 7autotest/site_utils/ is home to various upstart jobs and cron jobs that run on 8autotest drones. All these jobs currently configure logging in different ways. 9Worse, many of these scripts don't use logging at all, instead print()ing to 10stdout and use external log file management. 11 12This library provides a single consistent way to manage log configuration and 13log directories for these scripts. 14""" 15 16from __future__ import absolute_import 17from __future__ import division 18from __future__ import print_function 19 20import logging 21import logging.config 22import os 23 24 25def add_logging_options(parser): 26 """Add logging configuration options to argument parser. 27 28 @param parser: ArgumentParser instance. 29 """ 30 parser.add_argument( 31 '--log-dir', 32 default=None, 33 help='(existing) directory to drop log files in.' 34 ' By default, logs to stderr.', 35 ) 36 37 38def configure_logging_with_args(parser, args): 39 """Convenience function for calling configure_logging(). 40 41 @param parser: ArgumentParser instance. 42 @param args: Return value from ArgumentParser.parse_args(). 43 """ 44 configure_logging(parser.prog, args.log_dir) 45 46 47def configure_logging(name, log_dir=None): 48 """Configure logging globally. 49 50 @param name: Name to prepend to log messages. 51 This should be the name of the program. 52 @param log_dir: Path to the (existing) direcotry to create log files in. 53 If None, logs to stderr. 54 """ 55 if log_dir is None: 56 handlers = { 57 'default': { 58 'class': 'logging.StreamHandler', 59 'formatter': 'default' , 60 } 61 } 62 else: 63 handlers = { 64 'default': { 65 'class': 'logging.handlers.TimedRotatingFileHandler', 66 'formatter': 'default' , 67 'filename': os.path.join(log_dir, '%s.log' % name), 68 'when': 'midnight', 69 'backupCount': 14, 70 } 71 } 72 73 74 logging.config.dictConfig({ 75 'version': 1, 76 'handlers': handlers, 77 'formatters': { 78 'default': { 79 'format': ('{name}: ' 80 '%(asctime)s:%(levelname)s' 81 ':%(module)s:%(funcName)s:%(lineno)d' 82 ': %(message)s' 83 .format(name=name)), 84 }, 85 }, 86 'root': { 87 'level': 'INFO', 88 'handlers': ['default'], 89 }, 90 'disable_existing_loggers': False, 91 }) 92