-
Notifications
You must be signed in to change notification settings - Fork 6
Feature/logging module #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c110533
2c5f39a
82c64cc
32ef1f6
b0d326c
461906c
d0065e6
ed373e8
6823b2f
adef2a7
cc971b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ Config/config.ini | |
settings.json | ||
# C extensions | ||
*.so | ||
Logs/ | ||
|
||
# Distribution / packaging | ||
.Python | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import configparser | ||
|
||
config = configparser.ConfigParser() | ||
config.read('Config/logger.ini') | ||
|
||
# check if the required sections are present | ||
if 'loggers' not in config.sections() or 'handlers' not in config.sections(): | ||
raise ValueError('Missing required section in config.ini') | ||
|
||
if 'keys' not in config['loggers'] or 'suspicious' not in config['loggers']: | ||
raise ValueError('Missing required key in loggers section in config.ini') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar change required: raise ValueError('Missing required key in loggers section in **logger**.ini') |
||
|
||
# check if the required keys are present in the 'handlers' section | ||
if 'keys' not in config['handlers'] or 'console' not in config['handlers']['keys']: | ||
raise ValueError('Missing required key in handlers section in config.ini') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar change required: raise ValueError('Missing required key in handlers section in **logger**.ini') |
||
|
||
# check if the values of the keys are in the expected format | ||
if not isinstance(config.getint('handlers', 'console.level'), int): | ||
raise ValueError('Invalid value for console.level in config.ini') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar change: raise ValueError('Invalid value for console.level in logger.ini') |
||
|
||
if not isinstance(config.getint('loggers', 'keys.suspicious.level'), int): | ||
raise ValueError('Invalid value for keys.suspicious.level in config.ini') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar change: raise ValueError('Invalid value for keys.suspicious.level in logger.ini') |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,53 @@ | ||
# FILE CURRENTLY NOT USED | ||
import logging | ||
import logging.config | ||
import configparser | ||
import os | ||
import sys | ||
|
||
# import configparser | ||
# from Common import utils | ||
|
||
# try: | ||
# config = configparser.ConfigParser() | ||
# config.read('config.ini') | ||
# except Exception as er: | ||
# utils.error_message(er) | ||
def get_config(config_file_path): | ||
""" | ||
Parse configuration from file and environment variables. | ||
|
||
# # Get the Virus Total API key from the config file | ||
# VT_APIKey = config['APIKeys']['VT_APIKey'] | ||
:param str config_file_path: path to the configuration file | ||
:return: configuration values as a dictionary | ||
:rtype: dict | ||
""" | ||
config = configparser.ConfigParser() | ||
|
||
# read from file | ||
config.read(config_file_path) | ||
config.__dict__ | ||
|
||
# read from environment variables | ||
for key in config['ENVIRONMENT']: | ||
env_var = os.environ.get(key) | ||
if env_var is not None: | ||
config['ENVIRONMENT'][key] = env_var | ||
|
||
return config | ||
|
||
|
||
def get_logging_config(file_location="Config/logger.ini"): | ||
""" | ||
Get logging configuration from configuration file. | ||
|
||
:return: logging configuration as a dictionary | ||
:rtype: dict | ||
""" | ||
try: | ||
open(file_location, "r") | ||
except FileNotFoundError: | ||
logging.critical(f"File location invalid: {file_location}") | ||
sys.exit(1) | ||
|
||
config = get_config('Config/logger.ini') | ||
return config | ||
|
||
|
||
def configure_logging(): | ||
""" | ||
Configure logging for the application. | ||
""" | ||
logging_config = get_logging_config() | ||
return logging_config |
H4ppy-04 marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import logging | ||
|
||
|
||
class Formatter(logging.Formatter): | ||
def __init__(self, fmt=None, datefmt=None, levels=None): | ||
super().__init__(fmt, datefmt) | ||
self.levels = levels or {} | ||
|
||
def format(self, record): | ||
record.levelprefix = self.levels.get(record.levelno, '') | ||
emoji = '' | ||
if record.levelno == logging.CRITICAL: | ||
emoji = '💣' | ||
elif record.levelno == logging.ERROR: | ||
emoji = '🔥' | ||
elif record.levelno == logging.WARNING: | ||
emoji = '⚠️' | ||
elif record.levelno == logging.INFO: | ||
emoji = 'ℹ️' | ||
elif record.levelno == logging.DEBUG: | ||
emoji = '🔍' | ||
record.emoji = emoji | ||
return super().format(record) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[ENVIRONMENT] | ||
production = False | ||
|
||
[logging] | ||
level = INFO | ||
handler = console,file | ||
formatter = default | ||
output = Logs/traceback.log | ||
debug_emoji = 🐛 | ||
info_emoji = 💡 | ||
warning_emoji = ⚠️ | ||
error_emoji = 🚨 | ||
critical_emoji = 💣 | ||
|
||
[handlers] | ||
keys = console,file | ||
|
||
[formatters] | ||
keys = default | ||
|
||
[handler_console] | ||
class = logging.StreamHandler | ||
level = INFO | ||
formatter = default | ||
args = (sys.stdout,) | ||
|
||
[handler_file] | ||
class = logging.FileHandler | ||
level = INFO | ||
formatter = default | ||
args = ('Logs/traceback.log', 'a') | ||
|
||
[formatter_default] | ||
format = %(asctime)s - %(name)s - %(levelname)s - %(message)s | ||
datefmt = %Y-%m-%d %H:%M:%S |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import os | ||
import unittest | ||
from configparser import ConfigParser | ||
|
||
class TestConfig(unittest.TestCase): | ||
def setUp(self): | ||
self.path = os.path.join('Config/logger.ini') | ||
|
||
if not os.path.isdir('Logs'): | ||
os.mkdir('Logs') | ||
if not os.path.exists(os.path.join('Logs', 'traceback.log')): | ||
with open(os.path.join('Logs', 'traceback.log')) as fp: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have encountered an issue while running the test when traceback.log file isn't already created. Like in line 10, where Logs directory is created if not exists, we may need to create traceback.log if it doesn't exist. |
||
fp.close() | ||
|
||
def test_config_exists(self): | ||
self.assertTrue(self.path) | ||
|
||
def test_config_is_valid(self): | ||
parser = ConfigParser() | ||
if self.test_config_exists: | ||
parser.read(self.path) | ||
|
||
# Check if the required sections are present in the config | ||
self.assertIn('formatters', parser.sections()) | ||
self.assertIn('handler_console', parser.sections()) | ||
|
||
# Check if the required keys are present in the sections | ||
self.assertIn('keys', parser['formatters']) | ||
self.assertIn('level', parser['handler_console']) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this message would have to be: