diff --git a/NEWS b/NEWS index ea519dbfb..d02997b01 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ logs to send to the Healthchecks server. * #402: Remove the error when "archive_name_format" is specified but a retention prefix isn't. * #420: Warn when an unsupported variable is used in a hook command. + * #525: Add Healthchecks monitoring hook "skip_states" option to disable pinging for particular + monitoring states. * #528: Improve the error message when a configuration override contains an invalid value. * #531: BREAKING: When deep merging common configuration, merge colliding list values by appending them. Previously, one list replaced the other. @@ -12,7 +14,7 @@ * Add a randomized delay to the sample systemd timer to spread out the load on a server. * Change the configuration format for borgmatic monitoring hooks (Healthchecks, Cronitor, PagerDuty, and Cronhub) to specify the ping URL / integration key as a named option. The intent - is to support additional options in the future. This change is backwards-compatible. + is to support additional options (some in this release). This change is backwards-compatible. * Add emojis to documentation table of contents to make it easier to find particular how-to and reference guides at a glance. diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index 079b789fd..35cb38e14 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -901,6 +901,19 @@ properties: send all logs and disable this truncation. Defaults to 100000. example: 200000 + skip_states: + type: array + items: + type: string + enum: + - start + - finish + - fail + uniqueItems: true + description: | + List of one or more monitoring states to skip + pinging for: "start", "finish", and/or "fail". + Defaults to pinging for all states. description: | Configuration for a monitoring integration with Healthchecks. Create an account at https://healthchecks.io diff --git a/borgmatic/hooks/healthchecks.py b/borgmatic/hooks/healthchecks.py index 538965589..7b562615e 100644 --- a/borgmatic/hooks/healthchecks.py +++ b/borgmatic/hooks/healthchecks.py @@ -98,6 +98,12 @@ def ping_monitor(hook_config, config_filename, state, monitoring_log_level, dry_ ) dry_run_label = ' (dry run; not actually pinging)' if dry_run else '' + if state.name.lower() in hook_config.get('skip_states', []): + logger.info( + f'{config_filename}: Skipping Healthchecks {state.name.lower()} ping due to configured skip states' + ) + return + healthchecks_state = MONITOR_STATE_TO_HEALTHCHECKS.get(state) if healthchecks_state: ping_url = '{}/{}'.format(ping_url, healthchecks_state) diff --git a/tests/unit/hooks/test_healthchecks.py b/tests/unit/hooks/test_healthchecks.py index d07b71ae7..3a626cc55 100644 --- a/tests/unit/hooks/test_healthchecks.py +++ b/tests/unit/hooks/test_healthchecks.py @@ -185,3 +185,33 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url(): monitoring_log_level=1, dry_run=True, ) + + +def test_ping_monitor_with_skip_states_does_not_hit_ping_url(): + flexmock(module).should_receive('Forgetful_buffering_handler') + hook_config = {'ping_url': 'https://example.com', 'skip_states': ['start']} + flexmock(module.requests).should_receive('post').never() + + module.ping_monitor( + hook_config, + 'config.yaml', + state=module.monitor.State.START, + monitoring_log_level=1, + dry_run=True, + ) + + +def test_ping_monitor_hits_ping_url_with_non_matching_skip_states(): + flexmock(module).should_receive('Forgetful_buffering_handler') + hook_config = {'ping_url': 'https://example.com', 'skip_states': ['finish']} + flexmock(module.requests).should_receive('post').with_args( + 'https://example.com/start', data=''.encode('utf-8') + ) + + module.ping_monitor( + hook_config, + 'config.yaml', + state=module.monitor.State.START, + monitoring_log_level=1, + dry_run=False, + )