Browse Source

Customize Healthchecks log level via borgmatic "--monitoring-verbosity" flag (#277).

Dan Helfman 5 years ago
parent
commit
f66fd1caaa

+ 1 - 0
NEWS

@@ -1,5 +1,6 @@
 1.4.23.dev0
 1.4.23.dev0
  * #274: Add ~/.config/borgmatic.d as another configuration directory default.
  * #274: Add ~/.config/borgmatic.d as another configuration directory default.
+ * #277: Customize Healthchecks log level via borgmatic "--monitoring-verbosity" flag.
  * For "create" and "prune" actions, no longer list files or show detailed stats at verbosity 1. You
  * For "create" and "prune" actions, no longer list files or show detailed stats at verbosity 1. You
    can opt back in with "--files" or "--stats" flags.
    can opt back in with "--files" or "--stats" flags.
 
 

+ 7 - 0
borgmatic/commands/arguments.py

@@ -159,6 +159,13 @@ def parse_arguments(*unparsed_arguments):
         default=0,
         default=0,
         help='Log verbose progress to log file (from only errors to very verbose: -1, 0, 1, or 2). Only used when --log-file is given',
         help='Log verbose progress to log file (from only errors to very verbose: -1, 0, 1, or 2). Only used when --log-file is given',
     )
     )
+    global_group.add_argument(
+        '--monitoring-verbosity',
+        type=int,
+        choices=range(-1, 3),
+        default=1,
+        help='Log verbose progress to monitoring integrations that support logging (from only errors to very verbose: -1, 0, 1, or 2)',
+    )
     global_group.add_argument(
     global_group.add_argument(
         '--log-file',
         '--log-file',
         type=str,
         type=str,

+ 5 - 0
borgmatic/commands/borgmatic.py

@@ -53,6 +53,7 @@ def run_configuration(config_filename, config, arguments):
     encountered_error = None
     encountered_error = None
     error_repository = ''
     error_repository = ''
     prune_create_or_check = {'prune', 'create', 'check'}.intersection(arguments)
     prune_create_or_check = {'prune', 'create', 'check'}.intersection(arguments)
+    monitoring_log_level = verbosity_to_log_level(global_arguments.monitoring_verbosity)
 
 
     try:
     try:
         if prune_create_or_check:
         if prune_create_or_check:
@@ -62,6 +63,7 @@ def run_configuration(config_filename, config, arguments):
                 config_filename,
                 config_filename,
                 monitor.MONITOR_HOOK_NAMES,
                 monitor.MONITOR_HOOK_NAMES,
                 monitor.State.START,
                 monitor.State.START,
+                monitoring_log_level,
                 global_arguments.dry_run,
                 global_arguments.dry_run,
             )
             )
         if 'create' in arguments:
         if 'create' in arguments:
@@ -132,6 +134,7 @@ def run_configuration(config_filename, config, arguments):
                     config_filename,
                     config_filename,
                     monitor.MONITOR_HOOK_NAMES,
                     monitor.MONITOR_HOOK_NAMES,
                     monitor.State.FINISH,
                     monitor.State.FINISH,
+                    monitoring_log_level,
                     global_arguments.dry_run,
                     global_arguments.dry_run,
                 )
                 )
         except (OSError, CalledProcessError) as error:
         except (OSError, CalledProcessError) as error:
@@ -158,6 +161,7 @@ def run_configuration(config_filename, config, arguments):
                 config_filename,
                 config_filename,
                 monitor.MONITOR_HOOK_NAMES,
                 monitor.MONITOR_HOOK_NAMES,
                 monitor.State.FAIL,
                 monitor.State.FAIL,
+                monitoring_log_level,
                 global_arguments.dry_run,
                 global_arguments.dry_run,
             )
             )
         except (OSError, CalledProcessError) as error:
         except (OSError, CalledProcessError) as error:
@@ -601,6 +605,7 @@ def main():  # pragma: no cover
             verbosity_to_log_level(global_arguments.verbosity),
             verbosity_to_log_level(global_arguments.verbosity),
             verbosity_to_log_level(global_arguments.syslog_verbosity),
             verbosity_to_log_level(global_arguments.syslog_verbosity),
             verbosity_to_log_level(global_arguments.log_file_verbosity),
             verbosity_to_log_level(global_arguments.log_file_verbosity),
+            verbosity_to_log_level(global_arguments.monitoring_verbosity),
             global_arguments.log_file,
             global_arguments.log_file,
         )
         )
     except (FileNotFoundError, PermissionError) as error:
     except (FileNotFoundError, PermissionError) as error:

+ 1 - 1
borgmatic/hooks/cronhub.py

@@ -13,7 +13,7 @@ MONITOR_STATE_TO_CRONHUB = {
 }
 }
 
 
 
 
-def ping_monitor(ping_url, config_filename, state, dry_run):
+def ping_monitor(ping_url, config_filename, state, monitoring_log_level, dry_run):
     '''
     '''
     Ping the given Cronhub URL, modified with the monitor.State. Use the given configuration
     Ping the given Cronhub URL, modified with the monitor.State. Use the given configuration
     filename in any log entries. If this is a dry run, then don't actually ping anything.
     filename in any log entries. If this is a dry run, then don't actually ping anything.

+ 1 - 1
borgmatic/hooks/cronitor.py

@@ -13,7 +13,7 @@ MONITOR_STATE_TO_CRONITOR = {
 }
 }
 
 
 
 
-def ping_monitor(ping_url, config_filename, state, dry_run):
+def ping_monitor(ping_url, config_filename, state, monitoring_log_level, dry_run):
     '''
     '''
     Ping the given Cronitor URL, modified with the monitor.State. Use the given configuration
     Ping the given Cronitor URL, modified with the monitor.State. Use the given configuration
     filename in any log entries. If this is a dry run, then don't actually ping anything.
     filename in any log entries. If this is a dry run, then don't actually ping anything.

+ 8 - 5
borgmatic/hooks/healthchecks.py

@@ -22,13 +22,14 @@ class Forgetful_buffering_handler(logging.Handler):
     first) once a particular capacity in bytes is reached.
     first) once a particular capacity in bytes is reached.
     '''
     '''
 
 
-    def __init__(self, byte_capacity):
+    def __init__(self, byte_capacity, log_level):
         super().__init__()
         super().__init__()
 
 
         self.byte_capacity = byte_capacity
         self.byte_capacity = byte_capacity
         self.byte_count = 0
         self.byte_count = 0
         self.buffer = []
         self.buffer = []
         self.forgot = False
         self.forgot = False
+        self.setLevel(log_level)
 
 
     def emit(self, record):
     def emit(self, record):
         message = record.getMessage() + '\n'
         message = record.getMessage() + '\n'
@@ -64,16 +65,18 @@ def format_buffered_logs_for_payload():
     return payload
     return payload
 
 
 
 
-def ping_monitor(ping_url_or_uuid, config_filename, state, dry_run):
+def ping_monitor(ping_url_or_uuid, config_filename, state, monitoring_log_level, dry_run):
     '''
     '''
     Ping the given Healthchecks URL or UUID, modified with the monitor.State. Use the given
     Ping the given Healthchecks URL or UUID, modified with the monitor.State. Use the given
-    configuration filename in any log entries. If this is a dry run, then don't actually ping
-    anything.
+    configuration filename in any log entries, and log to Healthchecks with the giving log level.
+    If this is a dry run, then don't actually ping anything.
     '''
     '''
     if state is monitor.State.START:
     if state is monitor.State.START:
         # Add a handler to the root logger that stores in memory the most recent logs emitted. That
         # Add a handler to the root logger that stores in memory the most recent logs emitted. That
         # way, we can send them all to Healthchecks upon a finish or failure state.
         # way, we can send them all to Healthchecks upon a finish or failure state.
-        logging.getLogger().addHandler(Forgetful_buffering_handler(PAYLOAD_LIMIT_BYTES))
+        logging.getLogger().addHandler(
+            Forgetful_buffering_handler(PAYLOAD_LIMIT_BYTES, monitoring_log_level)
+        )
         payload = ''
         payload = ''
 
 
     ping_url = (
     ping_url = (

+ 9 - 2
borgmatic/logger.py

@@ -110,7 +110,11 @@ def color_text(color, message):
 
 
 
 
 def configure_logging(
 def configure_logging(
-    console_log_level, syslog_log_level=None, log_file_log_level=None, log_file=None
+    console_log_level,
+    syslog_log_level=None,
+    log_file_log_level=None,
+    monitoring_log_level=None,
+    log_file=None,
 ):
 ):
     '''
     '''
     Configure logging to go to both the console and (syslog or log file). Use the given log levels,
     Configure logging to go to both the console and (syslog or log file). Use the given log levels,
@@ -122,6 +126,8 @@ def configure_logging(
         syslog_log_level = console_log_level
         syslog_log_level = console_log_level
     if log_file_log_level is None:
     if log_file_log_level is None:
         log_file_log_level = console_log_level
         log_file_log_level = console_log_level
+    if monitoring_log_level is None:
+        monitoring_log_level = console_log_level
 
 
     # Log certain log levels to console stderr and others to stdout. This supports use cases like
     # Log certain log levels to console stderr and others to stdout. This supports use cases like
     # grepping (non-error) output.
     # grepping (non-error) output.
@@ -160,5 +166,6 @@ def configure_logging(
         handlers = (console_handler,)
         handlers = (console_handler,)
 
 
     logging.basicConfig(
     logging.basicConfig(
-        level=min(console_log_level, syslog_log_level, log_file_log_level), handlers=handlers
+        level=min(console_log_level, syslog_log_level, log_file_log_level, monitoring_log_level),
+        handlers=handlers,
     )
     )

+ 3 - 3
docs/how-to/monitor-your-backups.md

@@ -131,9 +131,9 @@ the `on_error` hooks run, also tacking on logs including the error itself. But
 the logs are only included for errors that occur when a `prune`, `create`, or
 the logs are only included for errors that occur when a `prune`, `create`, or
 `check` action is run.
 `check` action is run.
 
 
-Note that borgmatic sends logs to Healthchecks by applying the maximum of any
-other borgmatic verbosity levels (`--verbosity`, `--syslog-verbosity`, etc.),
-as there is not currently a dedicated Healthchecks verbosity setting.
+You can customize the verbosity of the logs that are sent to Healthchecks with
+borgmatic's `--monitoring-verbosity` flag. The `--files` and `--stats` flags
+may also be of use. See `borgmatic --help` for more information.
 
 
 You can configure Healthchecks to notify you by a [variety of
 You can configure Healthchecks to notify you by a [variety of
 mechanisms](https://healthchecks.io/#welcome-integrations) when backups fail
 mechanisms](https://healthchecks.io/#welcome-integrations) when backups fail

+ 12 - 12
tests/unit/commands/test_borgmatic.py

@@ -13,7 +13,7 @@ def test_run_configuration_runs_actions_for_each_repository():
         expected_results[1:]
         expected_results[1:]
     )
     )
     config = {'location': {'repositories': ['foo', 'bar']}}
     config = {'location': {'repositories': ['foo', 'bar']}}
-    arguments = {'global': flexmock()}
+    arguments = {'global': flexmock(monitoring_verbosity=1)}
 
 
     results = list(module.run_configuration('test.yaml', config, arguments))
     results = list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -26,7 +26,7 @@ def test_run_configuration_calls_hooks_for_prune_action():
     flexmock(module.dispatch).should_receive('call_hooks').at_least().twice()
     flexmock(module.dispatch).should_receive('call_hooks').at_least().twice()
     flexmock(module).should_receive('run_actions').and_return([])
     flexmock(module).should_receive('run_actions').and_return([])
     config = {'location': {'repositories': ['foo']}}
     config = {'location': {'repositories': ['foo']}}
-    arguments = {'global': flexmock(dry_run=False), 'prune': flexmock()}
+    arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'prune': flexmock()}
 
 
     list(module.run_configuration('test.yaml', config, arguments))
     list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -37,7 +37,7 @@ def test_run_configuration_executes_and_calls_hooks_for_create_action():
     flexmock(module.dispatch).should_receive('call_hooks').at_least().twice()
     flexmock(module.dispatch).should_receive('call_hooks').at_least().twice()
     flexmock(module).should_receive('run_actions').and_return([])
     flexmock(module).should_receive('run_actions').and_return([])
     config = {'location': {'repositories': ['foo']}}
     config = {'location': {'repositories': ['foo']}}
-    arguments = {'global': flexmock(dry_run=False), 'create': flexmock()}
+    arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
 
 
     list(module.run_configuration('test.yaml', config, arguments))
     list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -48,7 +48,7 @@ def test_run_configuration_calls_hooks_for_check_action():
     flexmock(module.dispatch).should_receive('call_hooks').at_least().twice()
     flexmock(module.dispatch).should_receive('call_hooks').at_least().twice()
     flexmock(module).should_receive('run_actions').and_return([])
     flexmock(module).should_receive('run_actions').and_return([])
     config = {'location': {'repositories': ['foo']}}
     config = {'location': {'repositories': ['foo']}}
-    arguments = {'global': flexmock(dry_run=False), 'check': flexmock()}
+    arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'check': flexmock()}
 
 
     list(module.run_configuration('test.yaml', config, arguments))
     list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -59,7 +59,7 @@ def test_run_configuration_does_not_trigger_hooks_for_list_action():
     flexmock(module.dispatch).should_receive('call_hooks').never()
     flexmock(module.dispatch).should_receive('call_hooks').never()
     flexmock(module).should_receive('run_actions').and_return([])
     flexmock(module).should_receive('run_actions').and_return([])
     config = {'location': {'repositories': ['foo']}}
     config = {'location': {'repositories': ['foo']}}
-    arguments = {'global': flexmock(dry_run=False), 'list': flexmock()}
+    arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'list': flexmock()}
 
 
     list(module.run_configuration('test.yaml', config, arguments))
     list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -72,7 +72,7 @@ def test_run_configuration_logs_actions_error():
     flexmock(module).should_receive('make_error_log_records').and_return(expected_results)
     flexmock(module).should_receive('make_error_log_records').and_return(expected_results)
     flexmock(module).should_receive('run_actions').and_raise(OSError)
     flexmock(module).should_receive('run_actions').and_raise(OSError)
     config = {'location': {'repositories': ['foo']}}
     config = {'location': {'repositories': ['foo']}}
-    arguments = {'global': flexmock(dry_run=False)}
+    arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False)}
 
 
     results = list(module.run_configuration('test.yaml', config, arguments))
     results = list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -86,7 +86,7 @@ def test_run_configuration_logs_pre_hook_error():
     flexmock(module).should_receive('make_error_log_records').and_return(expected_results)
     flexmock(module).should_receive('make_error_log_records').and_return(expected_results)
     flexmock(module).should_receive('run_actions').never()
     flexmock(module).should_receive('run_actions').never()
     config = {'location': {'repositories': ['foo']}}
     config = {'location': {'repositories': ['foo']}}
-    arguments = {'global': flexmock(dry_run=False), 'create': flexmock()}
+    arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
 
 
     results = list(module.run_configuration('test.yaml', config, arguments))
     results = list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -103,7 +103,7 @@ def test_run_configuration_logs_post_hook_error():
     flexmock(module).should_receive('make_error_log_records').and_return(expected_results)
     flexmock(module).should_receive('make_error_log_records').and_return(expected_results)
     flexmock(module).should_receive('run_actions').and_return([])
     flexmock(module).should_receive('run_actions').and_return([])
     config = {'location': {'repositories': ['foo']}}
     config = {'location': {'repositories': ['foo']}}
-    arguments = {'global': flexmock(dry_run=False), 'create': flexmock()}
+    arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
 
 
     results = list(module.run_configuration('test.yaml', config, arguments))
     results = list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -119,7 +119,7 @@ def test_run_configuration_logs_on_error_hook_error():
     ).and_return(expected_results[1:])
     ).and_return(expected_results[1:])
     flexmock(module).should_receive('run_actions').and_raise(OSError)
     flexmock(module).should_receive('run_actions').and_raise(OSError)
     config = {'location': {'repositories': ['foo']}}
     config = {'location': {'repositories': ['foo']}}
-    arguments = {'global': flexmock(dry_run=False), 'create': flexmock()}
+    arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
 
 
     results = list(module.run_configuration('test.yaml', config, arguments))
     results = list(module.run_configuration('test.yaml', config, arguments))
 
 
@@ -228,7 +228,7 @@ def test_collect_configuration_run_summary_logs_info_for_success():
 
 
 def test_collect_configuration_run_summary_executes_hooks_for_create():
 def test_collect_configuration_run_summary_executes_hooks_for_create():
     flexmock(module).should_receive('run_configuration').and_return([])
     flexmock(module).should_receive('run_configuration').and_return([])
-    arguments = {'create': flexmock(), 'global': flexmock(dry_run=False)}
+    arguments = {'create': flexmock(), 'global': flexmock(monitoring_verbosity=1, dry_run=False)}
 
 
     logs = tuple(
     logs = tuple(
         module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
         module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
@@ -305,7 +305,7 @@ def test_collect_configuration_run_summary_logs_pre_hook_error():
     flexmock(module.command).should_receive('execute_hook').and_raise(ValueError)
     flexmock(module.command).should_receive('execute_hook').and_raise(ValueError)
     expected_logs = (flexmock(),)
     expected_logs = (flexmock(),)
     flexmock(module).should_receive('make_error_log_records').and_return(expected_logs)
     flexmock(module).should_receive('make_error_log_records').and_return(expected_logs)
-    arguments = {'create': flexmock(), 'global': flexmock(dry_run=False)}
+    arguments = {'create': flexmock(), 'global': flexmock(monitoring_verbosity=1, dry_run=False)}
 
 
     logs = tuple(
     logs = tuple(
         module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
         module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
@@ -319,7 +319,7 @@ def test_collect_configuration_run_summary_logs_post_hook_error():
     flexmock(module).should_receive('run_configuration').and_return([])
     flexmock(module).should_receive('run_configuration').and_return([])
     expected_logs = (flexmock(),)
     expected_logs = (flexmock(),)
     flexmock(module).should_receive('make_error_log_records').and_return(expected_logs)
     flexmock(module).should_receive('make_error_log_records').and_return(expected_logs)
-    arguments = {'create': flexmock(), 'global': flexmock(dry_run=False)}
+    arguments = {'create': flexmock(), 'global': flexmock(monitoring_verbosity=1, dry_run=False)}
 
 
     logs = tuple(
     logs = tuple(
         module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
         module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)

+ 15 - 5
tests/unit/hooks/test_cronhub.py

@@ -7,32 +7,42 @@ def test_ping_monitor_rewrites_ping_url_for_start_state():
     ping_url = 'https://example.com/start/abcdef'
     ping_url = 'https://example.com/start/abcdef'
     flexmock(module.requests).should_receive('get').with_args('https://example.com/start/abcdef')
     flexmock(module.requests).should_receive('get').with_args('https://example.com/start/abcdef')
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.START, dry_run=False)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.START, monitoring_log_level=1, dry_run=False
+    )
 
 
 
 
 def test_ping_monitor_rewrites_ping_url_and_state_for_start_state():
 def test_ping_monitor_rewrites_ping_url_and_state_for_start_state():
     ping_url = 'https://example.com/ping/abcdef'
     ping_url = 'https://example.com/ping/abcdef'
     flexmock(module.requests).should_receive('get').with_args('https://example.com/start/abcdef')
     flexmock(module.requests).should_receive('get').with_args('https://example.com/start/abcdef')
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.START, dry_run=False)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.START, monitoring_log_level=1, dry_run=False
+    )
 
 
 
 
 def test_ping_monitor_rewrites_ping_url_for_finish_state():
 def test_ping_monitor_rewrites_ping_url_for_finish_state():
     ping_url = 'https://example.com/start/abcdef'
     ping_url = 'https://example.com/start/abcdef'
     flexmock(module.requests).should_receive('get').with_args('https://example.com/finish/abcdef')
     flexmock(module.requests).should_receive('get').with_args('https://example.com/finish/abcdef')
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.FINISH, dry_run=False)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False
+    )
 
 
 
 
 def test_ping_monitor_rewrites_ping_url_for_fail_state():
 def test_ping_monitor_rewrites_ping_url_for_fail_state():
     ping_url = 'https://example.com/start/abcdef'
     ping_url = 'https://example.com/start/abcdef'
     flexmock(module.requests).should_receive('get').with_args('https://example.com/fail/abcdef')
     flexmock(module.requests).should_receive('get').with_args('https://example.com/fail/abcdef')
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.FAIL, dry_run=False)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
+    )
 
 
 
 
 def test_ping_monitor_dry_run_does_not_hit_ping_url():
 def test_ping_monitor_dry_run_does_not_hit_ping_url():
     ping_url = 'https://example.com'
     ping_url = 'https://example.com'
     flexmock(module.requests).should_receive('get').never()
     flexmock(module.requests).should_receive('get').never()
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.START, dry_run=True)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.START, monitoring_log_level=1, dry_run=True
+    )

+ 12 - 4
tests/unit/hooks/test_cronitor.py

@@ -7,25 +7,33 @@ def test_ping_monitor_hits_ping_url_for_start_state():
     ping_url = 'https://example.com'
     ping_url = 'https://example.com'
     flexmock(module.requests).should_receive('get').with_args('{}/{}'.format(ping_url, 'run'))
     flexmock(module.requests).should_receive('get').with_args('{}/{}'.format(ping_url, 'run'))
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.START, dry_run=False)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.START, monitoring_log_level=1, dry_run=False
+    )
 
 
 
 
 def test_ping_monitor_hits_ping_url_for_finish_state():
 def test_ping_monitor_hits_ping_url_for_finish_state():
     ping_url = 'https://example.com'
     ping_url = 'https://example.com'
     flexmock(module.requests).should_receive('get').with_args('{}/{}'.format(ping_url, 'complete'))
     flexmock(module.requests).should_receive('get').with_args('{}/{}'.format(ping_url, 'complete'))
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.FINISH, dry_run=False)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.FINISH, monitoring_log_level=1, dry_run=False
+    )
 
 
 
 
 def test_ping_monitor_hits_ping_url_for_fail_state():
 def test_ping_monitor_hits_ping_url_for_fail_state():
     ping_url = 'https://example.com'
     ping_url = 'https://example.com'
     flexmock(module.requests).should_receive('get').with_args('{}/{}'.format(ping_url, 'fail'))
     flexmock(module.requests).should_receive('get').with_args('{}/{}'.format(ping_url, 'fail'))
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.FAIL, dry_run=False)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
+    )
 
 
 
 
 def test_ping_monitor_dry_run_does_not_hit_ping_url():
 def test_ping_monitor_dry_run_does_not_hit_ping_url():
     ping_url = 'https://example.com'
     ping_url = 'https://example.com'
     flexmock(module.requests).should_receive('get').never()
     flexmock(module.requests).should_receive('get').never()
 
 
-    module.ping_monitor(ping_url, 'config.yaml', module.monitor.State.START, dry_run=True)
+    module.ping_monitor(
+        ping_url, 'config.yaml', module.monitor.State.START, monitoring_log_level=1, dry_run=True
+    )

+ 39 - 9
tests/unit/hooks/test_healthchecks.py

@@ -4,7 +4,7 @@ from borgmatic.hooks import healthchecks as module
 
 
 
 
 def test_forgetful_buffering_handler_emit_collects_log_records():
 def test_forgetful_buffering_handler_emit_collects_log_records():
-    handler = module.Forgetful_buffering_handler(byte_capacity=100)
+    handler = module.Forgetful_buffering_handler(byte_capacity=100, log_level=1)
     handler.emit(flexmock(getMessage=lambda: 'foo'))
     handler.emit(flexmock(getMessage=lambda: 'foo'))
     handler.emit(flexmock(getMessage=lambda: 'bar'))
     handler.emit(flexmock(getMessage=lambda: 'bar'))
 
 
@@ -13,7 +13,7 @@ def test_forgetful_buffering_handler_emit_collects_log_records():
 
 
 
 
 def test_forgetful_buffering_handler_emit_forgets_log_records_when_capacity_reached():
 def test_forgetful_buffering_handler_emit_forgets_log_records_when_capacity_reached():
-    handler = module.Forgetful_buffering_handler(byte_capacity=len('foo\nbar\n'))
+    handler = module.Forgetful_buffering_handler(byte_capacity=len('foo\nbar\n'), log_level=1)
     handler.emit(flexmock(getMessage=lambda: 'foo'))
     handler.emit(flexmock(getMessage=lambda: 'foo'))
     assert handler.buffer == ['foo\n']
     assert handler.buffer == ['foo\n']
     handler.emit(flexmock(getMessage=lambda: 'bar'))
     handler.emit(flexmock(getMessage=lambda: 'bar'))
@@ -26,7 +26,7 @@ def test_forgetful_buffering_handler_emit_forgets_log_records_when_capacity_reac
 
 
 
 
 def test_format_buffered_logs_for_payload_flattens_log_buffer():
 def test_format_buffered_logs_for_payload_flattens_log_buffer():
-    handler = module.Forgetful_buffering_handler(byte_capacity=100)
+    handler = module.Forgetful_buffering_handler(byte_capacity=100, log_level=1)
     handler.buffer = ['foo\n', 'bar\n']
     handler.buffer = ['foo\n', 'bar\n']
     flexmock(module.logging).should_receive('getLogger').and_return(flexmock(handlers=[handler]))
     flexmock(module.logging).should_receive('getLogger').and_return(flexmock(handlers=[handler]))
 
 
@@ -36,7 +36,7 @@ def test_format_buffered_logs_for_payload_flattens_log_buffer():
 
 
 
 
 def test_format_buffered_logs_for_payload_inserts_truncation_indicator_when_logs_forgotten():
 def test_format_buffered_logs_for_payload_inserts_truncation_indicator_when_logs_forgotten():
-    handler = module.Forgetful_buffering_handler(byte_capacity=100)
+    handler = module.Forgetful_buffering_handler(byte_capacity=100, log_level=1)
     handler.buffer = ['foo\n', 'bar\n']
     handler.buffer = ['foo\n', 'bar\n']
     handler.forgot = True
     handler.forgot = True
     flexmock(module.logging).should_receive('getLogger').and_return(flexmock(handlers=[handler]))
     flexmock(module.logging).should_receive('getLogger').and_return(flexmock(handlers=[handler]))
@@ -63,7 +63,13 @@ def test_ping_monitor_hits_ping_url_for_start_state():
         '{}/{}'.format(ping_url, 'start'), data=''.encode('utf-8')
         '{}/{}'.format(ping_url, 'start'), data=''.encode('utf-8')
     )
     )
 
 
-    module.ping_monitor(ping_url, 'config.yaml', state=module.monitor.State.START, dry_run=False)
+    module.ping_monitor(
+        ping_url,
+        'config.yaml',
+        state=module.monitor.State.START,
+        monitoring_log_level=1,
+        dry_run=False,
+    )
 
 
 
 
 def test_ping_monitor_hits_ping_url_for_finish_state():
 def test_ping_monitor_hits_ping_url_for_finish_state():
@@ -74,7 +80,13 @@ def test_ping_monitor_hits_ping_url_for_finish_state():
         ping_url, data=payload.encode('utf-8')
         ping_url, data=payload.encode('utf-8')
     )
     )
 
 
-    module.ping_monitor(ping_url, 'config.yaml', state=module.monitor.State.FINISH, dry_run=False)
+    module.ping_monitor(
+        ping_url,
+        'config.yaml',
+        state=module.monitor.State.FINISH,
+        monitoring_log_level=1,
+        dry_run=False,
+    )
 
 
 
 
 def test_ping_monitor_hits_ping_url_for_fail_state():
 def test_ping_monitor_hits_ping_url_for_fail_state():
@@ -85,7 +97,13 @@ def test_ping_monitor_hits_ping_url_for_fail_state():
         '{}/{}'.format(ping_url, 'fail'), data=payload.encode('utf')
         '{}/{}'.format(ping_url, 'fail'), data=payload.encode('utf')
     )
     )
 
 
-    module.ping_monitor(ping_url, 'config.yaml', state=module.monitor.State.FAIL, dry_run=False)
+    module.ping_monitor(
+        ping_url,
+        'config.yaml',
+        state=module.monitor.State.FAIL,
+        monitoring_log_level=1,
+        dry_run=False,
+    )
 
 
 
 
 def test_ping_monitor_with_ping_uuid_hits_corresponding_url():
 def test_ping_monitor_with_ping_uuid_hits_corresponding_url():
@@ -96,7 +114,13 @@ def test_ping_monitor_with_ping_uuid_hits_corresponding_url():
         'https://hc-ping.com/{}'.format(ping_uuid), data=payload.encode('utf-8')
         'https://hc-ping.com/{}'.format(ping_uuid), data=payload.encode('utf-8')
     )
     )
 
 
-    module.ping_monitor(ping_uuid, 'config.yaml', state=module.monitor.State.FINISH, dry_run=False)
+    module.ping_monitor(
+        ping_uuid,
+        'config.yaml',
+        state=module.monitor.State.FINISH,
+        monitoring_log_level=1,
+        dry_run=False,
+    )
 
 
 
 
 def test_ping_monitor_dry_run_does_not_hit_ping_url():
 def test_ping_monitor_dry_run_does_not_hit_ping_url():
@@ -104,4 +128,10 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url():
     ping_url = 'https://example.com'
     ping_url = 'https://example.com'
     flexmock(module.requests).should_receive('post').never()
     flexmock(module.requests).should_receive('post').never()
 
 
-    module.ping_monitor(ping_url, 'config.yaml', state=module.monitor.State.START, dry_run=True)
+    module.ping_monitor(
+        ping_url,
+        'config.yaml',
+        state=module.monitor.State.START,
+        monitoring_log_level=1,
+        dry_run=True,
+    )