Last active
August 29, 2015 13:57
-
-
Save rickcnagy/9517510 to your computer and use it in GitHub Desktop.
Wrapper on top of the Logger class for logging QuickSchools API requests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/Library/Frameworks/Python.framework/Versions/2.7/bin/python | |
| """Wrapper on top of the Logger for logging QuickSchools API requests""" | |
| import logging | |
| import json | |
| import sys | |
| import random | |
| import os | |
| import traceback | |
| import syslog | |
| QS_INFO = 35 | |
| LOG_SENDER = 'QS API' | |
| has_been_configured = False | |
| def basicConfig(sender, silent=True, log_filename=None): | |
| """mirrors Logging.basicConfig(), especially setting the output stream | |
| sender should be sender's __file__ | |
| file will be based on sender's name unless log_filename is specified | |
| """ | |
| global has_been_configured | |
| # for logging INFO events while ignoring usual INFO level logs | |
| logging.addLevelName(QS_INFO, 'QS INFO') | |
| log_format = '%(levelname)s - %(message)s' | |
| log_path = filename(sender, log_filename) | |
| if not silent: | |
| logging.basicConfig( | |
| format=log_format, level=QS_INFO) | |
| else: | |
| logging.basicConfig( | |
| format=log_format, level=QS_INFO, filename=log_path) | |
| print("Logging to file:\n{}".format(log_path)) | |
| syslog.openlog(LOG_SENDER) | |
| has_been_configured = True | |
| def info(description, data, is_response=False, is_request=False, cc_print=False): | |
| """info level log messages, logs to syslog and default output stream""" | |
| check_config() | |
| log_message = format_for_log(description, data, is_request, is_response) | |
| syslog.syslog(syslog.LOG_INFO, log_message) | |
| logging.log(QS_INFO, log_message) | |
| if cc_print: | |
| print log_message | |
| def warning(description, data, is_response=False, is_request=False, cc_print=False): | |
| """same as info, but warning level""" | |
| check_config() | |
| log_message = format_for_log(description, data, is_request, is_response) | |
| syslog.syslog(syslog.LOG_ERR, log_message) | |
| logging.warning(log_message) | |
| if cc_print: | |
| print log_message | |
| def error(description, data, is_response=False, is_request=False, cc_print=False): | |
| """same as info, but error level""" | |
| check_config() | |
| log_message = format_for_log(description, data, is_request, is_response) | |
| syslog.syslog(syslog.LOG_ERR, log_message) | |
| logging.error(log_message) | |
| if cc_print: | |
| print log_message | |
| def critical(description, data, is_request=False, is_response=False): | |
| """same as info, but critical and also prints stack trace, log message, and then exits execution""" | |
| check_config() | |
| log_message = "CRITICAL:\n{}".format( | |
| format_for_log(description, data, is_request, is_response)) | |
| syslog.syslog(syslog.LOG_CRIT, log_message) | |
| logging.critical(log_message) | |
| traceback.print_stack() | |
| sys.exit(log_message) | |
| def error_or_critical(description, data, is_critical, is_request=False, is_response=False): | |
| """convenience method to trigger error or critical message based on is_critical param""" | |
| if is_critical: | |
| critical(description, data, is_request=is_request, is_response=is_response) | |
| else: | |
| error(description, data, is_request=is_request, is_response=is_response) | |
| def check_config(): | |
| if not has_been_configured: | |
| basicConfig(os.getcwd()) | |
| def format_for_log(description, data, is_request, is_response): | |
| """formats all log messages to be uniform for output and include all info""" | |
| description += " - RESPONSE" if is_response else '' | |
| description += " - REQUEST" if is_request else '' | |
| description += '\n{}'.format(json.dumps(data, indent=4)) if data else '' | |
| return description | |
| def filename(path, filename): | |
| """create and return a unique filename in a subdirectory called "logs" | |
| subdirectory is in either path param's os cwd | |
| if there's a path param, includes the sender's name (e.g. download.py) | |
| filename has precedence for log filename unless None | |
| """ | |
| if path: | |
| log_path = path if os.path.isdir(path) else os.path.dirname(path) | |
| else: | |
| log_path = os.getcwd() | |
| log_path += '/logs' | |
| if not os.path.exists(log_path): | |
| os.mkdir(log_path) | |
| fileid = filename | |
| if not filename: | |
| fileid = os.path.splitext(os.path.basename(path))[0] if not os.path.isdir(path) else 'API' | |
| return '{}/{} {}.log'.format(log_path, fileid, random.randint(1, 999)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment