From db81fd831e16f925d5c93d4c7d9b1fcc6a7bbffa Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Wed, 14 Aug 2019 20:35:39 +0200 Subject: Add a database logging handler. --- pydis_site/apps/api/dblogger.py | 22 ++++++++++++++++++++++ pydis_site/settings.py | 5 ++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 pydis_site/apps/api/dblogger.py diff --git a/pydis_site/apps/api/dblogger.py b/pydis_site/apps/api/dblogger.py new file mode 100644 index 00000000..f133832a --- /dev/null +++ b/pydis_site/apps/api/dblogger.py @@ -0,0 +1,22 @@ +from logging import LogRecord, StreamHandler + + +class DatabaseLogHandler(StreamHandler): + """Logs entries into the database.""" + + def emit(self, record: LogRecord): + """Write the given `record` into the database.""" + # This import needs to be deferred due to Django's application + # registry instantiation logic loading this handler before the + # application is ready. + from pydis_site.apps.api.models.log_entry import LogEntry + + entry = LogEntry( + application='site', + logger_name=record.name, + level=record.levelname.lower(), + module=record.module, + line=record.lineno, + message=self.format(record) + ) + entry.save() diff --git a/pydis_site/settings.py b/pydis_site/settings.py index 2050c6ab..4a4eb94b 100644 --- a/pydis_site/settings.py +++ b/pydis_site/settings.py @@ -227,11 +227,14 @@ LOGGING = { 'handlers': { 'console': { 'class': 'logging.StreamHandler' + }, + 'database': { + 'class': 'pydis_site.apps.api.dblogger.DatabaseLogHandler' } }, 'loggers': { 'django': { - 'handlers': ['console'], + 'handlers': ['console', 'database'], 'propagate': True, 'level': env( 'LOG_LEVEL', -- cgit v1.2.3 From 6bf05b68a99daefbb7ce38e7f5000c09e4f7f6a2 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Wed, 14 Aug 2019 20:48:42 +0200 Subject: Add a test case. --- pydis_site/apps/api/tests/test_dblogger.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 pydis_site/apps/api/tests/test_dblogger.py diff --git a/pydis_site/apps/api/tests/test_dblogger.py b/pydis_site/apps/api/tests/test_dblogger.py new file mode 100644 index 00000000..e774b1d6 --- /dev/null +++ b/pydis_site/apps/api/tests/test_dblogger.py @@ -0,0 +1,26 @@ +import logging +from datetime import datetime + +from django.test import TestCase + +from ..dblogger import DatabaseLogHandler +from ..models import LogEntry + + +class DatabaseLogHandlerTests(TestCase): + def test_logs_to_database(self): + logger = logging.getLogger(__file__) + logger.handlers = [DatabaseLogHandler()] + logger.warning("I am a test case!") + + # Ensure we only have a single record in the database + # after the logging call above. + [entry] = LogEntry.objects.all() + + self.assertEqual(entry.application, 'site') + self.assertEqual(entry.logger_name, __file__) + self.assertIsInstance(entry.timestamp, datetime) + self.assertEqual(entry.level, 'warning') + self.assertEqual(entry.module, 'test_dblogger') + self.assertIsInstance(entry.line, int) + self.assertEqual(entry.message, "I am a test case!") -- cgit v1.2.3 From 30b1a1bfa615395a283542fff8cc402e6d3f937f Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Wed, 14 Aug 2019 21:03:40 +0200 Subject: Apply Mark's suggestions. how to logging Co-Authored-By: Mark --- pydis_site/apps/api/tests/test_dblogger.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pydis_site/apps/api/tests/test_dblogger.py b/pydis_site/apps/api/tests/test_dblogger.py index e774b1d6..ec2ac017 100644 --- a/pydis_site/apps/api/tests/test_dblogger.py +++ b/pydis_site/apps/api/tests/test_dblogger.py @@ -9,7 +9,7 @@ from ..models import LogEntry class DatabaseLogHandlerTests(TestCase): def test_logs_to_database(self): - logger = logging.getLogger(__file__) + logger = logging.getLogger("test_logger") logger.handlers = [DatabaseLogHandler()] logger.warning("I am a test case!") @@ -18,9 +18,9 @@ class DatabaseLogHandlerTests(TestCase): [entry] = LogEntry.objects.all() self.assertEqual(entry.application, 'site') - self.assertEqual(entry.logger_name, __file__) + self.assertEqual(entry.logger_name, "test_logger") self.assertIsInstance(entry.timestamp, datetime) self.assertEqual(entry.level, 'warning') - self.assertEqual(entry.module, 'test_dblogger') + self.assertEqual(entry.module, __name__) self.assertIsInstance(entry.line, int) self.assertEqual(entry.message, "I am a test case!") -- cgit v1.2.3 From 83649a757796d03f42bfb1ffad876121e70f2d5f Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Wed, 14 Aug 2019 21:13:32 +0200 Subject: Avoid hardcoding module name. --- pydis_site/apps/api/tests/test_dblogger.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pydis_site/apps/api/tests/test_dblogger.py b/pydis_site/apps/api/tests/test_dblogger.py index ec2ac017..4f0692c2 100644 --- a/pydis_site/apps/api/tests/test_dblogger.py +++ b/pydis_site/apps/api/tests/test_dblogger.py @@ -9,7 +9,8 @@ from ..models import LogEntry class DatabaseLogHandlerTests(TestCase): def test_logs_to_database(self): - logger = logging.getLogger("test_logger") + module_basename = __name__.split('.')[-1] + logger = logging.getLogger(module_basename) logger.handlers = [DatabaseLogHandler()] logger.warning("I am a test case!") @@ -18,9 +19,9 @@ class DatabaseLogHandlerTests(TestCase): [entry] = LogEntry.objects.all() self.assertEqual(entry.application, 'site') - self.assertEqual(entry.logger_name, "test_logger") + self.assertEqual(entry.logger_name, module_basename) self.assertIsInstance(entry.timestamp, datetime) self.assertEqual(entry.level, 'warning') - self.assertEqual(entry.module, __name__) + self.assertEqual(entry.module, module_basename) self.assertIsInstance(entry.line, int) self.assertEqual(entry.message, "I am a test case!") -- cgit v1.2.3 From decba0e10418974ea31b3e700cb1daa123c0b79f Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Wed, 14 Aug 2019 21:17:41 +0200 Subject: Use different field values. --- pydis_site/apps/api/tests/test_dblogger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydis_site/apps/api/tests/test_dblogger.py b/pydis_site/apps/api/tests/test_dblogger.py index 4f0692c2..bb19f297 100644 --- a/pydis_site/apps/api/tests/test_dblogger.py +++ b/pydis_site/apps/api/tests/test_dblogger.py @@ -10,7 +10,7 @@ from ..models import LogEntry class DatabaseLogHandlerTests(TestCase): def test_logs_to_database(self): module_basename = __name__.split('.')[-1] - logger = logging.getLogger(module_basename) + logger = logging.getLogger(__name__) logger.handlers = [DatabaseLogHandler()] logger.warning("I am a test case!") @@ -19,7 +19,7 @@ class DatabaseLogHandlerTests(TestCase): [entry] = LogEntry.objects.all() self.assertEqual(entry.application, 'site') - self.assertEqual(entry.logger_name, module_basename) + self.assertEqual(entry.logger_name, __name__) self.assertIsInstance(entry.timestamp, datetime) self.assertEqual(entry.level, 'warning') self.assertEqual(entry.module, module_basename) -- cgit v1.2.3