Skip to content

Commit 1dd457a

Browse files
committed
Database cleanup job now also purges old messages, introduced MESSAGE_RETENTION env var
get ready for v0.6.1 release
1 parent 5d5e0ba commit 1dd457a

File tree

6 files changed

+46
-4
lines changed

6 files changed

+46
-4
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ LOG_CONSOLE=True # True or False (default: False) - Output logs to console (stde
2727
# SYSLOG=True # True or False (default: False) - Send logs to syslog
2828
# SENTRY_DSN=https://**********.ingest.sentry.io/XXXXXXXXXXXXXXXX # Your Sentry DSN (default: None)
2929
# SENTRY_ENVIRONMENT=prod
30+
# MESSAGE_RETENTION=90 # How many days to keep messages in the database (default: 0, never delete)

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# CHANGELOG
22

3+
## [v0.6.1](https://github.com/onlime/policyd-rate-guard/releases/tag/v0.6.1) (2023-09-06)
4+
5+
**Improved:**
6+
7+
- Code cleanup: Using relative imports.
8+
- Code cleanup: Simplified parsing of data using dict comprehension in `Handler`.
9+
- Refactoring: moved `PrefixedLogger` class into its own file.
10+
11+
**Added:**
12+
13+
- Database cleanup job now also purges old messages, if enabled through `MESSAGE_RETENTION` env var.
14+
- Introduced new environment variable `MESSAGE_RETENTION` to control number of days to keep messages in the database. Defaults to `0` (keep forever).
15+
316
## [v0.6.0](https://github.com/onlime/policyd-rate-guard/releases/tag/v0.6.0) (2023-09-01)
417

518
**Improved:**

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ PolicydRateGuard can be fully configured through environment variables in `.env`
227227
Your Sentry DSN in the following form: `https://**********.ingest.sentry.io/XXXXXXXXXXXXXXXX`. Defaults to `None` (commented out).
228228
- `SENTRY_ENVIRONMENT`
229229
Sentry environment. Suggested values: `dev` or `prod`, but can be any custom string. Defaults to `dev`.
230+
- `MESSAGE_RETENTION`
231+
How many days to keep messages in the database. Defaults to `0` (never delete).
230232

231233
You may also tune the database connection pooling by modifying the following environment variables (defaults are fine for most environments, and you'll find e detailed description in the [DBUtils PooledDB](https://webwareforpython.github.io/DBUtils/main.html#pooleddb-pooled-db-1) usage docs):
232234

@@ -284,7 +286,7 @@ $ cp yoyo.ini.docker yoyo.ini # & Adjust the settings
284286
(venv)$ python3 run.py
285287
```
286288

287-
To cleanup (reset all counters and quotas) the database, run:
289+
To cleanup (reset all counters and quotas and purge old messages if `MESSAGE_RETENTION` is set) the database, run:
288290

289291
```bash
290292
(venv)$ python3 cleanup.py
@@ -401,6 +403,7 @@ Planned features (coming soon):
401403
- [x] **Sentry** integration for exception reporting
402404
- [x] **Ansible role** for easy production deployment
403405
- [x] **Github workflow** for CI/testing
406+
- [x] **Message retention**: Expire/purge old messages, configurable via env var `MESSAGE_RETENTION` (defaults to keep forever)
404407
- [ ] Implement a **configurable webhook API** call for notification to sender on reaching quota limit (on first block) to external service.
405408
- [ ] **Publish package** to [PyPI](https://pypi.org/) (Might need some restructuring. Any help greatly appreciated!)
406409

app/message.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,16 @@ def is_blocked(self) -> bool:
7676

7777
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)
79+
80+
@staticmethod
81+
def purge_old_messages(db_pool: object, logger: object, days: int = 90) -> None:
82+
"""Purge old messages"""
83+
logger.debug('Purge old messages')
84+
db = db_pool.connection()
85+
try:
86+
deleted = db.cursor().execute('DELETE FROM `messages` WHERE `created_at` < DATE_SUB(CURDATE(), INTERVAL %s DAY)', (days,))
87+
db.commit()
88+
if deleted > 0:
89+
logger.info('Deleted {} old messages (retention: {} days)'.format(deleted, days))
90+
finally:
91+
db.close()

cleanup.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,27 @@
22
from app.logging import get_logger
33
from app.db import DbConnectionPool
44
from app.ratelimit import Ratelimit
5+
from app.message import Message
56

67
class Cleaner:
78

89
def __init__(self, conf: object = None) -> None:
910
self.conf = conf or Config()
1011
self.logger = get_logger(self.conf)
1112
self.db_pool = DbConnectionPool(self.conf)
13+
self.logger.debug('Cleaning up database')
14+
self.reset_counters()
1215
self.cleanup()
1316

14-
def cleanup(self) -> None:
15-
"""Cleanup database"""
16-
self.logger.debug('Cleaning up database')
17+
def reset_counters(self) -> None:
18+
"""Reset counters"""
1719
Ratelimit.reset_all_counters(self.db_pool, self.logger)
1820

21+
def cleanup(self) -> None:
22+
"""Cleanup database"""
23+
message_retention = int(self.conf.get('MESSAGE_RETENTION', 0))
24+
if message_retention > 0:
25+
Message.purge_old_messages(self.db_pool, self.logger, message_retention)
1926

2027
if __name__ == '__main__': # pragma: no cover
2128
Cleaner()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- update indexes
2+
-- depends: 20230827_01_o7RGx-update-table-ratelimits
3+
4+
ALTER TABLE `ratelimits` RENAME INDEX `idx_sender` TO `ratelimits_sender_unique`;
5+
ALTER TABLE `messages` ADD INDEX `messages_created_at_index` (`created_at`);

0 commit comments

Comments
 (0)