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 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.
- [ ] Last seen agents
- [ ] donner un aperçu rapide de létat de la supervision.
- [ ] Allow passing a dict to check
- [ ] Rename error in unexpected error
- [ ] Use background tasks for alerting
- [ ] Delete outdated tasks from config

View file

@ -64,13 +64,13 @@ def start(host, port, reload, log_config):
@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(
"--max-lock-seconds",
default=100,
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)
- 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):
# Get the id of the oldest result to keep, then delete all results older than that
subquery = (
db.query(Result.id).order_by(desc(Result.id)).limit(max_results).subquery()
)
min_id = db.query(func.min(subquery.c.id)).scalar()
if min_id:
deleted = db.query(Result).where(Result.id < min_id).delete()
db.commit()
else:
deleted = 0
tasks = db.query(Task).all()
deleted = 0
for task in tasks:
# Get the id of the oldest result to keep
subquery = (
db.query(Result.id)
.filter(Result.task_id == task.id)
.order_by(desc(Result.id))
.limit(max_results)
.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

View file

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

View file

@ -7,13 +7,28 @@ from argos.server.models import Result, Task
@pytest.mark.asyncio
async def test_remove_old_results(db, ten_results):
assert db.query(Result).count() == 10
async def test_remove_old_results(db, ten_tasks):
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)
assert deleted == 8
assert db.query(Result).count() == 2
# We should keep the last two results
assert db.query(Result).all() == ten_results[-2:]
assert deleted == 30
assert db.query(Result).count() == 20
for task in ten_tasks:
assert db.query(Result).filter(Result.task == task).count() == 2
@pytest.mark.asyncio