diff options
author | Ankitkumar Patel <ankit@research.att.com> | 2018-02-11 17:51:13 -0500 |
---|---|---|
committer | Ankitkumar Patel <ankit@research.att.com> | 2018-02-11 17:52:51 -0500 |
commit | 0b855c08fd98fb8fa0f4bc40d8df430c897b4bad (patch) | |
tree | efdd3c7ab31be64080dd71951a64d13f0ba493de /osdf/logging/osdf_logging.py | |
parent | bb8471cae394aa6ff0af8ba3e5354f3b121c56fc (diff) |
Re-org folders, onboard test folder, test config
Reorganized the folder structure. Onboarded testcases. Added test config.
Issue-ID: OPTFRA-74
Change-Id: I97882a162a405a18ffd287495039e15ae9d0ad7b
Signed-off-by: Ankitkumar Patel <ankit@research.att.com>
Diffstat (limited to 'osdf/logging/osdf_logging.py')
-rwxr-xr-x | osdf/logging/osdf_logging.py | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/osdf/logging/osdf_logging.py b/osdf/logging/osdf_logging.py new file mode 100755 index 0000000..9a6ff4e --- /dev/null +++ b/osdf/logging/osdf_logging.py @@ -0,0 +1,229 @@ +import logging +import traceback +import uuid + +import logging +from logging.handlers import RotatingFileHandler +from osdf.utils.programming_utils import MetaSingleton + + +def log_handlers_pre_onap(config_file="config/pre_onap_logging_common_v1.config", + service_name="OOF_OSDF"): + """ + Convenience handlers for logging to different log files + + :param config_file: configuration file (properties file) that specifies log location, rotation, etc. + :param service_name: name for this service + :return: dictionary of log objects: "error", "metrics", "audit", "debug" + + We can use the returned values as follows: + X["error"].fatal("a FATAL message for the error log") + X["error"].error("an ERROR message for the error log") + X["error"].warn("a WARN message for the error log") + X["audit"].info("an INFO message for the audit log") + X["metrics"].info("an INFO message for the metrics log") + X["debug"].debug("a DEBUG message for the debug log") + """ + # Keeping main_params as a place-holder for ONAP related logging needs + # main_params = dict(instanceUUID=uuid.uuid1(), serviceName=service_name, configFile=config_file) + return dict((x, logging.getLogger(x)) # keep **main_params as a placeholder for ONAP fields + for x in ["error", "metrics", "audit", "debug"]) + + +def format_exception(err, prefix=None): + """Format operation for use with ecomp logging + :param err: exception object + :param prefix: prefix string message + :return: formatted exception (via repr(traceback.format_tb(err.__traceback__)) + """ + exception_lines = traceback.format_exception(err.__class__, err, err.__traceback__) + exception_desc = "".join(exception_lines) + return exception_desc if not prefix else prefix + ": " + exception_desc + + +class OOF_OSDFLogMessageHelper(metaclass=MetaSingleton): + """Provides loggers as a singleton (otherwise, we end up with duplicate messages). + Provides error_log, metric_log, audit_log, and debug_log (in that order) + Additionally can provide specific log handlers too + """ + log_handlers = None + default_levels = ["error", "metrics", "audit", "debug"] + + def _setup_handlers(self, log_version="pre_onap", config_file=None, service_name=None): + """return error_log, metrics_log, audit_log, debug_log""" + if self.log_handlers is None: + params = {} + params.update({"config_file": config_file} if config_file else {}) + params.update({"service_name": service_name} if service_name else {}) + + if log_version == "pre_onap": + self.log_handlers = log_handlers_pre_onap(**params) + + def get_handlers(self, levels=None, log_version="pre_onap", config_file=None, service_name=None): + """Return ONAP-compliant log handlers for different levels. Each "level" ends up in a different log file + with a prefix of that level. + + For example: error_log, metrics_log, audit_log, debug_log in that order + :param levels: None or list of levels subset of self.default_levels (["error", "metrics", "audit", "debug"]) + :param log_version: Currently only pre_onap is supported + :param config_file: Logging configuration file for ONAP compliant logging + :param service_name: Name of the service + :return: list of log_handlers in the order of levels requested. + if levels is None: we return handlers for self.default_levels + if levels is ["error", "audit"], we return log handlers for that. + """ + self._setup_handlers(log_version="pre_onap", config_file=config_file, service_name=service_name) + wanted_levels = self.default_levels if levels is None else levels + return [self.log_handlers.get(x) for x in wanted_levels] + + +class OOF_OSDFLogMessageFormatter(object): + + @staticmethod + def accepted_valid_request(req_id, request): + return "Accepted valid request for ID: {} for endpoint: {}".format( + req_id, request.url) + + @staticmethod + def invalid_request(req_id, err): + return "Invalid request for request ID: {}; cause: {}".format( + req_id, format_exception(err)) + + @staticmethod + def invalid_response(req_id, err): + return "Invalid response for request ID: {}; cause: {}".format( + req_id, format_exception(err)) + + @staticmethod + def malformed_request(request, err): + return "Malformed request for URL {}, from {}; cause: {}".format( + request.url, request.remote_address, format_exception(err)) + + @staticmethod + def malformed_response(response, client, err): + return "Malformed response {} for client {}; cause: {}".format( + response, client, format_exception(err)) + + @staticmethod + def need_policies(req_id): + return "Policies required but found no policies for request ID: {}".format(req_id) + + @staticmethod + def policy_service_error(url, req_id, err): + return "Unable to call policy for {} for request ID: {}; cause: {}".format( + url, req_id, format_exception(err)) + + @staticmethod + def requesting_url(url, req_id): + return "Making a call to URL {} for request ID: {}".format(url, req_id) + + @staticmethod + def requesting(service_name, req_id): + return "Making a call to service {} for request ID: {}".format(service_name, req_id) + + @staticmethod + def error_requesting(service_name, req_id, err): + return "Error while requesting service {} for request ID: {}; cause: {}".format( + service_name, req_id, format_exception(err)) + + @staticmethod + def calling_back(req_id, callback_url): + return "Posting result to callback URL for request ID: {}; callback URL={}".format( + req_id, callback_url) + + @staticmethod + def calling_back_with_body(req_id, callback_url, body): + return "Posting result to callback URL for request ID: {}; callback URL={} body={}".format( + req_id, callback_url, body) + + @staticmethod + def error_calling_back(req_id, callback_url, err): + return "Error while posting result to callback URL {} for request ID: {}; cause: {}".format( + req_id, callback_url, format_exception(err)) + + @staticmethod + def received_request(url, remote_addr, json_body): + return "Received a call to {} from {} {}".format(url, remote_addr, json_body) + + @staticmethod + def new_worker_thread(req_id, extra_msg=""): + res = "Initiating new worker thread for request ID: {}".format(req_id) + return res + extra_msg + + @staticmethod + def inside_worker_thread(req_id, extra_msg=""): + res = "Inside worker thread for request ID: {}".format(req_id) + return res + extra_msg + + @staticmethod + def processing(req_id, desc): + return "Processing request ID: {} -- {}".format(req_id, desc) + + @staticmethod + def processed(req_id, desc): + return "Processed request ID: {} -- {}".format(req_id, desc) + + @staticmethod + def error_while_processing(req_id, desc, err): + return "Error while processing request ID: {} -- {}; cause: {}".format( + req_id, desc, format_exception(err)) + + @staticmethod + def creating_local_env(req_id): + return "Creating local environment request ID: {}".format( + req_id) + + @staticmethod + def error_local_env(req_id, desc, err): + return "Error while creating local environment for request ID: {} -- {}; cause: {}".format( + req_id, desc, err.__traceback__) + + @staticmethod + def inside_new_thread(req_id, extra_msg=""): + res = "Spinning up a new thread for request ID: {}".format(req_id) + return res + " " + extra_msg + + @staticmethod + def error_response_posting(req_id, desc, err): + return "Error while posting a response for a request ID: {} -- {}; cause: {}".format( + req_id, desc, err.__traceback__) + + @staticmethod + def received_http_response(resp): + return "Received response [code: {}, headers: {}, data: {}]".format( + resp.status_code, resp.headers, resp.__dict__) + + @staticmethod + def sending_response(req_id, desc): + return "Response is sent for request ID: {} -- {}".format( + req_id, desc) + + @staticmethod + def listening_response(req_id, desc): + return "Response is sent for request ID: {} -- {}".format( + req_id, desc) + + @staticmethod + def items_received(item_num, item_type, desc="Received"): + return "{} {} {}".format(desc, item_num, item_type) + + @staticmethod + def items_sent(item_num, item_type, desc="Published"): + return "{} {} {}".format(desc, item_num, item_type) + + +MH = OOF_OSDFLogMessageFormatter +error_log, metrics_log, audit_log, debug_log = OOF_OSDFLogMessageHelper().get_handlers() + +def warn_audit_error(msg): + """Log the message to error_log.warn and audit_log.warn""" + log_message_multi(msg, audit_log.warn, error_log.warn) + + +def log_message_multi(msg, *logger_methods): + """Log the msg to multiple loggers + :param msg: message to log + :param logger_methods: e.g. error_log.warn, audit_log.warn, etc. + """ + for log_method in logger_methods: + log_method(msg) |