Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly handle uptimes over a year on AIX #1049

Merged
merged 4 commits into from
Sep 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions lib/ohai/plugins/aix/uptime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,31 @@

collect_data(:aix) do
require "date"
# Example output:
# $ who -b
# . system boot Jul 9 17:51
so = shell_out("who -b")
so.stdout.lines.each do |line|
if line =~ /.* boot (.+)/
uptime_seconds Time.now.to_i - DateTime.parse($1 + " #{Time.now.zone}").strftime("%s").to_i
uptime seconds_to_human(uptime_seconds)
break
end
# below we're going to assume that PID 1 is init (this is true 99.99999% of the time)
# output will look like this
# 1148-20:54:50
# This reads as 1148 days, 20 hours, 54 minutes, 50 seconds since the process was started (elapsed)
# who -b does not return the YEAR, so we need something more concrete
so = shell_out("LC_ALL=POSIX ps -o etime= -p 1").stdout

# Here we'll check our shell_out for a dash, which indicates there is a # of days involved
# We'll chunk off the days, hours (where applicable), minutes, seconds into seperate vars
# We also need to do this because ps -o etime= will not display days if the machine has been up for less than 24 hours
# If the machine has been up for less than one hour, the shell_out will not output hours hence our else
# see here: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.cmds4/ps.htm#ps__row-d3e109655
d = nil
h = nil
case so
when /^\d+-\d/
(d, h, m, s) = so.split(/[-:]/)
when /^\d+:\d+:\d/
(h, m, s) = so.split(/[:]/)
else
(m, s) = so.split(/[:]/)
end
elapsed_seconds = ((d.to_i * 86400) + (h.to_i * 3600) + (m.to_i * 60) + s.to_i)

uptime_seconds Time.now.to_i - elapsed_seconds
uptime seconds_to_human(elapsed_seconds)
end
end
16 changes: 7 additions & 9 deletions spec/unit/plugins/aix/uptime_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,17 @@
before(:each) do
@plugin = get_plugin("aix/uptime")
allow(@plugin).to receive(:collect_os).and_return(:aix)
allow(Time).to receive_message_chain(:now, :to_i).and_return(1412072511)
allow(Time).to receive_message_chain(:now, :zone).and_return("IST")
allow(DateTime).to receive_message_chain(:parse, :strftime, :to_i).and_return(1411561320)
allow(@plugin).to receive(:shell_out).with("who -b").and_return(mock_shell_out(0, " . system boot Sep 24 17:52", nil))

allow(@plugin).to receive(:shell_out).and_call_original
allow(Time).to receive_message_chain(:now, :to_i).and_return(1504287957)
allow(@plugin).to receive(:shell_out).with("LC_ALL=POSIX ps -o etime= -p 1").and_return(mock_shell_out(0, "1148-20:54:50", nil))
@plugin.run
end

it "should set uptime_seconds to uptime" do
expect(@plugin[:uptime_seconds]).to eq(511191)
it "should set uptime_seconds to uptime with days" do
expect(@plugin[:uptime_seconds]).to eq(1405025467)
end

it "should set uptime to a human readable date" do
expect(@plugin[:uptime]).to eq("5 days 21 hours 59 minutes 51 seconds")
it "should set uptime to a human readable date with days" do
expect(@plugin[:uptime]).to eq("1148 days 20 hours 54 minutes 50 seconds")
end
end