1
\$\begingroup\$

I have this log file (example below) and I'm trying to find the number of times a particular route is called.

Example log file:

2019-05-29 11:00:00 192.168.1.1 POST /route1 200  100000

2019-05-29 11:00:01 10.1.1.2 POST /route1 200  100000

2019-05-29 11:00:01 192.168.1.2 GET /route2 404 200000

2019-05-29 11:00:02 192.168.1.3 GET /route3 200  100000

2019-05-29 11:00:03 10.1.1.3 GET /route4 200  200000

2019-05-29 11:00:04 192.168.1.1 POST /route1 200 100000

Here is the code I've written:

route_count = Hash.new(0)
File.open('test.log').each do |line|
  temp_array = line.split(" ")
  route = temp_array[4]
  if route_count.has_key?(route)
    route_count[route] = route_count[route] + 1
  else
    route_count[route] = 1
  end
end
puts( route_count.map{ |k,v| "#{k},#{v}" })

and it gives the output:

/route1,3

/route2,1

/route3,1

/route4,1

I wanted to know if there is a better way to do this.

\$\endgroup\$
4
\$\begingroup\$

The Enumerable.group_by method is perfect for situations like this. The method takes the items in the enumerable, evaluates a block on them to yield a key, and inserts them into a hash under that key. Using this the code is very short:

puts(File.open('test.log').entries
    .group_by { |line| line.split(" ")[4] }
    .map { |k, v| "#{k},#{v.count}" })
\$\endgroup\$
  • \$\begingroup\$ Thank you!! A much shorter and cleaner way. \$\endgroup\$ – user2253109 Jun 2 at 4:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.