argos server cleandb now keep a number of results per task

This commit is contained in:
Alexis Métaireau 2023-10-20 02:40:06 +02:00
parent 9d4dfd2555
commit 5bca4fa261
5 changed files with 61 additions and 23 deletions

View file

@ -1,15 +1,27 @@
# Argos monitoring # Argos monitoring
Argos is an HTTP monitoring service. It allows you to define a list of websites to monitor, and a list of checks to run on these websites. It will then run these checks periodically, and alert you if something goes wrong. An HTTP monitoring service.
See the online documentation at http://framasoft.frama.io/framaspace/argos 1. Define a list of websites to monitor
2. Specify a list of checks to run on these websites.
3. Argos will run the checks periodically and alert you if something goes wrong.
Todo: Internally, a HTTP API is exposed, and a job queue is used to distribute the checks to the agents.
- [Online documentation](http://framasoft.frama.io/framaspace/argos)
- [Issue tracker](https://framagit.org/framasoft/framaspace/argos/-/issues)
## Resquirements
- **Python**: 3.11+
- **Backends**: SQLite (development), PostgreSQL 14+ (production)
## Todo:
- [ ] Cleandb should keep max number of results by task
- [ ] Do not return empty list on / when no results from agents. - [ ] Do not return empty list on / when no results from agents.
- [ ] Last seen agents - [ ] Last seen agents
- [ ] donner un aperçu rapide de létat de la supervision. - [ ] donner un aperçu rapide de létat de la supervision.
- [ ] Allow passing a dict to check
- [ ] Rename error in unexpected error - [ ] Rename error in unexpected error
- [ ] Use background tasks for alerting - [ ] Use background tasks for alerting
- [ ] Delete outdated tasks from config - [ ] Delete outdated tasks from config

View file

@ -64,13 +64,13 @@ def start(host, port, reload, log_config):
@server.command() @server.command()
@click.option("--max-results", default=100, help="Maximum number of results to keep") @click.option("--max-results", default=100, help="Number of results per tasks to keep")
@click.option( @click.option(
"--max-lock-seconds", "--max-lock-seconds",
default=100, default=100,
help="The number of seconds after which a lock is considered stale", help="The number of seconds after which a lock is considered stale",
) )
def clean(max_results, max_lock_seconds): def cleandb(max_results, max_lock_seconds):
"""Clean the database (to run routinely) """Clean the database (to run routinely)
- Removes old results from the database. - Removes old results from the database.

View file

@ -117,16 +117,27 @@ async def get_severity_counts(db: Session):
async def remove_old_results(db: Session, max_results: int): async def remove_old_results(db: Session, max_results: int):
# Get the id of the oldest result to keep, then delete all results older than that tasks = db.query(Task).all()
subquery = ( deleted = 0
db.query(Result.id).order_by(desc(Result.id)).limit(max_results).subquery() for task in tasks:
) # Get the id of the oldest result to keep
min_id = db.query(func.min(subquery.c.id)).scalar() subquery = (
if min_id: db.query(Result.id)
deleted = db.query(Result).where(Result.id < min_id).delete() .filter(Result.task_id == task.id)
db.commit() .order_by(desc(Result.id))
else: .limit(max_results)
deleted = 0 .subquery()
)
min_id = db.query(func.min(subquery.c.id)).scalar()
# Delete all the results older than min_id
if min_id:
deleted += (
db.query(Result)
.where(Result.id < min_id, Result.task_id == task.id)
.delete()
)
db.commit()
return deleted return deleted

View file

@ -102,7 +102,7 @@ Options:
### Server clean ### Server clean
<!-- <!--
.. [[[cog .. [[[cog
help(["server", "clean", "--help"]) help(["server", "cleandb", "--help"])
.. ]]] --> .. ]]] -->
```man ```man

View file

@ -7,13 +7,28 @@ from argos.server.models import Result, Task
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_remove_old_results(db, ten_results): async def test_remove_old_results(db, ten_tasks):
assert db.query(Result).count() == 10 for task in ten_tasks:
for i in range(5):
result = Result(
submitted_at=datetime.now(),
status="success",
context={"foo": "bar"},
task=task,
agent_id="test",
severity="ok",
)
db.add(result)
db.commit()
# So we have 5 results per tasks
assert db.query(Result).count() == 50
# Keep only 2
deleted = await queries.remove_old_results(db, 2) deleted = await queries.remove_old_results(db, 2)
assert deleted == 8 assert deleted == 30
assert db.query(Result).count() == 2 assert db.query(Result).count() == 20
# We should keep the last two results for task in ten_tasks:
assert db.query(Result).all() == ten_results[-2:] assert db.query(Result).filter(Result.task == task).count() == 2
@pytest.mark.asyncio @pytest.mark.asyncio