diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index 699ea0f3d3f504bc9d1904960375ebd677e6ebbf..0aa6369576c36eb8615915a6cd538bdd670af7fb 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -2,13 +2,15 @@
 
 module Backup
   class Manager
+    include ::Gitlab::TaskHelpers
+
     FILE_NAME_SUFFIX = '_gitlab_backup.tar'
     MANIFEST_NAME = 'backup_information.yml'
 
     # Use the content from stdin instead of an actual filepath (used by tar as input or output)
     USE_STDIN = '-'
 
-    attr_reader :progress, :remote_storage, :options
+    attr_reader :remote_storage, :options, :logger, :progress
 
     def initialize(progress, backup_tasks: nil)
       @progress = progress
@@ -16,7 +18,8 @@ def initialize(progress, backup_tasks: nil)
       @options = Backup::Options.new
       @metadata = Backup::Metadata.new(manifest_filepath)
       @options.extract_from_env! # preserve existing behavior
-      @remote_storage = Backup::RemoteStorage.new(progress: progress, options: options)
+      @logger = Gitlab::BackupLogger.new(progress)
+      @remote_storage = Backup::RemoteStorage.new(logger: logger, options: options)
     end
 
     # @return [Boolean] whether all tasks succeeded
@@ -27,10 +30,10 @@ def create
       unpack(previous_backup) if options.incremental?
       create_all_tasks_result = run_all_create_tasks
 
-      puts_time "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \
+      logger.warn "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \
            "and are not included in this backup. You will need these files to restore a backup.\n" \
-           "Please back them up manually.".color(:red)
-      puts_time "Backup #{backup_id} is done."
+           "Please back them up manually."
+      logger.info "Backup #{backup_id} is done."
       create_all_tasks_result
     end
 
@@ -40,22 +43,22 @@ def run_create_task(task)
       build_backup_information
 
       unless task.enabled?
-        puts_time "Dumping #{task.human_name} ... ".color(:blue) + "[DISABLED]".color(:cyan)
+        logger.info "Dumping #{task.human_name} ... " + "[DISABLED]"
         return true
       end
 
       if options.skip_task?(task.id)
-        puts_time "Dumping #{task.human_name} ... ".color(:blue) + "[SKIPPED]".color(:cyan)
+        logger.info "Dumping #{task.human_name} ... " + "[SKIPPED]"
         return true
       end
 
-      puts_time "Dumping #{task.human_name} ... ".color(:blue)
+      logger.info "Dumping #{task.human_name} ... "
       task.backup!(backup_path, backup_id)
-      puts_time "Dumping #{task.human_name} ... ".color(:blue) + "done".color(:green)
+      logger.info "Dumping #{task.human_name} ... " + "done"
       true
 
     rescue Backup::DatabaseBackupError, Backup::FileBackupError => e
-      puts_time "Dumping #{task.human_name} failed: #{e.message}".color(:red)
+      logger.error "Dumping #{task.human_name} failed: #{e.message}"
       false
     end
 
@@ -63,9 +66,9 @@ def restore
       unpack(options.backup_id)
       run_all_restore_tasks
 
-      puts_time "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \
-        "and are not included in this backup. You will need to restore these files manually.".color(:red)
-      puts_time "Restore task is done."
+      logger.warn "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \
+        "and are not included in this backup. You will need to restore these files manually."
+      logger.info "Restore task is done."
     end
 
     # @param [Gitlab::Backup::Tasks::Task] task
@@ -73,30 +76,30 @@ def run_restore_task(task)
       read_backup_information
 
       unless task.enabled?
-        puts_time "Restoring #{task.human_name} ... ".color(:blue) + "[DISABLED]".color(:cyan)
+        logger.info "Restoring #{task.human_name} ... " + "[DISABLED]"
         return
       end
 
-      puts_time "Restoring #{task.human_name} ... ".color(:blue)
+      logger.info "Restoring #{task.human_name} ... "
 
       warning = task.pre_restore_warning
       if warning.present?
-        puts_time warning.color(:red)
+        logger.warn warning
         Gitlab::TaskHelpers.ask_to_continue
       end
 
       task.restore!(backup_path, backup_id)
 
-      puts_time "Restoring #{task.human_name} ... ".color(:blue) + "done".color(:green)
+      logger.info "Restoring #{task.human_name} ... done"
 
       warning = task.post_restore_warning
       if warning.present?
-        puts_time warning.color(:red)
+        logger.warn warning
         Gitlab::TaskHelpers.ask_to_continue
       end
 
-    rescue Gitlab::TaskAbortedByUserError
-      puts_time "Quitting...".color(:red)
+    rescue ::Gitlab::TaskAbortedByUserError
+      logger.error "Quitting..."
       exit 1
     end
 
@@ -241,7 +244,7 @@ def backup_information
     def pack
       Dir.chdir(backup_path) do
         # create archive
-        puts_time "Creating backup archive: #{tar_file} ... ".color(:blue)
+        logger.info "Creating backup archive: #{tar_file} ... "
 
         tar_utils = ::Gitlab::Backup::Cli::Utils::Tar.new
         tar_command = tar_utils.pack_cmd(
@@ -256,9 +259,9 @@ def pack
         result = tar_command.run_single_pipeline!(output: archive_file)
 
         if result.status.success?
-          puts_time "Creating backup archive: #{tar_file} ... ".color(:blue) + 'done'.color(:green)
+          logger.info "Creating backup archive: #{tar_file} ... done"
         else
-          puts_time "Creating archive #{tar_file} failed".color(:red)
+          logger.error "Creating archive #{tar_file} failed"
           raise Backup::Error, 'Backup failed'
         end
       end
@@ -269,30 +272,30 @@ def upload
     end
 
     def cleanup
-      puts_time "Deleting tar staging files ... ".color(:blue)
+      logger.info "Deleting tar staging files ... "
 
       remove_backup_path(MANIFEST_NAME)
       backup_tasks.each_value do |task|
         remove_backup_path(task.cleanup_path || task.destination_path)
       end
 
-      puts_time "Deleting tar staging files ... ".color(:blue) + 'done'.color(:green)
+      logger.info "Deleting tar staging files ... done"
     end
 
     def remove_backup_path(path)
       absolute_path = backup_path.join(path)
       return unless File.exist?(absolute_path)
 
-      puts_time "Cleaning up #{absolute_path}"
+      logger.info "Cleaning up #{absolute_path}"
       FileUtils.rm_rf(absolute_path)
     end
 
     def remove_tmp
       # delete tmp inside backups
-      puts_time "Deleting backups/tmp ... ".color(:blue)
+      logger.info "Deleting backups/tmp ... "
 
       FileUtils.rm_rf(backup_path.join('tmp'))
-      puts_time "Deleting backups/tmp ... ".color(:blue) + "done".color(:green)
+      logger.info "Deleting backups/tmp ... " + "done"
     end
 
     def remove_old
@@ -300,11 +303,11 @@ def remove_old
       keep_time = Gitlab.config.backup.keep_time.to_i
 
       if keep_time <= 0
-        puts_time "Deleting old backups ... ".color(:blue) + "[SKIPPED]".color(:cyan)
+        logger.info "Deleting old backups ... [SKIPPED]"
         return
       end
 
-      puts_time "Deleting old backups ... ".color(:blue)
+      logger.info "Deleting old backups ... "
       removed = 0
 
       Dir.chdir(backup_path) do
@@ -324,26 +327,26 @@ def remove_old
             FileUtils.rm(file)
             removed += 1
           rescue StandardError => e
-            puts_time "Deleting #{file} failed: #{e.message}".color(:red)
+            logger.error "Deleting #{file} failed: #{e.message}"
           end
         end
       end
 
-      puts_time "Deleting old backups ... ".color(:blue) + "done. (#{removed} removed)".color(:green)
+      logger.info "Deleting old backups ... done. (#{removed} removed)"
     end
 
     def verify_backup_version
       Dir.chdir(backup_path) do
         # restoring mismatching backups can lead to unexpected problems
         if backup_information[:gitlab_version] != Gitlab::VERSION
-          progress.puts(<<~HEREDOC.color(:red))
+          logger.error(<<~HEREDOC)
             GitLab version mismatch:
               Your current GitLab version (#{Gitlab::VERSION}) differs from the GitLab version in the backup!
               Please switch to the following version and try again:
               version: #{backup_information[:gitlab_version]}
           HEREDOC
-          progress.puts
-          progress.puts "Hint: git checkout v#{backup_information[:gitlab_version]}"
+          logger.error ""
+          logger.error "Hint: git checkout v#{backup_information[:gitlab_version]}"
           exit 1
         end
       end
@@ -351,33 +354,33 @@ def verify_backup_version
 
     def puts_available_timestamps
       available_timestamps.each do |available_timestamp|
-        puts_time " " + available_timestamp
+        logger.info " " + available_timestamp
       end
     end
 
     def unpack(source_backup_id)
       if source_backup_id.blank? && non_tarred_backup?
-        puts_time "Non tarred backup found in #{backup_path}, using that"
+        logger.info "Non tarred backup found in #{backup_path}, using that"
         return
       end
 
       Dir.chdir(backup_path) do
         # check for existing backups in the backup dir
         if backup_file_list.empty?
-          puts_time "No backups found in #{backup_path}"
-          puts_time "Please make sure that file name ends with #{FILE_NAME_SUFFIX}"
+          logger.error "No backups found in #{backup_path}"
+          logger.error "Please make sure that file name ends with #{FILE_NAME_SUFFIX}"
           exit 1
         elsif backup_file_list.many? && source_backup_id.nil?
-          puts_time 'Found more than one backup:'
+          logger.warn 'Found more than one backup:'
           # print list of available backups
           puts_available_timestamps
 
           if options.incremental?
-            puts_time 'Please specify which one you want to create an incremental backup for:'
-            puts_time 'rake gitlab:backup:create INCREMENTAL=true PREVIOUS_BACKUP=timestamp_of_backup'
+            logger.info 'Please specify which one you want to create an incremental backup for:'
+            logger.info 'rake gitlab:backup:create INCREMENTAL=true PREVIOUS_BACKUP=timestamp_of_backup'
           else
-            puts_time 'Please specify which one you want to restore:'
-            puts_time 'rake gitlab:backup:restore BACKUP=timestamp_of_backup'
+            logger.info 'Please specify which one you want to restore:'
+            logger.info 'rake gitlab:backup:restore BACKUP=timestamp_of_backup'
           end
 
           exit 1
@@ -390,16 +393,16 @@ def unpack(source_backup_id)
                    end
 
         unless File.exist?(tar_file)
-          puts_time "The backup file #{tar_file} does not exist!"
+          logger.error "The backup file #{tar_file} does not exist!"
           exit 1
         end
 
-        puts_time 'Unpacking backup ... '.color(:blue)
+        logger.info 'Unpacking backup ... '
 
         if Kernel.system(*%W[tar -xf #{tar_file}])
-          puts_time 'Unpacking backup ... '.color(:blue) + 'done'.color(:green)
+          logger.info 'Unpacking backup ... ' + 'done'
         else
-          puts_time 'Unpacking backup failed'.color(:red)
+          logger.error 'Unpacking backup failed'
           exit 1
         end
       end
@@ -464,11 +467,6 @@ def backup_id
         "#{backup_information[:backup_created_at].strftime('%s_%Y_%m_%d_')}#{backup_information[:gitlab_version]}"
       end
     end
-
-    def puts_time(msg)
-      progress.puts "#{Time.current} -- #{msg}"
-      Gitlab::BackupLogger.info(message: "#{Rainbow.uncolor(msg)}")
-    end
   end
 end
 
diff --git a/lib/backup/remote_storage.rb b/lib/backup/remote_storage.rb
index 1d11eee8f47231830519caac70099f49afdc9b1d..cbf3b3322295d8e71767afaa7e133283467245cd 100644
--- a/lib/backup/remote_storage.rb
+++ b/lib/backup/remote_storage.rb
@@ -2,10 +2,10 @@
 
 module Backup
   class RemoteStorage
-    attr_reader :progress, :options, :backup_information
+    attr_reader :options, :backup_information, :logger
 
-    def initialize(progress:, options:)
-      @progress = progress
+    def initialize(logger:, options:)
+      @logger = logger
       @options = options
     end
 
@@ -16,26 +16,24 @@ def upload(backup_information:)
       if connection_settings.blank? ||
           options.skippable_operations.remote_storage ||
           options.skippable_operations.archive
-        puts_time "Uploading backup archive to remote storage #{remote_directory} ... ".color(:blue) +
-          "[SKIPPED]".color(:cyan)
+        logger.info "Uploading backup archive to remote storage #{remote_directory} ... [SKIPPED]"
         return
       end
 
-      puts_time "Uploading backup archive to remote storage #{remote_directory} ... ".color(:blue)
+      logger.info "Uploading backup archive to remote storage #{remote_directory} ... "
 
       directory = connect_to_remote_directory
       upload = directory.files.create(create_attributes)
 
       if upload
         if upload.respond_to?(:encryption) && upload.encryption
-          puts_time "Uploading backup archive to remote storage #{remote_directory} ... ".color(:blue) +
-            "done (encrypted with #{upload.encryption})".color(:green)
+          logger.info "Uploading backup archive to remote storage #{remote_directory} ... " \
+                      "done (encrypted with #{upload.encryption})"
         else
-          puts_time "Uploading backup archive to remote storage #{remote_directory} ... ".color(:blue) +
-            "done".color(:green)
+          logger.info "Uploading backup archive to remote storage #{remote_directory} ... done"
         end
       else
-        puts_time "Uploading backup to #{remote_directory} failed".color(:red)
+        logger.error "Uploading backup to #{remote_directory} failed"
         raise Backup::Error, 'Backup failed'
       end
     end
@@ -127,13 +125,6 @@ def object_storage_config
       @object_storage_config ||= ObjectStorage::Config.new(Gitlab.config.backup.upload)
     end
 
-    # TODO: This is a temporary workaround for bad design in Backup::Manager
-    # Output related code would be moved to a new location
-    def puts_time(msg)
-      progress.puts "#{Time.current} -- #{msg}"
-      Gitlab::BackupLogger.info(message: Rainbow.uncolor(msg))
-    end
-
     # TODO: This is a temporary workaround for bad design in Backup::Manager
     def tar_file
       @tar_file ||= "#{backup_id}#{Backup::Manager::FILE_NAME_SUFFIX}"
diff --git a/lib/backup/targets/database.rb b/lib/backup/targets/database.rb
index bb39795f3d0474a2c479797839e8a1247a42c84c..49565c19caa0135b7504e3be1f09f73a4e2017f7 100644
--- a/lib/backup/targets/database.rb
+++ b/lib/backup/targets/database.rb
@@ -7,7 +7,8 @@ module Targets
     class Database < Target
       extend ::Gitlab::Utils::Override
       include Backup::Helper
-      attr_reader :force, :errors
+
+      attr_reader :force, :errors, :logger
 
       IGNORED_ERRORS = [
         # Ignore warnings
@@ -24,6 +25,7 @@ def initialize(progress, options:)
 
         @errors = []
         @force = options.force?
+        @logger = Gitlab::BackupLogger.new(progress)
       end
 
       override :dump
@@ -39,7 +41,7 @@ def dump(destination_dir, _)
           dump_file_name = file_name(destination_dir, backup_connection.connection_name)
           FileUtils.rm_f(dump_file_name)
 
-          progress.print "Dumping PostgreSQL database #{pg_database_name} ... "
+          logger.info "Dumping PostgreSQL database #{pg_database_name} ... "
 
           schemas = []
 
@@ -61,8 +63,7 @@ def dump(destination_dir, _)
           raise DatabaseBackupError.new(active_record_config, dump_file_name) unless success
 
           report_success(success)
-
-          progress.flush
+          logger.flush
         end
       ensure
         if multiple_databases?
@@ -96,12 +97,12 @@ def restore(destination_dir, _)
           unless File.exist?(db_file_name)
             raise(Backup::Error, "Source database file does not exist #{db_file_name}") if main_database?(database_name)
 
-            progress.puts "Source backup for the database #{database_name} doesn't exist. Skipping the task"
+            logger.info "Source backup for the database #{database_name} doesn't exist. Skipping the task"
             return false
           end
 
           unless force
-            progress.puts 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort'.color(:yellow)
+            logger.info 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort'
             sleep(5)
           end
 
@@ -119,7 +120,7 @@ def restore(destination_dir, _)
             status, tracked_errors =
               case config[:adapter]
               when "postgresql" then
-                progress.print "Restoring PostgreSQL database #{database} ... "
+                logger.info "Restoring PostgreSQL database #{database} ... "
                 execute_and_track_errors(pg_restore_cmd(database), decompress_rd)
               end
             decompress_rd.close
@@ -129,9 +130,9 @@ def restore(destination_dir, _)
           end
 
           unless tracked_errors.empty?
-            progress.print "------ BEGIN ERRORS -----\n".color(:yellow)
-            progress.print tracked_errors.join.color(:yellow)
-            progress.print "------ END ERRORS -------\n".color(:yellow)
+            logger.error "------ BEGIN ERRORS -----\n"
+            logger.error tracked_errors.join
+            logger.error "------ END ERRORS -------\n"
 
             @errors += tracked_errors
           end
@@ -191,17 +192,13 @@ def execute_and_track_errors(cmd, decompress_rd)
       end
 
       def report_success(success)
-        if success
-          progress.puts '[DONE]'.color(:green)
-        else
-          progress.puts '[FAILED]'.color(:red)
-        end
+        success ? logger.info('[DONE]') : logger.error('[FAILED]')
       end
 
       private
 
       def drop_tables(database_name)
-        puts_time 'Cleaning the database ... '.color(:blue)
+        logger.info 'Cleaning the database ... '
 
         if Rake::Task.task_defined? "gitlab:db:drop_tables:#{database_name}"
           Rake::Task["gitlab:db:drop_tables:#{database_name}"].invoke
@@ -210,7 +207,7 @@ def drop_tables(database_name)
           Rake::Task["gitlab:db:drop_tables"].invoke
         end
 
-        puts_time 'done'.color(:green)
+        logger.info 'done'
       end
 
       # @deprecated This will be removed when restore operation is refactored to use extended_env directly
diff --git a/lib/backup/targets/repositories.rb b/lib/backup/targets/repositories.rb
index 6d4456434fbb75241cb4c24755df8f39b0a05a4a..cfa615f4b3e4a7f119ff90708eab853be326bf5d 100644
--- a/lib/backup/targets/repositories.rb
+++ b/lib/backup/targets/repositories.rb
@@ -20,6 +20,7 @@ def initialize(progress, strategy:, options:, storages: [], paths: [], skip_path
         @storages = storages
         @paths = paths
         @skip_paths = skip_paths
+        @logger = Gitlab::BackupLogger.new(progress)
       end
 
       override :dump
@@ -49,7 +50,7 @@ def restore(destination_path, backup_id)
 
       private
 
-      attr_reader :strategy, :storages, :paths, :skip_paths
+      attr_reader :strategy, :storages, :paths, :skip_paths, :logger
 
       def remove_all_repositories
         return if paths.present?
@@ -125,10 +126,10 @@ def skipped_path_relation
 
       def restore_object_pools
         PoolRepository.includes(:source_project).find_each do |pool|
-          progress.puts " - Object pool #{pool.disk_path}..."
+          logger.info " - Object pool #{pool.disk_path}..."
 
           unless pool.source_project
-            progress.puts " - Object pool #{pool.disk_path}... " + "[SKIPPED]".color(:cyan)
+            logger.info " - Object pool #{pool.disk_path}... [SKIPPED]"
             next
           end
 
diff --git a/lib/backup/targets/target.rb b/lib/backup/targets/target.rb
index 05685659d871b23ef263b43c9a4d5291550b6684..e5cec482bc649abd5f198a533f984d74b99e089b 100644
--- a/lib/backup/targets/target.rb
+++ b/lib/backup/targets/target.rb
@@ -25,15 +25,6 @@ def dump(path, backup_id)
       def restore(path, backup_id)
         raise NotImplementedError
       end
-
-      private
-
-      attr_reader :progress
-
-      def puts_time(msg)
-        progress.puts "#{Time.zone.now} -- #{msg}"
-        Gitlab::BackupLogger.info(message: Rainbow.uncolor(msg).to_s)
-      end
     end
   end
 end
diff --git a/lib/gitlab/backup_logger.rb b/lib/gitlab/backup_logger.rb
index ec85c55d4a49f11e2da891b13feea563a431b05a..ee613701f72ea1dd3a2d50ff0a19adb7a5b10ded 100644
--- a/lib/gitlab/backup_logger.rb
+++ b/lib/gitlab/backup_logger.rb
@@ -4,6 +4,34 @@ module Gitlab
   class BackupLogger < Gitlab::JsonLogger
     exclude_context!
 
+    attr_reader :progress
+
+    def initialize(progress)
+      @progress = progress
+    end
+
+    def warn(message)
+      progress.puts "#{Time.zone.now} -- #{message}".color(:yellow)
+
+      super
+    end
+
+    def info(message)
+      progress.puts "#{Time.zone.now} -- #{message}".color(:cyan)
+
+      super
+    end
+
+    def error(message)
+      progress.puts "#{Time.zone.now} -- #{message}".color(:red)
+
+      super
+    end
+
+    def flush
+      progress.flush
+    end
+
     def self.file_name_noext
       'backup_json'
     end
diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb
index d0f911b90a96fd55e82d0eee6f7d421328f63711..df5027fbcd4d07e764e672ba56815925cef3571e 100644
--- a/spec/lib/backup/manager_spec.rb
+++ b/spec/lib/backup/manager_spec.rb
@@ -5,7 +5,8 @@
 RSpec.describe Backup::Manager, feature_category: :backup_restore do
   include StubENV
 
-  let(:progress) { StringIO.new }
+  let_it_be(:progress) { StringIO.new }
+  let(:logger) { subject.logger }
   let(:backup_tasks) { nil }
   let(:options) { build(:backup_options, :skip_none) }
 
@@ -18,8 +19,7 @@
     allow(File).to receive(:exist?).and_call_original
     allow(FileUtils).to receive(:rm_rf).and_call_original
 
-    allow(progress).to receive(:puts)
-    allow(progress).to receive(:print)
+    allow(progress).to receive(:puts).and_call_original
   end
 
   def backup_path
@@ -30,7 +30,7 @@ def backup_path
     describe 'other task' do
       let(:terraform_state) do
         Backup::Tasks::TerraformState.new(progress: progress, options: options)
-                                     .tap { |state| allow(state).to receive(:target).and_return(target) }
+                                    .tap { |state| allow(state).to receive(:target).and_return(target) }
       end
 
       let(:target) { instance_double(Backup::Targets::Target) }
@@ -40,8 +40,8 @@ def backup_path
 
       it 'runs the provided task' do
         expect(target).to receive(:dump)
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping terraform states ... ')
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping terraform states ... done')
+        expect(logger).to receive(:info).with('Dumping terraform states ... ')
+        expect(logger).to receive(:info).with('Dumping terraform states ... done')
 
         subject.run_create_task(terraform_state)
       end
@@ -51,7 +51,7 @@ def backup_path
           allow(terraform_state).to receive(:enabled).and_return(false)
 
           expect(target).not_to receive(:dump)
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping terraform states ... [DISABLED]')
+          expect(logger).to receive(:info).with('Dumping terraform states ... [DISABLED]')
 
           subject.run_create_task(terraform_state)
         end
@@ -62,7 +62,7 @@ def backup_path
           stub_env('SKIP', 'terraform_state')
 
           expect(target).not_to receive(:dump)
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping terraform states ... [SKIPPED]')
+          expect(logger).to receive(:info).with('Dumping terraform states ... [SKIPPED]')
 
           subject.run_create_task(terraform_state)
         end
@@ -73,7 +73,7 @@ def backup_path
   describe 'database task' do
     let(:backup_state) do
       Backup::Tasks::Database.new(progress: progress, options: options)
-                             .tap { |state| allow(state).to receive(:target).and_return(target) }
+                                   .tap { |state| allow(state).to receive(:target).and_return(target) }
     end
 
     let(:target) { instance_double(Backup::Targets::Target) }
@@ -83,8 +83,8 @@ def backup_path
 
     it 'runs the provided task' do
       expect(target).to receive(:dump)
-      expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... ')
-      expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... done')
+      expect(logger).to receive(:info).with('Dumping database ... ')
+      expect(logger).to receive(:info).with('Dumping database ... done')
 
       subject.run_create_task(backup_tasks)
     end
@@ -92,8 +92,8 @@ def backup_path
     context 'when the task succeeds' do
       it 'returns true' do
         expect(target).to receive(:dump)
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... ')
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... done')
+        expect(logger).to receive(:info).with('Dumping database ... ')
+        expect(logger).to receive(:info).with('Dumping database ... done')
         expect(subject.run_create_task(backup_tasks)).to be_truthy
       end
     end
@@ -101,9 +101,8 @@ def backup_path
     context 'when the task fails with a known error' do
       it 'returns false' do
         allow(target).to receive(:dump).and_raise(Backup::DatabaseBackupError.new({ host: 'foo', port: 'bar', database: 'baz' }, 'foo'))
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... ')
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: match('Dumping database failed: Failed to create compressed file '))
-
+        expect(logger).to receive(:info).with('Dumping database ... ')
+        expect(logger).to receive(:error).with(/Dumping database failed: Failed to create compressed file/)
         expect(subject.run_create_task(backup_tasks)).to be_falsey
       end
     end
@@ -111,7 +110,7 @@ def backup_path
     context 'when the task fails with an unknown error' do
       it 'returns false' do
         allow(target).to receive(:dump).and_raise(StandardError)
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... ')
+        expect(logger).to receive(:info).with('Dumping database ... ')
 
         expect do
           subject.run_create_task(backup_tasks)
@@ -147,18 +146,19 @@ def backup_path
 
     it 'runs the provided task' do
       expect(target).to receive(:restore)
-      expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered
-      expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered
+
+      expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered
+      expect(logger).to receive(:info).with('Restoring terraform states ... done').ordered
 
       subject.run_restore_task(terraform_state)
     end
 
-    context 'when disabled' do
-      it 'does not run the task and informs the user' do
+    describe 'disabled' do
+      it 'informs the user' do
         allow(terraform_state).to receive(:enabled).and_return(false)
 
         expect(target).not_to receive(:restore)
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... [DISABLED]').ordered
+        expect(logger).to receive(:info).with('Restoring terraform states ... [DISABLED]').ordered
 
         subject.run_restore_task(terraform_state)
       end
@@ -167,88 +167,52 @@ def backup_path
     describe 'pre_restore_warning' do
       let(:pre_restore_warning) { 'Watch out!' }
 
-      describe 'skip prompt' do
-        before do
-          stub_env('GITLAB_ASSUME_YES', 1)
-        end
-
-        it 'does not ask to continue' do
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered
-          expect(Gitlab::TaskHelpers).not_to receive(:prompt)
-          expect(target).to receive(:restore)
+      it 'displays and waits for the user' do
+        expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered
+        expect(logger).to receive(:warn).with('Watch out!').ordered
+        expect(logger).to receive(:info).with('Restoring terraform states ... done').ordered
+        expect(Gitlab::TaskHelpers).to receive(:ask_to_continue)
+        expect(target).to receive(:restore)
 
-          subject.run_restore_task(terraform_state)
-        end
+        subject.run_restore_task(terraform_state)
       end
 
-      describe 'with prompt' do
-        it 'displays and waits for the user' do
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered
-          expect(Gitlab::TaskHelpers).to receive(:ask_to_continue)
-          expect(target).to receive(:restore)
+      it 'does not continue when the user quits' do
+        expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered
+        expect(logger).to receive(:warn).with('Watch out!').ordered
+        expect(logger).to receive(:error).with('Quitting...').ordered
+        expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError)
 
+        expect do
           subject.run_restore_task(terraform_state)
-        end
-
-        it 'does not continue when the user quits' do
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Quitting...').ordered
-          expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError)
-
-          expect do
-            subject.run_restore_task(terraform_state)
-          end.to raise_error(SystemExit)
-        end
+        end.to raise_error(SystemExit)
       end
     end
 
     describe 'post_restore_warning' do
       let(:post_restore_warning) { 'Watch out!' }
 
-      describe 'skip prompt' do
-        before do
-          stub_env('GITLAB_ASSUME_YES', 1)
-        end
+      it 'displays and waits for the user' do
+        expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered
+        expect(logger).to receive(:info).with('Restoring terraform states ... done').ordered
+        expect(logger).to receive(:warn).with('Watch out!').ordered
+        expect(Gitlab::TaskHelpers).to receive(:ask_to_continue)
+        expect(target).to receive(:restore)
 
-        it "does not ask to continue" do
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
-          expect(Gitlab::TaskHelpers).not_to receive(:prompt)
-          expect(target).to receive(:restore)
-
-          subject.run_restore_task(terraform_state)
-        end
+        subject.run_restore_task(terraform_state)
       end
 
-      describe "prompt" do
-        it 'displays and waits for the user' do
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
-          expect(Gitlab::TaskHelpers).to receive(:ask_to_continue)
-          expect(target).to receive(:restore)
+      it 'does not continue when the user quits' do
+        expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered
+        expect(logger).to receive(:info).with('Restoring terraform states ... done').ordered
+        expect(logger).to receive(:warn).with('Watch out!').ordered
+        expect(logger).to receive(:error).with('Quitting...').ordered
+        expect(target).to receive(:restore)
+        expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError)
 
+        expect do
           subject.run_restore_task(terraform_state)
-        end
-
-        it 'does not continue when the user quits' do
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
-          expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Quitting...').ordered
-          expect(target).to receive(:restore)
-          expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError)
-
-          expect do
-            subject.run_restore_task(terraform_state)
-          end.to raise_error(SystemExit)
-        end
+        end.to raise_error(SystemExit)
       end
     end
   end
@@ -271,7 +235,6 @@ def backup_path
     before do
       stub_env('INCREMENTAL', incremental_env)
       allow(ApplicationRecord.connection).to receive(:reconnect!)
-      allow(Gitlab::BackupLogger).to receive(:info)
     end
 
     it 'creates a backup tar' do
@@ -308,7 +271,7 @@ def backup_path
             subject.create # rubocop:disable Rails/SaveBang
           end.to raise_error(Backup::Error, 'Backup failed')
 
-          expect(Gitlab::BackupLogger).to have_received(:info).with(message: "Creating archive #{pack_tar_file} failed")
+          expect(progress.string).to include("Creating archive #{pack_tar_file} failed")
           expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml'))
           expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp'))
         end
@@ -361,8 +324,6 @@ def backup_path
         end
 
         before do
-          allow(Gitlab::BackupLogger).to receive(:info)
-
           files.each do |bkp|
             FileUtils.touch(backup_path.join(bkp))
           end
@@ -385,7 +346,7 @@ def backup_path
           end
 
           it 'prints a skipped message' do
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... [SKIPPED]')
+            expect(progress.string).to include('Deleting old backups ... [SKIPPED]')
           end
         end
 
@@ -411,7 +372,7 @@ def backup_path
           end
 
           it 'prints a done message' do
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... done. (0 removed)')
+            expect(progress.string).to include('Deleting old backups ... done. (0 removed)')
           end
         end
 
@@ -430,7 +391,7 @@ def backup_path
           end
 
           it 'prints a done message' do
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... done. (0 removed)')
+            expect(progress.string).to include('Deleting old backups ... done. (0 removed)')
           end
         end
 
@@ -471,7 +432,7 @@ def backup_path
           end
 
           it 'prints a done message' do
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... done. (8 removed)')
+            expect(progress.string).to include('Deleting old backups ... done. (8 removed)')
           end
         end
 
@@ -495,11 +456,11 @@ def backup_path
           end
 
           it 'sets the correct removed count' do
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... done. (7 removed)')
+            expect(progress.string).to include('Deleting old backups ... done. (7 removed)')
           end
 
           it 'prints the error from file that could not be removed' do
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: a_string_matching(message))
+            expect(progress.string).to include(message)
           end
         end
       end
@@ -509,7 +470,6 @@ def backup_path
         let(:backup_filename) { File.basename(backup_file.path) }
 
         before do
-          allow(Gitlab::BackupLogger).to receive(:info)
           allow_next_instance_of(described_class) do |manager|
             allow(manager).to receive(:tar_file).and_return(backup_filename)
             allow(manager.remote_storage).to receive(:tar_file).and_return(backup_filename)
@@ -550,15 +510,15 @@ def backup_path
             stub_env('SKIP', 'remote')
             subject.create # rubocop:disable Rails/SaveBang
 
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Uploading backup archive to remote storage directory ... [SKIPPED]')
+            expect(progress.string).to include('Uploading backup archive to remote storage directory ... [SKIPPED]')
           end
         end
 
         context 'target path' do
           it 'uses the tar filename by default' do
             expect_any_instance_of(Fog::Collection).to receive(:create)
-                                                         .with(hash_including(key: backup_filename, public: false))
-                                                         .and_call_original
+              .with(hash_including(key: backup_filename, public: false))
+              .and_call_original
 
             subject.create # rubocop:disable Rails/SaveBang
           end
@@ -567,8 +527,8 @@ def backup_path
             stub_env('DIRECTORY', 'daily')
 
             expect_any_instance_of(Fog::Collection).to receive(:create)
-                                                         .with(hash_including(key: "daily/#{backup_filename}", public: false))
-                                                         .and_call_original
+              .with(hash_including(key: "daily/#{backup_filename}", public: false))
+              .and_call_original
 
             subject.create # rubocop:disable Rails/SaveBang
           end
@@ -606,7 +566,7 @@ def backup_path
             it 'sets encryption attributes' do
               subject.create # rubocop:disable Rails/SaveBang
 
-              expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Uploading backup archive to remote storage directory ... done (encrypted with AES256)')
+              expect(progress.string).to include('Uploading backup archive to remote storage directory ... done (encrypted with AES256)')
             end
           end
 
@@ -617,7 +577,7 @@ def backup_path
             it 'sets encryption attributes' do
               subject.create # rubocop:disable Rails/SaveBang
 
-              expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Uploading backup archive to remote storage directory ... done (encrypted with AES256)')
+              expect(progress.string).to include('Uploading backup archive to remote storage directory ... done (encrypted with AES256)')
             end
           end
 
@@ -632,7 +592,7 @@ def backup_path
             it 'sets encryption attributes' do
               subject.create # rubocop:disable Rails/SaveBang
 
-              expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Uploading backup archive to remote storage directory ... done (encrypted with aws:kms)')
+              expect(progress.string).to include('Uploading backup archive to remote storage directory ... done (encrypted with aws:kms)')
             end
           end
         end
@@ -660,8 +620,8 @@ def backup_path
 
           it 'does not attempt to set ACL' do
             expect_any_instance_of(Fog::Collection).to receive(:create)
-                                                         .with(hash_excluding(public: false))
-                                                         .and_call_original
+              .with(hash_excluding(public: false))
+              .and_call_original
 
             subject.create # rubocop:disable Rails/SaveBang
           end
@@ -747,8 +707,7 @@ def backup_path
 
         it 'fails the operation and prints an error' do
           expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
-          expect(progress).to have_received(:puts)
-                                .with(a_string_matching('No backups found'))
+          expect(progress.string).to include('No backups found')
         end
       end
 
@@ -764,14 +723,14 @@ def backup_path
 
         it 'prints the list of available backups' do
           expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
-          expect(progress).to have_received(:puts).with(a_string_matching('1451606400_2016_01_01_1.2.3'))
-          expect(progress).to have_received(:puts).with(a_string_matching('1451520000_2015_12_31'))
+
+          expect(progress.string).to include('1451606400_2016_01_01_1.2.3')
+          expect(progress.string).to include('1451520000_2015_12_31')
         end
 
         it 'fails the operation and prints an error' do
           expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
-          expect(progress).to have_received(:puts)
-                                .with(a_string_matching('Found more than one backup'))
+          expect(progress.string).to include('Found more than one backup')
         end
       end
 
@@ -790,8 +749,7 @@ def backup_path
         it 'fails the operation and prints an error' do
           expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
           expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar')
-          expect(progress).to have_received(:puts)
-                                .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist'))
+          expect(progress.string).to include('The backup file wrong_gitlab_backup.tar does not exist')
         end
       end
 
@@ -799,7 +757,6 @@ def backup_path
         let(:backup_id) { '1451606400_2016_01_01_1.2.3' }
 
         before do
-          allow(Gitlab::BackupLogger).to receive(:info)
           allow(Dir).to receive(:glob).and_return(
             [
               '1451606400_2016_01_01_1.2.3_gitlab_backup.tar'
@@ -834,7 +791,7 @@ def backup_path
               subject.create # rubocop:disable Rails/SaveBang
             end.to raise_error(SystemExit)
 
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Unpacking backup failed')
+            expect(progress.string).to include('Unpacking backup failed')
           end
         end
 
@@ -848,7 +805,7 @@ def backup_path
               subject.create # rubocop:disable Rails/SaveBang
             end.to raise_error(Backup::Error, 'Backup failed')
 
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: "Creating archive #{pack_tar_file} failed")
+            expect(progress.string).to include("Creating archive #{pack_tar_file} failed")
             expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml'))
             expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp'))
           end
@@ -864,8 +821,7 @@ def backup_path
 
           it 'stops the process' do
             expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
-            expect(progress).to have_received(:puts)
-                                  .with(a_string_matching('GitLab version mismatch'))
+            expect(progress.string).to include('GitLab version mismatch')
           end
         end
       end
@@ -885,8 +841,7 @@ def backup_path
         it 'fails the operation and prints an error' do
           expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
           expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar')
-          expect(progress).to have_received(:puts)
-                                .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist'))
+          expect(progress.string).to include('The backup file wrong_gitlab_backup.tar does not exist')
         end
       end
 
@@ -894,7 +849,6 @@ def backup_path
         let(:full_backup_id) { 'some_previous_backup' }
 
         before do
-          allow(Gitlab::BackupLogger).to receive(:info)
           allow(Dir).to receive(:glob).and_return(
             [
               'some_previous_backup_gitlab_backup.tar'
@@ -931,7 +885,7 @@ def backup_path
               end
             end.to raise_error(SystemExit)
 
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Unpacking backup failed')
+            expect(progress.string).to include('Unpacking backup failed')
           end
         end
 
@@ -949,7 +903,7 @@ def backup_path
               end
             end.to raise_error(Backup::Error, 'Backup failed')
 
-            expect(Gitlab::BackupLogger).to have_received(:info).with(message: "Creating archive #{pack_tar_file} failed")
+            expect(progress.string).to include("Creating archive #{pack_tar_file} failed")
             expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml'))
             expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp'))
           end
@@ -965,8 +919,7 @@ def backup_path
 
           it 'stops the process' do
             expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
-            expect(progress).to have_received(:puts)
-                                  .with(a_string_matching('GitLab version mismatch'))
+            expect(progress.string).to include('GitLab version mismatch')
           end
         end
       end
@@ -1000,10 +953,8 @@ def backup_path
             subject.create # rubocop:disable Rails/SaveBang
           end
 
-          expect(progress).to have_received(:puts)
-                                .with(a_string_matching('Non tarred backup found '))
-          expect(progress).to have_received(:puts)
-                                .with(a_string_matching("Backup #{backup_id} is done"))
+          expect(progress.string).to include('Non tarred backup found ')
+          expect(progress.string).to include("Backup #{backup_id} is done")
           expect(subject.send(:backup_information).to_h).to include(
             backup_created_at: backup_time,
             full_backup_id: full_backup_id,
@@ -1021,8 +972,7 @@ def backup_path
 
           it 'stops the process' do
             expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang
-            expect(progress).to have_received(:puts)
-                                  .with(a_string_matching('GitLab version mismatch'))
+            expect(progress.string).to include('GitLab version mismatch')
           end
         end
       end
@@ -1076,7 +1026,6 @@ def backup_path
       Rake.application.rake_require 'tasks/gitlab/shell'
       Rake.application.rake_require 'tasks/cache'
 
-      allow(Gitlab::BackupLogger).to receive(:info)
       allow(target1).to receive(:restore).with(backup_path.join('lfs.tar.gz'), backup_id)
       allow(target2).to receive(:restore).with(backup_path.join('pages.tar.gz'), backup_id)
       allow_next_instance_of(Backup::Metadata) do |metadata|
@@ -1093,8 +1042,7 @@ def backup_path
 
       it 'fails the operation and prints an error' do
         expect { subject.restore }.to raise_error SystemExit
-        expect(progress).to have_received(:puts)
-                              .with(a_string_matching('No backups found'))
+        expect(progress.string).to include('No backups found')
       end
     end
 
@@ -1110,14 +1058,13 @@ def backup_path
 
       it 'prints the list of available backups' do
         expect { subject.restore }.to raise_error SystemExit
-        expect(progress).to have_received(:puts).with(a_string_matching('1451606400_2016_01_01_1.2.3'))
-        expect(progress).to have_received(:puts).with(a_string_matching('1451520000_2015_12_31'))
+        expect(progress.string).to include('1451606400_2016_01_01_1.2.3')
+        expect(progress.string).to include('1451520000_2015_12_31')
       end
 
       it 'fails the operation and prints an error' do
         expect { subject.restore }.to raise_error SystemExit
-        expect(progress).to have_received(:puts)
-                              .with(a_string_matching('Found more than one backup'))
+        expect(progress.string).to include('Found more than one backup')
       end
     end
 
@@ -1136,8 +1083,7 @@ def backup_path
       it 'fails the operation and prints an error' do
         expect { subject.restore }.to raise_error SystemExit
         expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar')
-        expect(progress).to have_received(:puts)
-                              .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist'))
+        expect(progress.string).to include('The backup file wrong_gitlab_backup.tar does not exist')
       end
     end
 
@@ -1146,7 +1092,6 @@ def backup_path
       let(:backup_id) { "1451606400_2016_01_01_1.2.3" }
 
       before do
-        allow(Gitlab::BackupLogger).to receive(:info)
         allow(Dir).to receive(:glob).and_return(
           [
             '1451606400_2016_01_01_1.2.3_gitlab_backup.tar'
@@ -1198,7 +1143,7 @@ def backup_path
             subject.restore
           end.to raise_error(SystemExit)
 
-          expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Unpacking backup failed')
+          expect(progress.string).to include('Unpacking backup failed')
         end
       end
 
@@ -1212,8 +1157,7 @@ def backup_path
 
         it 'stops the process' do
           expect { subject.restore }.to raise_error SystemExit
-          expect(progress).to have_received(:puts)
-                                .with(a_string_matching('GitLab version mismatch'))
+          expect(progress.string).to include('GitLab version mismatch')
         end
       end
     end
@@ -1233,8 +1177,7 @@ def backup_path
 
         subject.restore
 
-        expect(progress).to have_received(:puts)
-                              .with(a_string_matching('Non tarred backup found '))
+        expect(progress.string).to include('Non tarred backup found ')
         expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp'))
       end
 
@@ -1248,8 +1191,7 @@ def backup_path
 
         it 'stops the process' do
           expect { subject.restore }.to raise_error SystemExit
-          expect(progress).to have_received(:puts)
-                                .with(a_string_matching('GitLab version mismatch'))
+          expect(progress.string).to include('GitLab version mismatch')
         end
       end
     end
diff --git a/spec/lib/backup/targets/database_spec.rb b/spec/lib/backup/targets/database_spec.rb
index fe293f80d3153668fcbe52bcdf4343c779d4e16a..26fa769f83a24658ac8058580d4ebc54ecc197f9 100644
--- a/spec/lib/backup/targets/database_spec.rb
+++ b/spec/lib/backup/targets/database_spec.rb
@@ -9,6 +9,7 @@
   let(:one_database_configured?) { base_models_for_backup.one? }
   let(:force) { true }
   let(:backup_options) { Backup::Options.new(force: force) }
+  let(:logger) { subject.logger }
   let(:timeout_service) do
     instance_double(Gitlab::Database::TransactionTimeoutSettings, restore_timeouts: nil, disable_timeouts: nil)
   end
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index 2ebad71ef8ece83f3c73a486a76afdf920f786d7..88abe2401fdcf112f3d418684da696c8ae3d98f3 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -9,6 +9,8 @@
     %w[db repo uploads builds artifacts pages lfs terraform_state registry packages ci_secure_files]
   end
 
+  let(:progress) { StringIO.new }
+
   let(:backup_task_ids) do
     %w[db repositories uploads builds artifacts pages lfs terraform_state registry packages ci_secure_files]
   end
@@ -298,6 +300,9 @@ def reenable_backup_sub_tasks
     context 'with specific backup tasks' do
       before do
         stub_env('SKIP', 'db')
+        allow_next_instance_of(Gitlab::BackupLogger) do |instance|
+          allow(instance).to receive(:info).and_call_original
+        end
       end
 
       it 'prints a progress message to stdout' do
@@ -307,27 +312,29 @@ def reenable_backup_sub_tasks
       end
 
       it 'logs the progress to log file' do
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping database ... [SKIPPED]")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping repositories ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping repositories ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping uploads ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping uploads ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping builds ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping builds ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping artifacts ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping artifacts ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping pages ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping pages ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping lfs objects ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping lfs objects ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping terraform states ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping terraform states ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping container registry images ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping container registry images ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping packages ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping packages ... done")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping ci secure files ... ")
-        expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping ci secure files ... done")
+        expect_logger_to_receive_messages([
+          "Dumping database ... [SKIPPED]",
+          "Dumping repositories ... ",
+          "Dumping repositories ... done",
+          "Dumping uploads ... ",
+          "Dumping uploads ... done",
+          "Dumping builds ... ",
+          "Dumping builds ... done",
+          "Dumping artifacts ... ",
+          "Dumping artifacts ... done",
+          "Dumping pages ... ",
+          "Dumping pages ... done",
+          "Dumping lfs objects ... ",
+          "Dumping lfs objects ... done",
+          "Dumping terraform states ... ",
+          "Dumping terraform states ... done",
+          "Dumping container registry images ... ",
+          "Dumping container registry images ... done",
+          "Dumping packages ... ",
+          "Dumping packages ... done",
+          "Dumping ci secure files ... ",
+          "Dumping ci secure files ... done"
+        ])
 
         backup_rake_task_names.each do |task|
           run_rake_task("gitlab:backup:#{task}:create")
@@ -718,5 +725,13 @@ def reenable_backup_sub_tasks
       expect(backup_tar).to match(/\d+_\d{4}_\d{2}_\d{2}_\d+\.\d+\.\d+.*_gitlab_backup.tar$/)
     end
   end
+
+  def expect_logger_to_receive_messages(messages)
+    expect_any_instance_of(Gitlab::BackupLogger) do |logger|
+      messages.each do |message|
+        allow(logger).to receive(:info).with(message).ordered
+      end
+    end
+  end
 end
 # gitlab:app namespace