Add support for healthchecks "log" feature #628

Closed
opened 2023-01-09 09:48:54 +00:00 by xLogiiCx · 9 comments

What I'm trying to do and why

I do not know exactly when, but i recently noticed, that Healthchecks.io introduced a feature where you can send logging information to Healthchecks.io without signalling success or failure. It would be great to add this feature to borgbackup.

Other notes / implementation ideas

My Idea was, that if you use the logging feature you can decide if you want your logs pushed to Healthchecks or if you just want to log success/failure. And if the attached Message for success/failure is not used then a user could use it for a custom message. This is imo especially useful for users having multiple backup configurations / run per-application backups.

Environment

borgmatic version: 1.7.5

borgmatic installation method: yay

Borg version: borg 1.2.3

Python version: Python 3.10.9

operating system and version: Linux x86_64 6.1.4-zen2-1-zen

#### What I'm trying to do and why I do not know exactly when, but i recently noticed, that Healthchecks.io introduced a feature where you can send logging information to Healthchecks.io without signalling success or failure. It would be great to add this feature to borgbackup. #### Other notes / implementation ideas My Idea was, that if you use the logging feature you can decide if you want your logs pushed to Healthchecks or if you just want to log success/failure. And if the attached Message for success/failure is not used then a user could use it for a custom message. This is imo especially useful for users having multiple backup configurations / run per-application backups. #### Environment **borgmatic version:** 1.7.5 **borgmatic installation method:** yay **Borg version:** borg 1.2.3 **Python version:** Python 3.10.9 **operating system and version:** Linux x86_64 6.1.4-zen2-1-zen
witten added the
good first issue
label 2023-02-04 17:14:17 +00:00
Contributor

Is this issue taken or can I work on this issue?

Is this issue taken or can I work on this issue?
Owner

Nobody is working on this right now, so feel free to jump in! I'm not exactly sure on the design of this ticket, so it may be worth discussing your plans here before jumping into writing code. That may prevent some back and forth on an eventual pull request.

Nobody is working on this right now, so feel free to jump in! I'm not exactly sure on the design of this ticket, so it may be worth discussing your plans here before jumping into writing code. That may prevent some back and forth on an eventual pull request.
Owner

FYI, I think this is the Healthchecks feature mentioned in this ticket: https://healthchecks.io/docs/http_api/#log-uuid

FYI, I think this is the Healthchecks feature mentioned in this ticket: https://healthchecks.io/docs/http_api/#log-uuid
Owner

Hey @Soumik_Dutta.. Just checking in. Have you had a chance to look into this? Let me know if there's anything I can do to help.

Hey @Soumik_Dutta.. Just checking in. Have you had a chance to look into this? Let me know if there's anything I can do to help.
Contributor

Hello,

Yes, I looked into the docs as you provided https://healthchecks.io/docs/http_api/#log-uuid, and I think the steps to implement will be :

  1. In the file borgmatic/hooks/monitor.py add log to:
class State(Enum):
    START = 1
    FINISH = 2
    FAIL = 3
    LOG = 4
  1. In the file borgmatic/hooks/healthchecks.py add log level to:
MONITOR_STATE_TO_HEALTHCHECKS = {
    monitor.State.START: 'start',
    monitor.State.FINISH: None,  # Healthchecks doesn't append to the URL for the finished state.
    monitor.State.FAIL: 'fail',
    monitor.State.LOG: 'log',
}
  1. Add the state to the if condition
if state in (monitor.State.FINISH, monitor.State.FAIL, monitor.State.LOG):
        payload = format_buffered_logs_for_payload()
    else:
        payload = ''
  1. Register the state in borgmatic/config/schema.yaml :
enum:
  - start
  - finish
  - fail
  - log

So, now it has basic support for sending payload without signalling success or failure.

However to trigger this, we have to add the snippet to /home/sm/Public/Sock/borgmatic/borgmatic/commands/borgmatic.py :

if not encountered_error:
        try:
            if using_primary_action:
                dispatch.call_hooks(
                    'ping_monitor',
                    hooks,
                    config_filename,
                    monitor.MONITOR_HOOK_NAMES,
                    monitor.State.LOG,
                    monitoring_log_level,
                    global_arguments.dry_run,
                )

I have tested the code with the above changes, and the logs are getting successfully logged in Healthcheck

Hello, Yes, I looked into the docs as you provided https://healthchecks.io/docs/http_api/#log-uuid, and I think the steps to implement will be : 1. In the file `borgmatic/hooks/monitor.py` add `log` to: ```python class State(Enum): START = 1 FINISH = 2 FAIL = 3 LOG = 4 ``` 2. In the file `borgmatic/hooks/healthchecks.py` add `log` level to: ```python MONITOR_STATE_TO_HEALTHCHECKS = { monitor.State.START: 'start', monitor.State.FINISH: None, # Healthchecks doesn't append to the URL for the finished state. monitor.State.FAIL: 'fail', monitor.State.LOG: 'log', } ``` 4. Add the state to the `if` condition ```python if state in (monitor.State.FINISH, monitor.State.FAIL, monitor.State.LOG): payload = format_buffered_logs_for_payload() else: payload = '' ``` 5. Register the state in `borgmatic/config/schema.yaml` : ```yaml enum: - start - finish - fail - log ``` So, now it has basic support for sending `payload` without signalling success or failure. However to trigger this, we have to add the snippet to `/home/sm/Public/Sock/borgmatic/borgmatic/commands/borgmatic.py` : ```python if not encountered_error: try: if using_primary_action: dispatch.call_hooks( 'ping_monitor', hooks, config_filename, monitor.MONITOR_HOOK_NAMES, monitor.State.LOG, monitoring_log_level, global_arguments.dry_run, ) ``` I have tested the code with the above changes, and the logs are getting successfully logged in Healthcheck
Contributor

I have few questions about this:

  1. What should be the ideal behavior of sending logs, i.e. when should this get triggered?
  2. Do I have to add tests for this?
  3. (I am currently testing but any pointers will be helpful) Do I have to implement the log level for other services mentioned here?
MONITOR_HOOK_NAMES = ('healthchecks', 'cronitor', 'cronhub', 'pagerduty', 'ntfy')
I have few questions about this: 1. What should be the ideal behavior of sending logs, i.e. when should this get triggered? 2. Do I have to add tests for this? 3. (I am currently testing but any pointers will be helpful) Do I have to implement the `log` level for other services mentioned here? ```python MONITOR_HOOK_NAMES = ('healthchecks', 'cronitor', 'cronhub', 'pagerduty', 'ntfy') ```
Owner

Your proposed approach looks great! Thanks for taking the time to detail it. To answer your questions:

What should be the ideal behavior of sending logs, i.e. when should this get triggered?

Given the requirements of the ticket, my suggestion is to send the logs regardless of whether an error was encountered or not. So that could mean moving your dispatch.call_hooks() call to before the if not encountered_error: check. (You'd probably need a try/except there as well.) We can always get into the details in the pull request.

Do I have to add tests for this?

That would be great, yes. You can look at the existing tests in unit/commands/test_borgmatic.py for inspiration. They should hopefully be straight-forward to add. But if not, I'd be happy to help.

(I am currently testing but any pointers will be helpful) Do I have to implement the log level for other services mentioned here?

It would be good to make sure that the other monitoring hooks do something when they receive the LOG state. But they don't have to implement actual logging. For instance, it would be totally fine if when they receive a LOG state, they immediately return since logging may not be implemented for those hooks.

Let me know if any other questions come up as you work on this. I really appreciate the effort!

Your proposed approach looks great! Thanks for taking the time to detail it. To answer your questions: > What should be the ideal behavior of sending logs, i.e. when should this get triggered? Given the requirements of the ticket, my suggestion is to send the logs _regardless_ of whether an error was encountered or not. So that could mean moving your `dispatch.call_hooks()` call to *before* the `if not encountered_error:` check. (You'd probably need a `try`/`except` there as well.) We can always get into the details in the pull request. > Do I have to add tests for this? That would be great, yes. You can look at the existing tests in `unit/commands/test_borgmatic.py` for inspiration. They should hopefully be straight-forward to add. But if not, I'd be happy to help. > (I am currently testing but any pointers will be helpful) Do I have to implement the log level for other services mentioned here? It would be good to make sure that the other monitoring hooks do _something_ when they receive the `LOG` state. But they don't have to implement actual logging. For instance, it would be totally fine if when they receive a `LOG` state, they immediately return since logging may not be implemented for those hooks. Let me know if any other questions come up as you work on this. I really appreciate the effort!
Owner

Implemented in #645! This will be part of the next release.

Implemented in #645! This will be part of the next release.
Owner

Just released in borgmatic 1.7.9!

Just released in borgmatic 1.7.9!
Sign in to join this conversation.
No Milestone
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: borgmatic-collective/borgmatic#628
No description provided.