blob: ce7ff936f6b1ba5d872a3c089d7761ba26ff7b7d [file] [log] [blame] [edit]
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module for Local Agent logger."""
import logging
from logging import handlers
from typing import Optional
log_handler_map = {}
logger = logging.getLogger(name='local_agent')
_DEFAULT_LOG_FILE = 'local_agent.log'
# Example:
# 20210725 18:23:09.509 W tmp.py:23 This is the log message.
_LOG_FORMAT_PARTS = ('%(asctime)s.%(msecs)03d', # Time.
'%(levelname).1s', # Level.
'%(filename)s:%(lineno)d', # Where.
'%(message)s')
_LOG_FORMAT = ' '.join(_LOG_FORMAT_PARTS)
_DATE_FORMAT = '%Y%m%d %X'
def create_handler(log_file: Optional[str] = None) -> logging.Handler:
"""Creates the logging handler for a specific log file.
If log_file arugment is provided, we create RotatingFileHandler; otherwise
we create a StreamHandler.
Args:
log_file (str): Path to the log file.
Returns:
The logging handler created.
"""
if log_file is not None:
handler = handlers.RotatingFileHandler(log_file,
maxBytes=100000,
backupCount=10)
else:
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter(_LOG_FORMAT, datefmt=_DATE_FORMAT))
return handler
def add_file_handler(log_file: str) -> None:
"""Adds a handler to the global logger for logging to the given file.
We use a global dict to prevent adding multiple file handlers for one
single file.
Args:
log_file: Path of the file to add handler for.
"""
if log_file in log_handler_map:
return
handler = create_handler(log_file)
log_handler_map[log_file] = handler
logger.addHandler(handler)
def remove_file_handler(log_file: str) -> None:
"""Removes the logging handler of a specific file.
If there isn't a handler for the file, no-op.
Args:
log_file: Path of the log file.
"""
if log_file not in log_handler_map:
return
handler = log_handler_map[log_file]
logger.removeHandler(handler)
del log_handler_map[log_file]
def setup_logger() -> None:
"""Sets up the logger for logging in file and console."""
logger.setLevel(logging.DEBUG)
file_handler = create_handler(_DEFAULT_LOG_FILE)
stream_handler = create_handler()
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
def get_logger() -> logging.Logger:
"""Gets the local agent logger for logging.
This get function helps modules in the local agent package get the local
agent logger without having to directly importing the "logger" member.
Returns:
The local agent logger.
"""
return logger
setup_logger()