From: "Jesús Gabriel y Galán" Date: 2009-02-04T07:51:49+09:00 Subject: Re: Hash counting On Tue, Feb 3, 2009 at 11:12 PM, Stuart Clarke wrote: > Thanks for your response. It makes a lot more sense and you are on the > right lines I think. There is other code around this but it does not > bare much relevance: > > def scanEVTWithSource(file, source) > @alerts = [] > @evtLogArray = [] This is unneeded, since you later assign another array to this variable without using this one. > begin > #read the contents of the event logs files > evtLog = EventLog.open_backup(file, source) > > #put data into an array > @evtLogArray = evtLog.read.sort { |a, b| (a.event_id <=> > b.event_id).nonzero? || (a.time_written <=> b.time_written)} Are you sure you want to put this in an instance variable? > #event log data collected > evtLog.close > if evtLogArray.length == 0 Shouldn't this be checking the @evtLogArray? > return > end > > #failed logons where more than 10 have occurred in a day > if event.event_id == 529 Here we are reaching the culprit, I think. What is event? It's not defined in this method... > eventdateID = [] > #assign all time written values to the eventsbydate array > eventsbydate = "#{event.time_written}" > eventdateID.push eventsbydate.gsub(/\s/, '')[0..7] + > eventsbydate[26..30] > counts = Hash.new(0) > eventdateID.each {|d| counts[d] += 1} > counts.each do |id,cnt| > @alerts.push("#{event.event_id} #{@tab} #{event.time_written} > #{@tab} #{event.event_type} #{@tab} #{type}") if cnt >= 5 > end > end > end > Let me try to write what I think you want cause I still think the above code is not what you are actually running, cause the above as is will give a NoMethodError in the evtLogArray.length method call. The following is untested: def scanEVTWithSource(file, source) @alerts = [] #read the contents of the event logs files evtLog = EventLog.open_backup(file, source) #put data into an array; sort it using David's advice evtLogArray = evtLog.read.sort_by { |e| [e.event_id, e.time_written] } #event log data collected evtLog.close return if evtLogArray.length == 0 # Important part here: create the hash outside the loop # and, actually, do a loop on evtLogArray counts = Hash.new(0) # select relevant events, mapping them to the modified string events = evtLogArray.select {|event| event.event_id == 529} events.each do |event| event_time = event.time_written.to_s eventsbydate = event_time.gsub(/\s/, '')[0..7] + event_time[26..30] counts[eventsbydate] += 1 end counts.each do |id,cnt| # Now I have a problem here: what we are putting in the hash is a string, not an event object # @alerts.push("#{event.event_id} #{@tab} #{event.time_written} #{@tab} #{event.event_type} #{@tab} #{type}") if cnt >= 5 @alerts.push(id) if cnt >= 5 end end I hope this helps. I don't have time now to solve the issue about you wanting to push the event object to the alerts array, instead of just the calculated string, but I hope you find a way to do that easily. Let me know if this helped. Jesus.