blob: ec373b794810c25c86a853873c77cca84327a52e [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
'''
@Desc: Module for providing logging facilities to marvin
'''
import logging
import sys
import time
import os
from marvin.codes import (SUCCESS,
FAILED
)
from marvin.cloudstackException import GetDetailExceptionInfo
from marvin.lib.utils import random_gen
class MarvinLog:
'''
@Name : MarvinLog
@Desc : provides interface for logging to marvin
@Input : logger_name : name for logger
'''
logFormat = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
_instance = None
def __new__(cls, logger_name):
if not cls._instance:
cls._instance = super(MarvinLog, cls).__new__(cls)
return cls._instance
def __init__(self, logger_name):
'''
@Name: __init__
@Input: logger_name for logger
'''
self.__loggerName = logger_name
'''
Logger for Logging Info
'''
self.__logger = None
'''
Log Folder Directory
'''
self.__logFolderDir = None
self.__setLogger()
def __setLogger(self):
'''
@Name : __setLogger
@Desc : Sets the Logger and Level
'''
self.__logger = logging.getLogger(self.__loggerName)
self.__logger.setLevel(logging.DEBUG)
def __setLogHandler(self, log_file_path,
log_format=None,
log_level=logging.DEBUG):
'''
@Name : __setLogHandler
@Desc: Adds the given Log handler to the current logger
@Input: log_file_path: Log File Path as where to store the logs
log_format : Format of log messages to be dumped
log_level : Determines the level of logging for this logger
@Output: SUCCESS if no issues else FAILED
'''
try:
if log_file_path is not None:
stream = logging.FileHandler(log_file_path)
else:
stream = logging.StreamHandler(stream=sys.stdout)
if log_format is not None:
stream.setFormatter(log_format)
else:
stream.setFormatter(self.__class__.logFormat)
stream.setLevel(log_level)
self.__logger.addHandler(stream)
return SUCCESS
except Exception as e:
print("\nException Occurred Under " \
"__setLogHandler %s" % GetDetailExceptionInfo(e))
return FAILED
def __cleanPreviousLogs(self, logfolder_to_remove):
'''
@Name : __cleanPreviousLogs
@Desc : Removes the Previous Logs
@Return: N\A
@Input: logfolder_to_remove: Path of Log to remove
'''
try:
if os.path.isdir(logfolder_to_remove):
os.rmdir(logfolder_to_remove)
except Exception as e:
print("\n Exception Occurred Under __cleanPreviousLogs :%s" % \
GetDetailExceptionInfo(e))
return FAILED
def getLogger(self):
'''
@Name:getLogger
@Desc : Returns the Logger
'''
return self.__logger
def getLogFolderPath(self):
'''
@Name : getLogFolderPath
@Desc : Returns the final log directory path for marvin run
'''
return self.__logFolderDir
def createLogs(self,
test_module_name=None,
log_cfg=None,
user_provided_logpath=None, use_temp_path=True):
'''
@Name : createLogs
@Desc : Gets the Logger with file paths initialized and created
@Inputs :test_module_name: Test Module Name to use for logs while
creating log folder path
log_cfg: Log Configuration provided inside of
Configuration
user_provided_logpath:LogPath provided by user
If user provided log path
is available, then one in cfg
will not be picked up.
use_temp_path: Boolean value which specifies either logs will
be prepended by random path or not.
@Output : SUCCESS\FAILED
'''
try:
temp_ts = time.strftime("%b_%d_%Y_%H_%M_%S", time.localtime())
if test_module_name is None:
temp_path = temp_ts + "_" + random_gen()
else:
temp_path = str(test_module_name) + "__" + str(temp_ts) + "_" + random_gen()
if user_provided_logpath:
temp_dir = os.path.join(user_provided_logpath, "MarvinLogs")
elif ((log_cfg is not None) and
('LogFolderPath' in list(log_cfg.__dict__.keys())) and
(log_cfg.__dict__.get('LogFolderPath') is not None)):
temp_dir = os.path.join(log_cfg.__dict__.get('LogFolderPath'), "MarvinLogs")
if use_temp_path == True:
self.__logFolderDir = os.path.join(temp_dir, temp_path)
else:
if test_module_name == None:
self.__logFolderDir = temp_dir
else:
self.__logFolderDir = os.path.join(temp_dir, str(test_module_name))
print("\n==== Log Folder Path: %s All logs will be available here ====" % str(self.__logFolderDir))
os.makedirs(self.__logFolderDir)
'''
Log File Paths
1. FailedExceptionLog
2. RunLog contains the complete Run Information for Test Run
3. ResultFile contains the TC result information for Test Run
'''
tc_failed_exception_log = os.path.join(self.__logFolderDir, "failed_plus_exceptions.txt")
tc_run_log = os.path.join(self.__logFolderDir, "runinfo.txt")
if self.__setLogHandler(tc_run_log,
log_level=logging.DEBUG) != FAILED:
self.__setLogHandler(tc_failed_exception_log,
log_level=logging.FATAL)
return SUCCESS
return FAILED
except Exception as e:
print("\n Exception Occurred Under createLogs :%s" % \
GetDetailExceptionInfo(e))
return FAILED