1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 require 'current_api_client'
6 require 'db_current_time'
9 extend CurrentApiClient
12 def self.delete_old(max_age:, max_batch:)
14 if !File.owned?(Rails.root.join('tmp'))
15 Rails.logger.warn("AuditLogs: not owner of #{Rails.root}/tmp, skipping")
18 lockfile = Rails.root.join('tmp', 'audit_logs.lock')
19 File.open(lockfile, File::RDWR|File::CREAT, 0600) do |f|
20 return unless f.flock(File::LOCK_NB|File::LOCK_EX)
22 sql = "select clock_timestamp() - interval '#{'%.9f' % max_age} seconds'"
23 threshold = ActiveRecord::Base.connection.select_value(sql).to_time.utc
24 Rails.logger.info "AuditLogs: deleting logs older than #{threshold}"
31 where('event_type in (?)', ['create', 'update', 'destroy', 'delete']).
32 where('created_at < ?', threshold).
35 did = Log.unscoped.where("id in (#{sql})").delete_all
38 Rails.logger.info "AuditLogs: deleted batch of #{did}"
41 Rails.logger.info "AuditLogs: deleted total #{did_total}"
46 def self.tidy_in_background
47 max_age = Rails.configuration.AuditLogs.MaxAge.to_i
48 max_batch = Rails.configuration.AuditLogs.MaxDeleteBatch
49 return if max_age <= 0 || max_batch <= 0
51 exp = (max_age/14).seconds
53 Rails.cache.fetch('AuditLogs', expires_in: exp) do
59 Thread.current.abort_on_exception = false
61 delete_old(max_age: max_age, max_batch: max_batch)
63 Rails.logger.error "#{e.class}: #{e}\n#{e.backtrace.join("\n\t")}"
65 # Rails 5.1+ makes test threads share a database connection, so we can't
66 # close a connection shared with other threads.
67 # https://github.com/rails/rails/commit/deba47799ff905f778e0c98a015789a1327d5087
68 if Rails.env != "test"
69 ActiveRecord::Base.connection.close