3 require "apache_log_regex"
7 def categorise_uri(line)
8 uri = line.split(" ")[1]
11 when %r{api/0\.6/map} then :map
12 when %r{api/0\.6/changeset/[0-9]*/upload} then :upload
13 when %r{api/0\.6/amf} then :amf
14 when %r{api/0\.6/(node|way|relation)/[0-9]*/history} then :history
15 when %r{api/0\.6/(node|way|relation)/[0-9]*/full} then :full
16 when %r{api/0\.6/trackpoints} then :trkpts
17 when %r{api/0\.6/} then :other
22 parser = ApacheLogRegex.new('%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %Dus %{UNIQUE_ID}e %{SSL_PROTOCOL}x %{SSL_CIPHER}x %{AUTH_METHOD}e')
26 :status => Hash.new(0),
28 :count => Hash.new(0),
29 :bytes => Hash.new(0),
30 :seconds => Hash.new(0.0),
35 File::Tail::Logfile.tail("/var/log/apache2/access.log") do |line|
37 hash = parser.parse(line)
39 uri = categorise_uri(hash["%r"])
41 bytes = hash["%O"].to_i
42 seconds = hash["%Dus"].to_f / 1000000
43 protocol = hash["%{SSL_PROTOCOL}x"]
44 cipher = hash["%{SSL_CIPHER}x"]
45 auth = hash["%{AUTH_METHOD}e"]
47 statistics[:status][status] += 1
48 statistics[:uri][uri] += 1
49 statistics[:count][[uri, status]] += 1
50 statistics[:bytes][[uri, status]] += bytes
51 statistics[:seconds][[uri, status]] += seconds
52 statistics[:ssl][[protocol, cipher]] += 1 unless protocol == "-"
53 statistics[:auth][auth] += 1 unless auth == "-"
54 rescue ApacheLogRegex::ParseError
58 if Time.now - last_write > 10
59 File.write("/srv/www.openstreetmap.org/rails/tmp/statistics.json", statistics.slice(:status, :uri).to_json)
61 File.open("/var/lib/prometheus/node-exporter/api.tmp", "w") do |file|
62 file.puts "# HELP api_call_count_total Number of calls by type and status"
63 file.puts "# TYPE api_call_count_total counter"
65 statistics[:count].each do |key, value|
68 file.puts "api_call_count_total{uri=\"#{uri}\",status=\"#{status}\"} #{value}"
71 file.puts "# HELP api_call_bytes_total Number of bytes returned by type and status"
72 file.puts "# TYPE api_call_bytes_total counter"
74 statistics[:bytes].each do |key, value|
77 file.puts "api_call_bytes_total{uri=\"#{uri}\",status=\"#{status}\"} #{value}"
80 file.puts "# HELP api_call_seconds_total Number of seconds returned by type and status"
81 file.puts "# TYPE api_call_seconds_total counter"
83 statistics[:seconds].each do |key, value|
86 file.puts "api_call_seconds_total{uri=\"#{uri}\",status=\"#{status}\"} #{value}"
89 file.puts "# HELP api_call_ssl_total Number of calls by SSL protocol and cipher"
90 file.puts "# TYPE api_call_ssl_total counter"
92 statistics[:ssl].each do |key, value|
93 protocol, cipher = key
95 file.puts "api_call_ssl_total{protocol=\"#{protocol}\",cipher=\"#{cipher}\"} #{value}"
98 file.puts "# HELP api_call_auth_method_total Number of calls by authentication method"
99 file.puts "# TYPE api_call_auth_method_total counter"
101 statistics[:auth].each do |method, value|
102 file.puts "api_call_auth_method_total{method=\"#{method}\"} #{value}"
106 File.rename("/var/lib/prometheus/node-exporter/api.tmp", "/var/lib/prometheus/node-exporter/api.prom")
108 last_write = Time.now