searching for a simple ruby/bash solution to investigate a logfile, for example an apache access log.
my log contains lines with beginning string "authorization:"
goal of the script is to return the whole next but one line after this match, which contains the string "x-forwarded-for".
host: 10.127.5.12:8088^M
accept: */*^M
date: Wed, 19 Apr 2019 22:12:36 GMT^M
authorization: FOP ASC-amsterdam-b2c-v7:fkj9234f$t34g34rf=^M
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0)
x-forwarded-for: 195.99.33.222, 10.127.72.254^M
x-forwarded-host: my.luckyhost.com^M
x-forwarded-server: server.luckyhost.de^M
connection: Keep-Alive^M
^M
My question relates to the if condition. How can I get the line number/caller from readline and in second step return the whole next line with x-forwarded-for.
file = File.open(args[:apache_access_log], "r")
log_snapshot = file.readlines
file.close
log_snapshot.reverse_each do |line|
if line.include? "authorization:"
puts line
end
end
Maybe something along these lines:
log_snapshot.each_with_index.reverse_each do |line, n|
case (line)
when /authorization:/
puts '%d: %s' % [ n + 1, line ]
end
end
Where each_with_index
is used to generate 0-indexed line numbers. I've switched to a case
style so you can have more flexibility in matching different conditions. For example, you can add the /i
flag to do a case-insensitive match really easily or add \A
at the beginning to anchor it at the beginning of the string.
Another thing to consider using the block method for File.open
, like this:
File.open(args[:apache_access_log], "r") do |f|
f.readlines.each_with_index.reverse_each do |line, n|
# ...
end
end
Where that eliminates the need for an explicit close
call. The end of the block closes it for you automatically.