Merge branch 'master' into 5383-api-db-current-time
[arvados.git] / services / api / lib / simulate_job_log.rb
1 require 'db_current_time'
2
3 module SimulateJobLog
4   include DbCurrentTime
5
6   def replay(filename, multiplier = 1, simulated_job_uuid = nil)
7     raise "Environment must be development or test" unless [ 'test', 'development' ].include? ENV['RAILS_ENV']
8
9     multiplier = multiplier.to_f
10     multiplier = 1.0 if multiplier <= 0
11
12     actual_start_time = db_current_time
13     log_start_time = nil
14
15     act_as_system_user do
16       File.open(filename).each.with_index do |line, index|
17         cols = {}
18         cols[:timestamp], rest_of_line = line.split(' ', 2)
19         begin
20           cols[:timestamp] = Time.strptime( cols[:timestamp], "%Y-%m-%d_%H:%M:%S" )
21         rescue ArgumentError
22           if line =~ /^((?:Sun|Mon|Tue|Wed|Thu|Fri|Sat) (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2} \d\d:\d\d:\d\d \d{4}) (.*)/
23             # Wed Nov 19 07:12:39 2014
24             cols[:timestamp] = Time.strptime( $1, "%a %b %d %H:%M:%S %Y" )
25             rest_of_line = $2
26           else
27               STDERR.puts "Ignoring log line because of unknown time format: #{line}"
28           end
29         end
30         cols[:job_uuid], cols[:pid], cols[:task], cols[:event_type], cols[:message] = rest_of_line.split(' ', 5)
31         # Override job uuid with a simulated one if specified
32         cols[:job_uuid] = simulated_job_uuid || cols[:job_uuid]
33         # determine when we want to simulate this log being created, based on the time multiplier
34         log_start_time = cols[:timestamp] if log_start_time.nil?
35         log_time = cols[:timestamp]
36         actual_elapsed_time = db_current_time - actual_start_time
37         log_elapsed_time = log_time - log_start_time
38         modified_elapsed_time = log_elapsed_time / multiplier
39         pause_time = modified_elapsed_time - actual_elapsed_time
40         sleep pause_time if pause_time > 0
41         # output log entry for debugging and create it in the current environment's database
42         puts "#{index} #{cols.to_yaml}\n"
43         Log.new({
44           event_at:    Time.zone.local_to_utc(cols[:timestamp]),
45           object_uuid: cols[:job_uuid],
46           event_type:  cols[:event_type],
47           properties:  { 'text' => line }
48         }).save!
49       end
50     end
51
52   end
53 end