Class: RightScale::History

Inherits:
Object show all
Defined in:
lib/right_agent/history.rb

Overview

Agent history manager

Instance Method Summary collapse

Constructor Details

#initialize(identity, pid = nil) ⇒ History

Initialize history

Parameters

identity(String)

Serialized agent identity

pid(Integer)

Process ID of agent, defaults to ID if current process



35
36
37
38
# File 'lib/right_agent/history.rb', line 35

def initialize(identity, pid = nil)
  @pid = pid || Process.pid
  @history = File.join(AgentConfig.pid_dir, identity + ".history")
end

Instance Method Details

#analyze_serviceObject

Analyze history to determine service attributes like uptime and restart/crash counts

Return

(Hash)

Results of analysis

:uptime(Integer)

Current time in service

:total_uptime(Integer)

Total time in service (but if there were crashes

  this total includes recovery time, which makes it inaccurate)
:restarts(Integer|nil):: Number of restarts, if any
:graceful_exits(Integer|nil):: Number of graceful terminations, if any
:crashes(Integer|nil):: Number of crashes, if any
:last_crash_time(Integer|nil):: Time in seconds in Unix-epoch when last crash occurred, if any
:crashed_last(Boolean):: Whether crashed last time it was started


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/right_agent/history.rb', line 81

def analyze_service
  now = Time.now.to_i
  if @last_analysis && @last_event == @last_update
    delta = now - @last_analysis_time
    @last_analysis[:uptime] += delta
    @last_analysis[:total_uptime] += delta
  else
    last_run = last_crash = @last_event = {:time => 0, :pid => 0, :event => nil}
    restarts = graceful_exits = crashes = accumulated_uptime = 0
    crashed_last = false
    load.each do |event|
      event = SerializationHelper.symbolize_keys(event)
      case event[:event]
      when "start"
        case @last_event[:event]
        when "stop", "graceful exit"
          restarts += 1
        when "start"
          crashes += 1
          last_crash = event
          crashed_last = true
        when "run"
          crashes += 1
          last_crash = event
          crashed_last = true
          # Accumulating uptime here although this will wrongly include recovery time
          accumulated_uptime += (event[:time] - @last_event[:time])
        end
      when "run"
        last_run = event
      when "stop"
        crashed_last = false
        if @last_event[:event] == "run" && @last_event[:pid] == event[:pid]
          accumulated_uptime += (event[:time] - @last_event[:time])
        end
      when "graceful exit"
        crashed_last = false
        graceful_exits += 1
      else
        next
      end
      @last_event = event
    end
    current_uptime = last_run[:pid] == @pid ? (now - last_run[:time]) : 0
    @last_analysis = {
      :uptime => current_uptime,
      :total_uptime => accumulated_uptime + current_uptime
    }
    if restarts > 0
      @last_analysis[:restarts] = restarts
      @last_analysis[:graceful_exits] = graceful_exits
    end
    if crashes > 0
      @last_analysis[:crashes] = crashes
      @last_analysis[:last_crash_time] = last_crash[:time]
      @last_analysis[:crashed_last] = crashed_last
    end
  end
  @last_analysis_time = now
  @last_analysis
end

#loadObject

Load events from history file

Return

events(Array)

List of historical events with each being a hash of

:time(Integer)

Time in seconds in Unix-epoch when event occurred

:pid(Integer)

Process id of agent recording the event

:event(Object)

Event object in the form String or => Object,

where String is the event name and Object is any associated JSON-encodable data


63
64
65
66
67
# File 'lib/right_agent/history.rb', line 63

def load
  events = []
  File.open(@history, "r") { |f| events = f.readlines.map { |l| JSON.legacy_load(l) } } if File.readable?(@history)
  events
end

#update(event) ⇒ Object

Append event to history file

Parameters

event(Object)

Event to be stored in the form String or => Object,

where String is the event name and Object is any associated JSON-encodable data

Return

true

Always return true



48
49
50
51
52
53
# File 'lib/right_agent/history.rb', line 48

def update(event)
  @last_update = {:time => Time.now.to_i, :pid => @pid, :event => event}
  FileUtils.mkdir_p(File.dirname(@history)) unless File.exists?(File.dirname(@history))
  File.open(@history, "a") { |f| f.puts @last_update.to_json }
  true
end