Skip to content

Commit abf4738

Browse files
committed
Prefix all log messages with msgid (Postfix queue_id) if available
1 parent f705160 commit abf4738

File tree

10 files changed

+29
-15
lines changed

10 files changed

+29
-15
lines changed

.env.docker

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ SOCKET="0.0.0.0,10033"
1212
# SOCKET=/tmp/test.sock
1313
LOG_LEVEL=DEBUG
1414
# LOG_FILE=/tmp/policyd-rate-guard.log
15-
# LOG_MSG_PREFIX=True
15+
# LOG_MSG_PREFIX=False
1616
LOG_CONSOLE=True
1717
# SYSLOG=True

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ DB_DATABASE=policyd-rate-guard
1515
# SOCKET="[::1],10033" # Use this for IPv6 TCP socket
1616
# LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
1717
# LOG_FILE=/var/log/policyd-rate-guard/policyd-rate-guard.log
18-
# LOG_MSG_PREFIX=True # True or False (default: True) - Prefix log messages with caller filename and class/method
18+
LOG_MSG_PREFIX=False # True or False (default: True) - Prefix log messages with caller filename and class/method
1919
LOG_CONSOLE=True # True or False (default: False) - Output logs to console (stderr)
2020
# SYSLOG=True # True or False (default: False) - Send logs to syslog
2121
# SENTRY_DSN=https://**********.ingest.sentry.io/XXXXXXXXXXXXXXXX # Your Sentry DSN (default: None)

.env.github

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ SOCKET="127.0.0.1,10033"
1212
# SOCKET=/tmp/test.sock
1313
LOG_LEVEL=ERROR
1414
# LOG_FILE=/tmp/policyd-rate-guard.log
15-
# LOG_MSG_PREFIX=True
15+
# LOG_MSG_PREFIX=False
1616
LOG_CONSOLE=True
1717
# SYSLOG=True

.env.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ DB_DATABASE=policyd-rate-guard
1111
SOCKET="127.0.0.1,10033"
1212
LOG_LEVEL=ERROR
1313
# LOG_FILE=/tmp/policyd-rate-guard.log
14-
# LOG_MSG_PREFIX=True
14+
# LOG_MSG_PREFIX=False
1515
LOG_CONSOLE=True
1616
# SYSLOG=True
1717
# SENTRY_DSN=https://**********.ingest.sentry.io/XXXXXXXXXXXXXXXX

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
**Added:**
66

7-
- Added `LOG_MSG_PREFIX` (boolean) environment variable which is enabled by default. Prefix all log messages with a prefix containing information about the calling filename, class, and function name, e.g. `ratelimit.py Ratelimit.update() - `.
7+
- Added `LOG_MSG_PREFIX` (boolean) environment variable which is enabled by default. Prefix all log messages with a prefix containing information about the calling filename, class, and function name, e.g. `ratelimit.py Ratelimit.update() - `.
8+
- Always prepend log messages with message ID (Postfix `queue_id`) if available, independent from `LOG_MSG_PREFIX` feature being enabled/disabled.
89

910
**Fixed:**
1011

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ PolicydRateGuard can be fully configured through environment variables in `.env`
209209
- `LOG_FILE`
210210
Set a logfile path, e.g. `/var/log/policyd-rate-guard/policyd-rate-guard.log`. This can be used in addition to enabling `SYSLOG` and/or `LOG_CONSOLE`, to log into a separate log file. Defaults to `None` (commented out).
211211
- `LOG_MSG_PREFIX`
212-
Prefix all log messages with a prefix containing information about the calling filename, class, and function name, e.g. `ratelimit.py Ratelimit.update() - `. Defaults to `True`.
212+
Prefix all log messages with a prefix containing information about the calling filename, class, and function name, e.g. `ratelimit.py Ratelimit.update() - `. We recommend to disable this on a production deployment (as it's more kind of debug information that shouldn't bloat our logs). Defaults to `True`.
213213
- `LOG_CONSOLE` (bool)
214214
Send logs to console (on `stderr`). This can be used in addition to enabling `LOG_FILE` and/or `SYSLOG`. Possible values: `True` or `False`. Defaults to `False`.
215215
- `SYSLOG` (bool)

app/handler.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def __init__(self, conn: object, addr: str, conf: object, logger: object, db: ob
99
self.conn = conn
1010
self.addr = addr
1111
self.conf = conf
12-
self.logger = logger # TODO: Add msgid to logger
12+
self.logger = logger
1313
self.db = db
1414
try:
1515
self.handle()
@@ -39,6 +39,9 @@ def handle(self):
3939
except ValueError: # Needed to ignore lines without "=" (e.g. the final two empty lines)
4040
pass
4141

42+
# Add msgid to logger
43+
self.logger.msgid = request.get('queue_id')
44+
4245
# Break no sasl_username was found (e.g. on incoming mail on port 25)
4346
if not request.get('sasl_username'):
4447
self.logger.debug('sasl_username is empty, accepting message and reply with DUNNO')
@@ -77,8 +80,7 @@ def handle(self):
7780

7881
# Detailed log message in the following format:
7982
# TEST1234567: client=unknown[8.8.8.8], helo=myCLIENTPC, sasl_method=PLAIN, sasl_username=test@example.com, recipient_count=1, curr_count=2/1000, status=ACCEPTED
80-
log_message = '{}: client={}[{}], helo={}, sasl_method={}, sasl_username={}, from={}, to={}, recipient_count={}, curr_count={}/{}, status={}{}'.format(
81-
message.msgid,
83+
log_message = 'client={}[{}], helo={}, sasl_method={}, sasl_username={}, from={}, to={}, recipient_count={}, curr_count={}/{}, status={}{}'.format(
8284
message.client_name,
8385
message.client_address,
8486
request.get('helo_name'), # currently not stored in Message object or `messages` table
@@ -105,6 +107,7 @@ def handle(self):
105107
self.send_response('OK')
106108
self.logger.info(log_message)
107109

110+
self.logger.msgid = None # Reset msgid in logger
108111
self.conn.close()
109112

110113
def send_response(self, message: str = 'OK'):

app/logging.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@
55
from os import path
66

77
class PrefixedLogger(logging.Logger):
8+
"""Custom logger that prefixes messages with msgid, the filename, class and function name of the caller"""
9+
10+
msg_prefix = True
11+
msgid = None
12+
813
def __init__(self, name, level=logging.NOTSET):
914
super().__init__(name, level)
1015

1116
def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
12-
co_filename, co_class, co_function = self._get_caller_info()
13-
prefix = f"{path.basename(co_filename)} {co_class}.{co_function}() - "
17+
if self.msg_prefix:
18+
co_filename, co_class, co_function = self._get_caller_info()
19+
prefix = f"{path.basename(co_filename)} {co_class}.{co_function}() - "
20+
else:
21+
prefix = ''
22+
if self.msgid:
23+
prefix += f"{self.msgid}: "
1424
msg = prefix + msg
1525
super()._log(level, msg, args, exc_info, extra, stack_info)
1626

@@ -60,10 +70,10 @@ def get_logger(conf: Config):
6070
log_handlers.append(syslog)
6171

6272
# Set the custom logger class
63-
if conf.get('LOG_MSG_PREFIX', True):
64-
logging.setLoggerClass(PrefixedLogger)
73+
logging.setLoggerClass(PrefixedLogger)
6574
logging.basicConfig(level=log_level, format=log_format, handlers=log_handlers)
6675
logger = logging.getLogger('policyd-rate-guard')
6776
logger.setLevel(log_level)
77+
logger.msg_prefix = conf.get('LOG_MSG_PREFIX', True) # Enable/disable custom log message prefix feature
6878

6979
return logger

app/message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,5 @@ def is_blocked(self) -> bool:
7474
self.blocked = False
7575
return False
7676

77-
def get_props_description(self, props: list = ['msgid', 'sender', 'rcpt_count', 'from_addr', 'client_address', 'client_name'], separator: str = ' '):
77+
def get_props_description(self, props: list = ['sender', 'rcpt_count', 'from_addr', 'client_address', 'client_name'], separator: str = ' '):
7878
return separator.join(f"{name}={getattr(self, name)}" for name in props)

tests/test_app_message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def test_store(self) -> None:
6868

6969
def test_get_props_description(self) -> None:
7070
desc = self.message.get_props_description()
71-
self.assertEqual(desc, 'msgid=TEST1234567 sender=test@example.com rcpt_count=3 from_addr=test@example.com client_address=172.19.0.2 client_name=unknown')
71+
self.assertEqual(desc, 'sender=test@example.com rcpt_count=3 from_addr=test@example.com client_address=172.19.0.2 client_name=unknown')
7272
desc = self.message.get_props_description(['msgid'])
7373
self.assertEqual(desc, 'msgid=TEST1234567')
7474
desc = self.message.get_props_description(['msgid', 'sender', 'rcpt_count'])

0 commit comments

Comments
 (0)