瀏覽代碼

When the "--json" flag is given, suppress console escape codes so as not to interfere with JSON output (#827).

Dan Helfman 1 年之前
父節點
當前提交
f4744826fe
共有 4 個文件被更改,包括 57 次插入56 次删除
  1. 2 0
      NEWS
  2. 3 4
      borgmatic/commands/borgmatic.py
  3. 6 2
      borgmatic/logger.py
  4. 46 50
      tests/unit/test_logger.py

+ 2 - 0
NEWS

@@ -1,4 +1,6 @@
 1.8.9.dev0
 1.8.9.dev0
+ * #827: When the "--json" flag is given, suppress console escape codes so as not to
+   interfere with JSON output.
  * Clarify documentation about restoring a database: borgmatic does not create the database upon
  * Clarify documentation about restoring a database: borgmatic does not create the database upon
    restore.
    restore.
 
 

+ 3 - 4
borgmatic/commands/borgmatic.py

@@ -872,10 +872,8 @@ def main(extra_summary_logs=[]):  # pragma: no cover
     any_json_flags = any(
     any_json_flags = any(
         getattr(sub_arguments, 'json', False) for sub_arguments in arguments.values()
         getattr(sub_arguments, 'json', False) for sub_arguments in arguments.values()
     )
     )
-    colorama.init(
-        autoreset=True,
-        strip=not should_do_markup(global_arguments.no_color or any_json_flags, configs),
-    )
+    color_enabled = should_do_markup(global_arguments.no_color or any_json_flags, configs)
+    colorama.init(autoreset=color_enabled, strip=not color_enabled)
     try:
     try:
         configure_logging(
         configure_logging(
             verbosity_to_log_level(global_arguments.verbosity),
             verbosity_to_log_level(global_arguments.verbosity),
@@ -884,6 +882,7 @@ def main(extra_summary_logs=[]):  # pragma: no cover
             verbosity_to_log_level(global_arguments.monitoring_verbosity),
             verbosity_to_log_level(global_arguments.monitoring_verbosity),
             global_arguments.log_file,
             global_arguments.log_file,
             global_arguments.log_file_format,
             global_arguments.log_file_format,
+            color_enabled=color_enabled,
         )
         )
     except (FileNotFoundError, PermissionError) as error:
     except (FileNotFoundError, PermissionError) as error:
         configure_logging(logging.CRITICAL)
         configure_logging(logging.CRITICAL)

+ 6 - 2
borgmatic/logger.py

@@ -159,10 +159,11 @@ def configure_logging(
     monitoring_log_level=None,
     monitoring_log_level=None,
     log_file=None,
     log_file=None,
     log_file_format=None,
     log_file_format=None,
+    color_enabled=True,
 ):
 ):
     '''
     '''
     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,
-    respectively.
+    respectively. If color is enabled, set up log formatting accordingly.
 
 
     Raise FileNotFoundError or PermissionError if the log file could not be opened for writing.
     Raise FileNotFoundError or PermissionError if the log file could not be opened for writing.
     '''
     '''
@@ -191,7 +192,10 @@ def configure_logging(
             logging.DEBUG: console_standard_handler,
             logging.DEBUG: console_standard_handler,
         }
         }
     )
     )
-    console_handler.setFormatter(Console_color_formatter())
+
+    if color_enabled:
+        console_handler.setFormatter(Console_color_formatter())
+
     console_handler.setLevel(console_log_level)
     console_handler.setLevel(console_log_level)
 
 
     handlers = [console_handler]
     handlers = [console_handler]

+ 46 - 50
tests/unit/test_logger.py

@@ -177,11 +177,9 @@ def test_add_logging_level_skips_global_setting_if_already_set():
 def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_linux():
 def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_linux():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).ANSWER = module.ANSWER
     flexmock(module.logging).ANSWER = module.ANSWER
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module).should_receive('interactive_console').and_return(False)
     flexmock(module).should_receive('interactive_console').and_return(False)
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
@@ -199,11 +197,9 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_linux(
 def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_macos():
 def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_macos():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).ANSWER = module.ANSWER
     flexmock(module.logging).ANSWER = module.ANSWER
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module).should_receive('interactive_console').and_return(False)
     flexmock(module).should_receive('interactive_console').and_return(False)
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
@@ -222,11 +218,9 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_macos(
 def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_freebsd():
 def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_freebsd():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).ANSWER = module.ANSWER
     flexmock(module.logging).ANSWER = module.ANSWER
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module).should_receive('interactive_console').and_return(False)
     flexmock(module).should_receive('interactive_console').and_return(False)
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
@@ -246,11 +240,9 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_freebs
 def test_configure_logging_without_syslog_log_level_skips_syslog():
 def test_configure_logging_without_syslog_log_level_skips_syslog():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).ANSWER = module.ANSWER
     flexmock(module.logging).ANSWER = module.ANSWER
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
         level=logging.INFO, handlers=list
         level=logging.INFO, handlers=list
@@ -264,11 +256,9 @@ def test_configure_logging_without_syslog_log_level_skips_syslog():
 def test_configure_logging_skips_syslog_if_not_found():
 def test_configure_logging_skips_syslog_if_not_found():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).ANSWER = module.ANSWER
     flexmock(module.logging).ANSWER = module.ANSWER
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module).should_receive('Console_color_formatter')
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
         level=logging.INFO, handlers=list
         level=logging.INFO, handlers=list
@@ -282,11 +272,9 @@ def test_configure_logging_skips_syslog_if_not_found():
 def test_configure_logging_skips_log_file_if_log_file_logging_is_disabled():
 def test_configure_logging_skips_log_file_if_log_file_logging_is_disabled():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).DISABLED = module.DISABLED
     flexmock(module.logging).DISABLED = module.DISABLED
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
 
 
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
         level=logging.INFO, handlers=list
         level=logging.INFO, handlers=list
@@ -303,11 +291,9 @@ def test_configure_logging_skips_log_file_if_log_file_logging_is_disabled():
 def test_configure_logging_to_log_file_instead_of_syslog():
 def test_configure_logging_to_log_file_instead_of_syslog():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).ANSWER = module.ANSWER
     flexmock(module.logging).ANSWER = module.ANSWER
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
 
 
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
         level=logging.DEBUG, handlers=list
         level=logging.DEBUG, handlers=list
@@ -330,11 +316,9 @@ def test_configure_logging_to_log_file_instead_of_syslog():
 def test_configure_logging_to_both_log_file_and_syslog():
 def test_configure_logging_to_both_log_file_and_syslog():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).ANSWER = module.ANSWER
     flexmock(module.logging).ANSWER = module.ANSWER
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
 
 
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
         level=logging.DEBUG, handlers=list
         level=logging.DEBUG, handlers=list
@@ -363,11 +347,9 @@ def test_configure_logging_to_log_file_formats_with_custom_log_format():
     flexmock(module.logging).should_receive('Formatter').with_args(
     flexmock(module.logging).should_receive('Formatter').with_args(
         '{message}', style='{'  # noqa: FS003
         '{message}', style='{'  # noqa: FS003
     ).once()
     ).once()
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
 
 
     flexmock(module).should_receive('interactive_console').and_return(False)
     flexmock(module).should_receive('interactive_console').and_return(False)
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
@@ -391,11 +373,9 @@ def test_configure_logging_to_log_file_formats_with_custom_log_format():
 def test_configure_logging_skips_log_file_if_argument_is_none():
 def test_configure_logging_skips_log_file_if_argument_is_none():
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module).should_receive('add_custom_log_levels')
     flexmock(module.logging).ANSWER = module.ANSWER
     flexmock(module.logging).ANSWER = module.ANSWER
-    flexmock(module).should_receive('Multi_stream_handler').and_return(
-        flexmock(
-            setFormatter=lambda formatter: None, setLevel=lambda level: None, level=logging.INFO
-        )
-    )
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').once()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
 
 
     flexmock(module.logging).should_receive('basicConfig').with_args(
     flexmock(module.logging).should_receive('basicConfig').with_args(
         level=logging.INFO, handlers=list
         level=logging.INFO, handlers=list
@@ -404,3 +384,19 @@ def test_configure_logging_skips_log_file_if_argument_is_none():
     flexmock(module.logging.handlers).should_receive('WatchedFileHandler').never()
     flexmock(module.logging.handlers).should_receive('WatchedFileHandler').never()
 
 
     module.configure_logging(console_log_level=logging.INFO, log_file=None)
     module.configure_logging(console_log_level=logging.INFO, log_file=None)
+
+
+def test_configure_logging_skips_console_color_formatter_if_color_disabled():
+    flexmock(module).should_receive('add_custom_log_levels')
+    flexmock(module.logging).ANSWER = module.ANSWER
+    multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO)
+    multi_stream_handler.should_receive('setFormatter').never()
+    flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler)
+
+    flexmock(module.logging).should_receive('basicConfig').with_args(
+        level=logging.INFO, handlers=list
+    )
+    flexmock(module.os.path).should_receive('exists').and_return(False)
+    flexmock(module.logging.handlers).should_receive('WatchedFileHandler').never()
+
+    module.configure_logging(console_log_level=logging.INFO, log_file=None, color_enabled=False)