ckbrumb
ckbrumb

Reputation: 191

Ruby Date range and matching

I'm writing a small log-sniffer program for my work environment that searches for a few key words in the logs and let's the user know they have some things to look at. That part is pretty simple, but one of the features I'm trying to implement is the option for the user to choose how far back form today they would like to go, so they're not getting errors from months ago that no longer matter.

I've got the date, and I have the gap from now and a user-specified range. I'm just not sure how to get the range and matching working. Here is my code:

require 'date'
### Get the logfile path from the user
p "What is the path to your log file?"
logfile = gets.chomp

### Get number of days user would like to go back
p "How many days back from today would you like to look?"
num_days = gets.chomp


############################################################################################
### Define Log class. Accept argumnet for path of the file. Called by foo = Log.new
############################################################################################
class Log

    def scan_log(file_name, days)
        error_exists = false
        verify = false
        apn = false
        strict = false
        days = days.to_i
        # time = Time.now.strftime("%Y-%m-%d")
        now = Date.today
        days_ago = (now - days)
        p now
        p days_ago

        File.open(file_name, "r") do |file_handle|
            file_handle.each_line do |line|
                if line =~ /Unable to verify signature/
                    verify = true
                    error_exists = true
                end

                if line =~ /gateway.push.apple.com/
                    apn = true
                    error_exists = true
                end

                if line =~ /Data truncation/
                    strict = true
                    error_exists = true
                end
            end
        end

        p "Verify signature error found" if verify


        p "You have an APNS error" if apn


        p "You have strict mode enabled" if strict

    end

end

l = Log.new
l.scan_log(logfile, num_days)

My thought is that a loop under file_handle.each_line do... would work. I would include the existing if statements in the loop, and the loop would match the date range set by the user to the dates in the logs. The format in the log is:

2013-04-17 15:10:42, 767

I don't care about the timestamp, just the datestamp.

Thanks if you can help.

Upvotes: 1

Views: 743

Answers (2)

steenslag
steenslag

Reputation: 80065

You can construct a Range from dates (like the question title suggests) and use it's include? method.

require 'date'

puts "How many days back from today would you like to look?"
days_back = gets.to_i #input: 3

logline_date = "2013-04-17 15:10:42, 767"

end_date = Date.today
start_date = end_date - days_back
selected_range = start_date..end_date

p selected_range.include?( Date.parse( logline_date )) #true (today for me, that is)

Upvotes: 0

Tilo
Tilo

Reputation: 33732

one robust way to parse a free-form date would be:

 > Time.parse(" 2013-04-17 13:15:24 -0700 ").strftime("%Y-%m-%d")
  => "2013-04-17" 
 > Time.parse("Wed Apr 17 13:15:09 PDT 2013 ").strftime("%Y-%m-%d")
  => "2013-04-17" 

assuming the user specifies the start_date in "%Y-%m-%d" format and the time range, you could do this:

 start_date = Time.parse( user_provided_date ) # e.g. "2013-04-10"
 log_date = Time.parse( line )

 do_something if (start_date - log_date) < number_of_seconds  # or whatever time range

If you just want to show all logs which are newer than a given time-range, then you could do this:

 log_date = Time.parse( line )

 do_something if (Time.now - log_date) < number_of_seconds  # or whatever time range

To get pretty time ranges in Rails style, like 1.day or 12.hours , you can include ActiveSupport::Duration

Upvotes: 1

Related Questions