mirror of
https://framagit.org/framasoft/framaspace/argos.git
synced 2025-04-28 18:02:41 +02:00
Merge branch 'quick-overview' into 'main'
💄 — Quick supervision overview on homepage
See merge request framasoft/framaspace/argos!7
This commit is contained in:
commit
e652659fb6
11 changed files with 135 additions and 77 deletions
|
@ -19,7 +19,7 @@ Internally, a HTTP API is exposed, and a job queue is used to distribute the che
|
|||
## Todo:
|
||||
|
||||
- [ ] Do not return empty list on / when no results from agents.
|
||||
- [ ] donner un aperçu rapide de l’état de la supervision.
|
||||
- [X] 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
|
||||
|
@ -29,4 +29,4 @@ Internally, a HTTP API is exposed, and a job queue is used to distribute the che
|
|||
- [ ] Un flag de configuration permet d’ajouter automatiquement un job de vérification de redirection 301 de la version HTTP vers HTTPS
|
||||
- [ ] add an "unknown" severity for check errors
|
||||
- [ ] Add a way to specify the severity of the alerts in the config
|
||||
- [ ] Add a command to generate new authentication token
|
||||
- [ ] Add a command to generate new authentication token
|
||||
|
|
|
@ -105,7 +105,7 @@ async def update_from_config(db: Session, config: schemas.Config):
|
|||
db.commit()
|
||||
|
||||
|
||||
async def get_severity_counts(db: Session):
|
||||
async def get_severity_counts(db: Session) -> dict:
|
||||
# Get the last result of each task
|
||||
subquery = (
|
||||
db.query(Result.task_id, func.max(Result.id).label("max_result_id"))
|
||||
|
@ -122,6 +122,10 @@ async def get_severity_counts(db: Session):
|
|||
|
||||
# Execute the query and fetch the results
|
||||
task_counts_by_severity = query.all()
|
||||
|
||||
counts_dict = dict(task_counts_by_severity)
|
||||
for key in ("ok", "warning", "critical"):
|
||||
counts_dict.setdefault(key, 0)
|
||||
return task_counts_by_severity
|
||||
|
||||
|
||||
|
|
|
@ -73,8 +73,4 @@ async def get_stats(db: Session = Depends(get_db)):
|
|||
@route.get("/severities")
|
||||
async def get_severity_counts(db: Session = Depends(get_db)):
|
||||
"""Returns the number of results per severity"""
|
||||
counts = await queries.get_severity_counts(db)
|
||||
counts_dict = dict(counts)
|
||||
for key in ("ok", "warning", "critical"):
|
||||
counts_dict.setdefault(key, 0)
|
||||
return counts_dict
|
||||
return await queries.get_severity_counts(db)
|
||||
|
|
|
@ -7,6 +7,7 @@ from sqlalchemy import desc
|
|||
from sqlalchemy.orm import Session, aliased
|
||||
|
||||
from argos.schemas import Config
|
||||
from argos.server import queries
|
||||
from argos.server.models import Result, Task
|
||||
from argos.server.routes.dependencies import get_config, get_db
|
||||
|
||||
|
@ -16,6 +17,23 @@ templates = Jinja2Templates(directory="argos/server/templates")
|
|||
|
||||
|
||||
@route.get("/")
|
||||
async def get_severity_counts(request: Request, db: Session = Depends(get_db)):
|
||||
"""Returns the number of results per severity"""
|
||||
counts_dict = await queries.get_severity_counts(db)
|
||||
|
||||
agents = db.query(Result.agent_id).distinct().all()
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"index.html",
|
||||
{
|
||||
"request": request,
|
||||
"counts_dict": counts_dict,
|
||||
"agents": agents,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@route.get("/details")
|
||||
async def read_tasks(request: Request, db: Session = Depends(get_db)):
|
||||
tasks = db.query(Task).order_by(Task.domain).all()
|
||||
|
||||
|
@ -46,7 +64,7 @@ async def read_tasks(request: Request, db: Session = Depends(get_db)):
|
|||
agents = db.query(Result.agent_id).distinct().all()
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"index.html",
|
||||
"details.html",
|
||||
{
|
||||
"request": request,
|
||||
"domains": domains,
|
||||
|
|
|
@ -2,4 +2,16 @@
|
|||
|
||||
code {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-index {
|
||||
font-size: 2rem;
|
||||
}
|
||||
.text-center,
|
||||
.grid-index {
|
||||
text-align: center;
|
||||
}
|
||||
.grid-index article {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
|
|
@ -9,13 +9,12 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for result in last_seen %}
|
||||
<tr>
|
||||
<td>{{ result.agent_id }}</td>
|
||||
<td>{{ result.submitted_at }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for result in last_seen %}
|
||||
<tr>
|
||||
<td>{{ result.agent_id }}</td>
|
||||
<td>{{ result.submitted_at }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Argos</title>
|
||||
<link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<div id="header">
|
||||
{% block title %}<a href="/"><h1 id="title">Argos monitoring</h1></a>{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Argos</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||
<link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<div id="header">
|
||||
{% block title %}
|
||||
<a href="/"><h1 id="title">Argos monitoring</h1></a>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div id="content">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
33
argos/server/templates/details.html
Normal file
33
argos/server/templates/details.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div id="domains" class="frame">
|
||||
<p>
|
||||
{{ domains | length}} domains,
|
||||
{{ total_task_count }} tasks,
|
||||
<a href="/agents">{{ agents | length }} agent{% if agents | length > 1 %}s{% endif %}</a>
|
||||
</p>
|
||||
<table id="domains-list" role="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Domain</th>
|
||||
<th class="today">Current status</th>
|
||||
<th>Last check</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody id="domains-body">
|
||||
{% for (domain, status) in domains %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/domain/{{ domain }}">{{ domain }}</a>
|
||||
</td>
|
||||
<td class="status highlight">
|
||||
{% if status == "ok" %}✅ OK {% elif statuts == "warning"%}⚠ Warning{% elif status == "critical"%}❌ Critical{% elif status == "to-process" %}⏱︎ Waiting for the jobs{% endif %}
|
||||
</td>
|
||||
<td>{{ last_checks.get(domain) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}<h2>{{domain}}</h2>{% endblock %}
|
||||
{% block title %}<h2>{{ domain }}</h2>{% endblock %}
|
||||
{% block content %}
|
||||
<div id="domains" class="frame">
|
||||
<table id="domains-list" role="grid">
|
||||
|
@ -19,12 +19,13 @@
|
|||
<td>{{ task.url }}</td>
|
||||
<td>{{ task.check }}</td>
|
||||
<td>{{ task.expected }}</td>
|
||||
<td class="status highlight"><a data-tooltip="Completed at {{ task.completed_at }}" href="/result/{{ task.last_result.id }}">{% if task.status == "success" %}✅ Success {% elif task.status == "error"%}⚠ Error{% elif task.status == "failure"%}❌ Failure{% endif %}</a></td>
|
||||
<td class="status highlight">
|
||||
<a data-tooltip="Completed at {{ task.completed_at }}" href="/result/{{ task.last_result.id }}">{% if task.status == "success" %}✅ Success {% elif task.status == "error"%}⚠ Error{% elif task.status == "failure"%}❌ Failure{% endif %}</a>
|
||||
</td>
|
||||
<td><a href="/task/{{task.id}}/results">view all</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,34 +2,27 @@
|
|||
{% block content %}
|
||||
<div id="domains" class="frame">
|
||||
<p>
|
||||
{{domains | length}} domains,
|
||||
{{ total_task_count }} tasks,
|
||||
<a href="/agents">{{ agents |length }} agent{% if agents|length > 1 %}s{% endif %}</a>
|
||||
<a href="/agents">{{ agents | length }} agent{% if agents| length > 1 %}s{% endif %}</a>
|
||||
</p>
|
||||
|
||||
<div class="container">
|
||||
<div class="grid grid-index">
|
||||
<article>
|
||||
<header>✅ OK </header>
|
||||
{{ counts_dict['ok'] }}
|
||||
</article>
|
||||
<article>
|
||||
<header> ⚠️ Warning</header>
|
||||
{{ counts_dict['warning'] }}
|
||||
</article>
|
||||
<article>
|
||||
<header>❌ Critical</header>
|
||||
{{ counts_dict['critical'] }}
|
||||
</article>
|
||||
</div>
|
||||
<p class="text-center">
|
||||
<a href="/details" role="button">Details</a>
|
||||
</p>
|
||||
|
||||
<table id="domains-list" role="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Domain</th>
|
||||
<th class="today">Current status</th>
|
||||
<th>Last check</th>
|
||||
</thead>
|
||||
|
||||
<tbody id="domains-body">
|
||||
{% for (domain, status) in domains %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/domain/{{domain}}">
|
||||
{{ domain }} </a>
|
||||
</td>
|
||||
|
||||
<td class="status highlight">{% if status == "ok" %}✅ OK {% elif statuts == "warning"%}⚠ Warning{% elif status == "critical"%}❌ Critical{% elif status == "to-process" %}⏱︎ Waiting for the jobs{% endif %}</td>
|
||||
<td>{{ last_checks.get(domain) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}<h2>{{result}}</h2>{% endblock %}
|
||||
{% block title %}<h2>{{ result }}</h2>{% endblock %}
|
||||
{% block content %}
|
||||
<dl>
|
||||
<dt>Task</dt>
|
||||
<dd>{{result.task}}</dd>
|
||||
<dd>{{ result.task }}</dd>
|
||||
<dt>Submitted at</dt>
|
||||
<dd>{{result.submitted_at}}</dd>
|
||||
<dd>{{ result.submitted_at }}</dd>
|
||||
<dt>Status</dt>
|
||||
<dd>{{result.status}}</dd>
|
||||
<dd>{{ result.status }}</dd>
|
||||
<dt>Severity</dt>
|
||||
<dd>{{result.severity}}</dd>
|
||||
<dd>{{ result.severity }}</dd>
|
||||
<dt>Context</dt>
|
||||
<dd>{{result.context}}</dd>
|
||||
<dd>{{ result.context }}</dd>
|
||||
</dl>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in a new issue