1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2021-2024 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import logging 19from pathlib import Path 20from typing import NoReturn, Type, Optional 21 22from runner.enum_types.verbose_format import VerboseKind 23from runner.path_utils import chown2user 24 25SUMMARY_LOG_LEVEL = 21 26NONE_LOG_LEVEL = 22 27 28 29class Log: 30 _is_init = False 31 32 @staticmethod 33 def setup(verbose: VerboseKind, report_root: str) -> logging.Logger: 34 logger = logging.getLogger("runner") 35 36 log_path: Path = Path(report_root) if report_root is not None else \ 37 Path("/") / "tmp" 38 log_path.mkdir(exist_ok=True) 39 log_path = log_path / "runner.log" 40 log_path.unlink(missing_ok=True) 41 42 file_handler = logging.FileHandler(log_path) 43 console_handler = logging.StreamHandler() 44 45 if verbose == VerboseKind.ALL: 46 logger.setLevel(logging.DEBUG) 47 file_handler.setLevel(logging.DEBUG) 48 console_handler.setLevel(logging.DEBUG) 49 elif verbose == VerboseKind.SHORT: 50 logger.setLevel(logging.INFO) 51 file_handler.setLevel(logging.INFO) 52 console_handler.setLevel(logging.INFO) 53 else: 54 logger.setLevel(NONE_LOG_LEVEL) 55 file_handler.setLevel(NONE_LOG_LEVEL) 56 console_handler.setLevel(NONE_LOG_LEVEL) 57 58 file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s') 59 file_handler.setFormatter(file_formatter) 60 console_formatter = logging.Formatter('%(message)s') 61 console_handler.setFormatter(console_formatter) 62 63 logger.addHandler(file_handler) 64 logger.addHandler(console_handler) 65 logger.addHandler(logging.NullHandler()) 66 67 chown2user(log_path.parent, recursive=False) 68 chown2user(log_path) 69 70 return logger 71 72 @staticmethod 73 def all(logger: logging.Logger, message: str) -> None: 74 """ 75 Logs on the level verbose=ALL 76 """ 77 logger.debug(message) 78 79 @staticmethod 80 def short(logger: logging.Logger, message: str) -> None: 81 """ 82 Logs on the level verbose=SHORT 83 """ 84 logger.info(message) 85 86 @staticmethod 87 def summary(logger: logging.Logger, message: str) -> None: 88 """ 89 Logs on the level verbose=SUMMARY (sum) 90 """ 91 logger.log(SUMMARY_LOG_LEVEL, message) 92 93 @staticmethod 94 def default(logger: logging.Logger, message: str) -> None: 95 """ 96 Logs on the level verbose=None 97 """ 98 logger.log(NONE_LOG_LEVEL, message) 99 100 @staticmethod 101 def exception_and_raise(logger: logging.Logger, message: str, 102 exception_cls: Optional[Type[Exception]] = None) -> NoReturn: 103 """ 104 Logs and throw the exception 105 """ 106 logger.critical(message) 107 if exception_cls is None: 108 raise Exception(message) 109 raise exception_cls(message) 110