1#!/usr/bin/ruby
2# Copyright 2010 Thomas Stromberg - All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16#
17#
18# lasthit, part of iExploder
19# 
20# Shows statistics about recent agents that have tested with iExploder. 
21# It takes all or part of an apache logfile via stdin, and outputs a list
22# of all the agents who tested within that section, what their last test
23# was, and how many tests they have done.
24
25# The usefulness is finding out where a browser crashed.
26
27require 'cgi'
28
29hostHash = Hash.new
30
31if (ARGV[0])
32	file = File.open(ARGV[0])
33else
34  puts "No filename specified, waiting for data via stdin..."
35	file = $stdin
36end
37
38last_index = nil
39file.readlines.each_with_index { |line, index|
40  # filter out mime hits as they produce a lot of odd user agents
41  next if line =~ /&m=/
42	if (line =~ /([\w\.]+) - - .*iexploder.cgi\?(.*?)&b=([\w\%-\.+]+)/)
43		host = $1
44		test_url = $2
45		agent = $3
46		if (! hostHash[host])
47			hostHash[host] = Hash.new
48		end
49		if (! hostHash[host][agent])
50			hostHash[host][agent] = Hash.new
51			hostHash[host][agent]['total'] = 0
52		end
53		hostHash[host][agent]['last'] = test_url
54		hostHash[host][agent]['total'] = hostHash[host][agent]['total'] + 1
55		hostHash[host][agent]['last_line'] = index
56	end
57  last_index = index
58}
59
60printf("%-14.14s | %-25.25s | %6.6s | %7.7s | %s\n",
61	 "Host", "Test URL", "Total", "LineAgo", "Agent")
62puts "-" * 78
63hostHash.each_key { |host|
64	hostHash[host].each_key { |agent|
65    next if agent.length < 8
66    display_agent = CGI::unescape(agent).sub('U; ', '')
67		printf("%-14.14s | %-25.25s | %6.6s | %7.7s | %s\n",
68			host, hostHash[host][agent]['last'],
69      hostHash[host][agent]['total'],
70      hostHash[host][agent]['last_line'] - last_index,
71      display_agent);
72	}
73}
74
75