Commit 335f24eb authored by Ibrahim Ahmed's avatar Ibrahim Ahmed
Browse files

utils/logs.py: Logging exceptions via HTTP formats traceback into message string;

Previously the monitor.py script would not log the traceback logged for errors in controller. Since the logrecord was converted to a json object for transport, the exc_info attribute could not be read on the monitor side to get a traceback string. Now the utils.RemoteHandler class formats traceback string into the message before sending it via HTTP.
parent 7b3bb8cc
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -47,12 +47,13 @@ def make_arguments() -> ArgumentParser:
    # Actual default values should be stored as variables (DEFAULTS), or put in
    # the settings ini file.
    parser = ArgumentParser(description='Condenser set-point optimization script.',
        epilog='Additional settings can be changed from the specified settings ini file.')
    # parser.add_argument('-i', '--interval', type=int, required=False, default=None,
    #                     help='Interval in seconds to apply control action.')
    # parser.add_argument('-t', '--target', type=str, required=False, default=None,
    #                     help='Optimization target for condenser water setpoint.',
    #                     choices=('power', 'temperature'))
        epilog=('NOTE: Command line settings are global and overrite settings for all controller threads. '
                'Additional settings can be changed from the specified settings ini file.'))
    parser.add_argument('-i', '--interval', type=int, required=False, default=None,
                        help='Interval in seconds to apply control action.')
    parser.add_argument('-t', '--target', type=str, required=False, default=None,
                        help='Optimization target for condenser water setpoint.',
                        choices=('power', 'temperature'))
    # parser.add_argument('-o', '--output', type=str, required=False, default=None,
    #                     help='Location of file to write output to.')
    parser.add_argument('-s', '--settings', type=str, required=False,
@@ -227,8 +228,8 @@ if __name__ == '__main__':
                thread.join(timeout=2.)

    # Exceptions during settings parsing, thread creation
    except Exception as e:
    except Exception as exc:
        logger = get_logger()
        logger.critical(msg=e, exc_info=True)
        logger.exception(msg=exc, exc_info=True)
        logger.critical(msg='Could not start script.')
        exit(-1)
+5 −6
Original line number Diff line number Diff line
@@ -31,13 +31,12 @@ dapp.layout = html.Div([
@app.route('/log', methods=('POST',))   # endpoint for POST requests
def log():
    logger = get_logger('monitor')
    rdict = request.form
    rdict = request.form    # dictionary with keys as logging.LogRecord
    name = rdict.get('name', '')
    message = rdict.get('message', rdict.get('msg', 'NO_MESSAGE'))
    ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)
    logger.log(int(rdict.get('levelno', logging.ERROR)), 'From: %s %s, %s' % \
                                                        (ip,
                                                        rdict.get('name', ''),
                                                        rdict.get('message', rdict.get('msg', 'NO_MESSAGE')),
                                                        ))
    loglevel = int(rdict.get('levelno', logging.ERROR))
    logger.log(loglevel, 'From: %s %s, %s' % (ip, name, message))
    return 'OK'


+7 −1
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ Various classes to be used by `logging.Logger` for sending messages:
"""
import sys
import logging
import traceback
from logging.handlers import HTTPHandler, BufferingHandler
import smtplib
import email
@@ -192,7 +193,12 @@ class RemoteHandler(HTTPHandler):
        Dict[str, str]
            A dictionary to encode into a HTTP request.
        """
        return super().mapLogRecord(record)
        rdict = super().mapLogRecord(record)
        if record.exc_info is not None:
            exc, value, tb = record.exc_info
            exc_str = ''.join(traceback.format_exception(exc, value, tb))
            rdict['message'] += '\n' + exc_str
        return rdict


    def emit(self, record: logging.LogRecord):