Skip to content

Commit f6cd493

Browse files
authored
Merge pull request #74 from GabrielSalla/improve-monitor-routes
Improve monitor routes
2 parents a3408af + 0c06524 commit f6cd493

File tree

7 files changed

+170
-27
lines changed

7 files changed

+170
-27
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,18 @@ State machine-related issues often require several data checks and conditional l
6868
2. [Building a Monitor](./docs/monitor.md)
6969
1. [Sample Monitor](./docs/sample_monitor.md)
7070
3. [Querying data from databases](./docs/querying.md)
71-
4. [Registering a monitor](./docs/monitor_registering.md)
72-
5. Deployment
71+
4. [Validating a monitor](./docs/monitor_validating.md)
72+
5. [Registering a monitor](./docs/monitor_registering.md)
73+
6. Deployment
7374
1. [Configuration](./docs/configuration.md)
7475
2. [Configuration file](./docs/configuration_file.md)
7576
3. [How to run](./docs/how_to_run.md)
76-
6. [Monitoring Sentinela](./docs/monitoring_sentinela.md)
77-
7. [Plugins](./docs/plugins/plugins.md)
77+
7. [Monitoring Sentinela](./docs/monitoring_sentinela.md)
78+
8. [Plugins](./docs/plugins/plugins.md)
7879
1. [AWS](./docs/plugins/aws.md)
7980
2. [Postgres](./docs/plugins/postgres.md)
8081
2. [Slack](./docs/plugins/slack.md)
81-
8. Interacting with Sentinela
82+
9. Interacting with Sentinela
8283
1. [HTTP server](./docs/http_server.md)
83-
9. Special cases
84+
10. Special cases
8485
1. [Dropping issues](./docs/dropping_issues.md)

docs/http_server.md

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,113 @@ Exposes Prometheus-formatted metrics, enabling external monitoring and observabi
2323
# Interaction routes
2424
These routes are available only when the container deployment includes the **Controller** component.
2525

26+
## List monitors
27+
**`GET /monitors/list`**
28+
29+
Returns a list of all monitors currently registered with the `id`, `name` and `enabled` fields for each monitor.
30+
31+
Response example:
32+
```json
33+
[
34+
{
35+
"id": 123,
36+
"name": "monitor_name",
37+
"enabled": true
38+
},
39+
{
40+
"id": 124,
41+
"name": "another_monitor",
42+
"enabled": false
43+
}
44+
]
45+
```
46+
47+
## Get monitor
48+
**`GET /monitor/{monitor_name}`**
49+
50+
Returns the monitor details for the monitor with the provided `monitor_name`.
51+
52+
Response example:
53+
```json
54+
{
55+
"id": 123,
56+
"name": "monitor_name",
57+
"enabled": true,
58+
"code": "...",
59+
"additional_files": {"file_name.txt": "..."}
60+
}
61+
```
62+
2663
## Disable monitor
27-
**`POST /{monitor_name}/disable`**
64+
**`POST /monitor/{monitor_name}/disable`**
2865

2966
Disable the monitor with the provided `monitor_name`.
3067

3168
## Enable monitor
32-
**`POST /{monitor_name}/enable`**
69+
**`POST /monitor/{monitor_name}/enable`**
3370

3471
Enable the monitor with the provided `monitor_name`.
3572

73+
## Validate monitor
74+
**`POST /monitor/validate`**
75+
76+
Validate the monitor code provided without registering it.
77+
78+
For more information, check the [Validating a monitor](./monitor_validating.md) documentation.
79+
80+
Request body example:
81+
```json
82+
{
83+
"monitor_code": "...",
84+
}
85+
```
86+
87+
Response example:
88+
```json
89+
{
90+
"status": "monitor_validated"
91+
}
92+
```
93+
94+
## Register monitor
95+
**`POST /monitor/register/{monitor_name}`**
96+
97+
Register the monitor with the provided `monitor_name`.
98+
99+
For more information, check the [Registering a monitor](./monitor_registering.md) documentation.
100+
101+
Request body example:
102+
```json
103+
{
104+
"monitor_code": "...",
105+
"additional_files": {"file_name.txt": "..."}
106+
}
107+
```
108+
109+
Response example:
110+
```json
111+
{
112+
"status": "monitor_registered",
113+
"monitor_id": 123
114+
}
115+
```
116+
36117
## Acknowledge alert
37-
**`POST /{alert_id}/acknowledge`**
118+
**`POST /alert/{alert_id}/acknowledge`**
38119

39120
Acknowledge the alert with the provided `alert_id`.
40121

41122
## Lock alert
42-
**`POST /{alert_id}/lock`**
123+
**`POST /alert/{alert_id}/lock`**
43124

44125
Lock the alert with the provided `alert_id`.
45126

46127
## Solve alert
47-
**`POST /{alert_id}/solve`**
128+
**`POST /alert/{alert_id}/solve`**
48129

49130
Solve the alert with the provided `alert_id`.
50131

51132
## Drop issue
52-
**`POST /{issue_id}/drop`**
133+
**`POST /issue/{issue_id}/drop`**
53134

54135
Drop the issue with the provided `issue_id`.

docs/monitor_registering.md

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ A monitor consists of:
99
- **Optional Additional Files**: Supporting resources used during the monitor's execution, such as SQL query files or other data files.
1010

1111
## Registration Process
12-
To register a monitor, use the POST method with the `monitors/register/` route, providing all the required information in the request.
12+
```
13+
POST monitors/register/{monitor_name}
14+
```
1315

14-
1. **Request URL**:
15-
Format the URL as `monitors/register/{monitor_name}`, where `{monitor_name}` is the name of the monitor being created or updated.
16-
Example: `monitors/register/my_monitor`
16+
Parameters:
17+
- `{monitor_name}` is the name of the monitor being created or updated.
1718

18-
2. **Request Payload**:
19-
The payload should include the following fields:
20-
- `monitor_code`: The content of the monitor’s main `.py` file content.
21-
- `additional_files`: Optional field with an object where the keys are the names of additional files, and the values are their content.
19+
The payload should include the following fields:
20+
- `monitor_code`: The content of the monitor’s main `.py` file content.
21+
- `additional_files`: Optional field with an object where the keys are the names of additional files, and the values are their content.
2222

2323
Example:
2424
```json
@@ -30,6 +30,28 @@ Example:
3030
}
3131
```
3232

33+
## Responses
34+
The response will contain the status of the registration process. The field `status` will be set to `monitor_registered` if the monitor was successfully registered and the monitor id will be in the `monitor_id` field.
35+
36+
Example:
37+
```json
38+
{
39+
"status": "monitor_registered",
40+
"monitor_id": 123
41+
}
42+
```
43+
44+
If the registration fails, the `status` field will be set to `error` and the field `message` will contain the error message. Depending on the error, additional fields may be present to help diagnose the issue.
45+
46+
Example:
47+
```json
48+
{
49+
"status": "error",
50+
"message": "Module didn't pass check",
51+
"error": "Monitor 'my_monitor' has the following errors:\n 'monitor_options' is required"
52+
}
53+
```
54+
3355
## Monitor register tool
3456
To simplify the registration process, a Python script is available in the `tools` folder.
3557

docs/monitor_validating.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Validating a monitor
2+
Validating a monitor is a important step before registering it. This process ensures that the monitor code is correct and can be executed by Sentinela. This is useful when using a deployment pipeline to ensure that the monitor is correctly implemented before being deployed.
3+
4+
## Validation Process
5+
```
6+
POST monitors/validate/
7+
```
8+
9+
The payload should include the following fields:
10+
- `monitor_code`: The content of the monitor’s main `.py` file content.
11+
12+
Example:
13+
```json
14+
{
15+
"monitor_code": "...",
16+
}
17+
```
18+
19+
## Responses
20+
The response will contain the status of the validation process. The field `status` will be set to `monitor_validated` if the monitor was successfully validated.
21+
22+
Example:
23+
```json
24+
{
25+
"status": "monitor_validated",
26+
}
27+
```
28+
29+
If the validation fails, the `status` field will be set to `error` and the field `message` will contain the error message. Depending on the error, additional fields may be present to help diagnose the issue.
30+
31+
Example:
32+
```json
33+
{
34+
"status": "error",
35+
"message": "Module didn't pass check",
36+
"error": "Monitor has the following errors:\n 'monitor_options' is required"
37+
}
38+
```

src/components/http_server/monitor_routes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ async def monitor_validate(request: Request) -> Response:
141141
error_response = {
142142
"status": "error",
143143
"message": "Module didn't pass check",
144-
"error": e.get_error_message(),
144+
"error": e.get_error_message(include_monitor_name=False),
145145
}
146146
return web.json_response(error_response, status=400)
147147
except Exception as e:

src/components/monitors_loader/monitors_loader.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,12 @@ def __init__(self, monitor_name: str, errors_found: list[str], *args: object) ->
5151
self.monitor_name = monitor_name
5252
self.errors_found = errors_found
5353

54-
def get_error_message(self) -> str:
54+
def get_error_message(self, include_monitor_name: bool = True) -> str:
5555
"""Get the error message for the module validation errors"""
56-
error_message = f"Monitor '{self.monitor_name}' has the following errors:\n "
56+
if include_monitor_name:
57+
error_message = f"Monitor '{self.monitor_name}' has the following errors:\n "
58+
else:
59+
error_message = "Monitor has the following errors:\n "
5760
error_message += "\n ".join(self.errors_found)
5861
return error_message
5962

tests/components/http_server/test_monitor_routes.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,8 @@ async def test_monitor_validate_dataclass_validation_error():
263263
}
264264

265265

266-
async def test_monitor_validate_check_fail(mocker):
266+
async def test_monitor_validate_check_fail():
267267
"""The 'monitor validate' route should return an error if the provided module code is invalid"""
268-
check_monitor_spy: MagicMock = mocker.spy(monitors_loader, "check_monitor")
269-
270268
monitor_code = "import time"
271269

272270
request_payload = {"monitor_code": monitor_code}
@@ -279,7 +277,7 @@ async def test_monitor_validate_check_fail(mocker):
279277
"message": "Module didn't pass check",
280278
"error": "\n".join(
281279
[
282-
f"Monitor '{check_monitor_spy.call_args[0][0]}' has the following errors:",
280+
"Monitor has the following errors:",
283281
" 'monitor_options' is required",
284282
" 'issue_options' is required",
285283
" 'IssueDataType' is required",

0 commit comments

Comments
 (0)