| 
					
				 | 
			
			
				@@ -20,6 +20,8 @@ from .helpers import Error, location_validator, format_time, format_file_size, \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     get_cache_dir, get_keys_dir, format_timedelta, prune_within, prune_split, \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Manifest, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     is_cachedir, bigint_to_int, ChunkerParams, CompressionSpec, have_cython 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from .logger import create_logger, setup_logging 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+logger = create_logger() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 if have_cython(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     from .compress import Compressor, COMPR_BUFFER 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     from .upgrader import AtticRepositoryUpgrader 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -48,15 +50,11 @@ class Archiver: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def print_error(self, msg, *args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         msg = args and msg % args or msg 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.exit_code = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print('borg: ' + msg, file=sys.stderr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        logger.error('borg: ' + msg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def print_verbose(self, msg, *args, **kw): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if self.verbose: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            msg = args and msg % args or msg 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if kw.get('newline', True): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print(msg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print(msg, end=' ') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        msg = args and msg % args or msg 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        logger.info(msg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def do_serve(self, args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Start in server mode. This command is usually not used manually. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -65,7 +63,7 @@ class Archiver: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def do_init(self, args): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Initialize an empty repository""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print('Initializing repository at "%s"' % args.repository.orig) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        logger.info('Initializing repository at "%s"' % args.repository.orig) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         repository = self.open_repository(args.repository, create=True, exclusive=True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         key = key_creator(repository, args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         manifest = Manifest(key, repository) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -87,9 +85,9 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if input('Do you want to continue? ') == 'Yes I am sure': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if not args.archives_only: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            print('Starting repository check...') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logger.warning('Starting repository check...') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if repository.check(repair=args.repair): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print('Repository check complete, no problems found.') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                logger.info('Repository check complete, no problems found.') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if not args.repo_only and not ArchiveChecker().check( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -118,7 +116,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             archive = Archive(repository, key, manifest, args.archive.archive, cache=cache, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                               create=True, checkpoint_interval=args.checkpoint_interval, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                               numeric_owner=args.numeric_owner, progress=args.progress, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                              chunker_params=args.chunker_params) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              chunker_params=args.chunker_params, start=t0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             archive = cache = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Add cache dir to inode_skip list 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -163,16 +161,10 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if args.progress: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 archive.stats.show_progress(final=True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if args.stats: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                t = datetime.now() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                diff = t - t0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                archive.end = datetime.now() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 print('-' * 78) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print('Archive name: %s' % args.archive.archive) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print('Archive fingerprint: %s' % hexlify(archive.id).decode('ascii')) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print('Start time: %s' % t0.strftime('%c')) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print('End time: %s' % t.strftime('%c')) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print('Duration: %s' % format_timedelta(diff)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print('Number of files: %d' % archive.stats.nfiles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                archive.stats.print_('This archive:', cache) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                print(str(archive)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                print(archive.stats.print_('This archive:', cache)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 print('-' * 78) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return self.exit_code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -252,7 +244,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Extract archive contents""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # be restrictive when restoring files, restore permissions later 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if sys.getfilesystemencoding() == 'ascii': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            print('Warning: File system encoding is "ascii", extracting non-ascii filenames will not be supported.') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logger.warning('Warning: File system encoding is "ascii", extracting non-ascii filenames will not be supported.') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         repository = self.open_repository(args.archive) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         manifest, key = Manifest.load(repository) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         archive = Archive(repository, key, manifest, args.archive.archive, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -318,21 +310,22 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             repository.commit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cache.commit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if args.stats: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stats.print_('Deleted data:', cache) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                logger.info(stats.print_('Deleted data:', cache)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if not args.cache_only: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print("You requested to completely DELETE the repository *including* all archives it contains:") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                print("You requested to completely DELETE the repository *including* all archives it contains:", file=sys.stderr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 for archive_info in manifest.list_archive_infos(sort_by='ts'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    print(format_archive(archive_info)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    print(format_archive(archive_info), file=sys.stderr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if not os.environ.get('BORG_CHECK_I_KNOW_WHAT_I_AM_DOING'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    print("""Type "YES" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    print("""Type "YES" if you understand this and want to continue.\n""", file=sys.stderr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    # XXX: prompt may end up on stdout, but we'll assume that input() does the right thing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if input('Do you want to continue? ') != 'YES': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         self.exit_code = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         return self.exit_code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 repository.destroy() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                print("Repository deleted.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                logger.info("Repository deleted.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cache.destroy() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            print("Cache deleted.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logger.info("Cache deleted.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return self.exit_code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def do_mount(self, args): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -418,7 +411,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         print('Time: %s' % to_localtime(archive.ts).strftime('%c')) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         print('Command line:', remove_surrogates(' '.join(archive.metadata[b'cmdline']))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         print('Number of files: %d' % stats.nfiles) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        stats.print_('This archive:', cache) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print(stats.print_('This archive:', cache)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return self.exit_code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def do_prune(self, args): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -463,7 +456,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             repository.commit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cache.commit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if args.stats: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            stats.print_('Deleted data:', cache) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logger.info(stats.print_('Deleted data:', cache)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return self.exit_code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def do_upgrade(self, args): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -551,9 +544,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def build_parser(self, args=None, prog=None): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         common_parser = argparse.ArgumentParser(add_help=False, prog=prog) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        common_parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                   default=False, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                   help='verbose output') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        common_parser.add_argument('-v', '--verbose', dest='verbose', action='count', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                   help='verbose output, defaults to warnings only') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         common_parser.add_argument('--no-files-cache', dest='cache_files', action='store_false', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    help='do not load/update the file metadata cache used to detect unchanged files') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         common_parser.add_argument('--umask', dest='umask', type=lambda s: int(s, 8), default=RemoteRepository.umask, metavar='M', 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -983,7 +975,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         parser = self.build_parser(args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         args = parser.parse_args(args or ['-h']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.verbose = args.verbose 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        setup_logging(args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         os.umask(args.umask) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         RemoteRepository.remote_path = args.remote_path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         RemoteRepository.umask = args.umask 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1002,7 +994,7 @@ def sig_info_handler(signum, stack):  # pragma: no cover 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 total = loc['st'].st_size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             except Exception: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 pos, total = 0, 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            print("{0} {1}/{2}".format(path, format_file_size(pos), format_file_size(total))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logger.warning("{0} {1}/{2}".format(path, format_file_size(pos), format_file_size(total))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if func in ('extract_item', ):  # extract op 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             path = loc['item'][b'path'] 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1010,7 +1002,7 @@ def sig_info_handler(signum, stack):  # pragma: no cover 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 pos = loc['fd'].tell() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             except Exception: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 pos = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            print("{0} {1}/???".format(path, format_file_size(pos))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logger.warning("{0} {1}/???".format(path, format_file_size(pos))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |