apache_log_report 1.1.8 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -4
- data/README.org +2 -111
- data/Rakefile +13 -0
- data/apache_log_report.gemspec +12 -0
- data/exe/apache_log_report +1 -0
- data/lib/apache_log_report/data_cruncher.rb +13 -6
- data/lib/apache_log_report/ip_locator.rb +42 -0
- data/lib/apache_log_report/templates/template.html.erb +28 -1
- data/lib/apache_log_report/version.rb +1 -1
- data/lib/apache_log_report.rb +1 -0
- metadata +50 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffde49bcae6f56e31b5ef7cccd88d5391127ee330264c188132f9ccbec94f421
|
4
|
+
data.tar.gz: 04c799c68ab676b176314b7ebe68cd3514faa48f853b9793e76d505d71342ae9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b5010ca3fa37d6dceb8ab48d0fc5f256713db19f63366602f7200219c9ec51656160e2e50901709179fac67633f5703eb137432c5cd289bc080f14dc675aebf
|
7
|
+
data.tar.gz: 377a4a516fe144f6167c83850c0037cb9d0c216090ad197b2ca22b94d6ab156d1c696ceb31ab5c0be6f06227e7ef62dfd8a23667b26a9919e56eff431c9c977c
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
apache_log_report (1.1.
|
4
|
+
apache_log_report (1.1.8)
|
5
5
|
apache_log-parser
|
6
6
|
browser
|
7
|
+
ipaddr
|
7
8
|
sqlite3
|
8
9
|
terminal-table
|
9
10
|
|
@@ -12,11 +13,12 @@ GEM
|
|
12
13
|
specs:
|
13
14
|
apache_log-parser (3.1.2)
|
14
15
|
browser (5.3.1)
|
16
|
+
ipaddr (1.2.3)
|
15
17
|
rake (12.3.3)
|
16
18
|
sqlite3 (1.4.2)
|
17
|
-
terminal-table (
|
18
|
-
unicode-display_width (
|
19
|
-
unicode-display_width (1.
|
19
|
+
terminal-table (3.0.2)
|
20
|
+
unicode-display_width (>= 1.1.1, < 3)
|
21
|
+
unicode-display_width (2.1.0)
|
20
22
|
|
21
23
|
PLATFORMS
|
22
24
|
ruby
|
data/README.org
CHANGED
@@ -2,115 +2,6 @@
|
|
2
2
|
#+AUTHOR: Adolfo Villafiorita
|
3
3
|
#+STARTUP: showall
|
4
4
|
|
5
|
-
|
5
|
+
This Gem has been superseded by [[https://rubygems.org/gems/log_sense][Log Sense]], which produces better
|
6
|
+
outputs and parses also rails logs.
|
6
7
|
|
7
|
-
ApacheLogReport generates reports and statistics from Apache web logs
|
8
|
-
in the =combined= format. Written in Ruby, it runs from the command
|
9
|
-
line, it is fast, and it can be installed on any system which supports
|
10
|
-
Ruby.
|
11
|
-
|
12
|
-
ApacheLogReport moves along the lines of tools such as [[https://goaccess.io/][GoAccess]]
|
13
|
-
and [[https://umami.is/][Umami]], focusing on privacy and data-ownership: the data
|
14
|
-
generated by ApacheLogReport is stored on your computer and owned by
|
15
|
-
you (like it should be).
|
16
|
-
|
17
|
-
ApacheLogReport is also inspired by static websites generators:
|
18
|
-
statistics are generated from the command line and accessed as static
|
19
|
-
HTML files. By generating static resources, ApacheLogReport
|
20
|
-
significantly reduces the attack surface of your webserver and
|
21
|
-
installation headaches.
|
22
|
-
|
23
|
-
We have, for instance, a cron job running on our servers, generating
|
24
|
-
statistics at night. The generated files are then made available on a
|
25
|
-
private area on the web.
|
26
|
-
|
27
|
-
Statistics are generated from Apache log formats in the =combined=
|
28
|
-
format. Reports are tailored, but not limited, to web servers serving
|
29
|
-
static websites. No need to install Java Script code on your
|
30
|
-
websites, no cookies installed, no user tracking.
|
31
|
-
|
32
|
-
ApacheLogReport reports the following data:
|
33
|
-
|
34
|
-
- Visitors, hits, unique visitors, bandwidth used
|
35
|
-
- Most accessed HTML pages
|
36
|
-
- Most accessed resources
|
37
|
-
- Response statuses
|
38
|
-
- referers
|
39
|
-
- OS, browsers, and devices
|
40
|
-
- Streaks: resources accessed by a given IP over time
|
41
|
-
- Potential attacks: access to resources which are not meant to be
|
42
|
-
served by a web server serving static websites
|
43
|
-
|
44
|
-
Filters from the command line allow to analyze specific periods and
|
45
|
-
distinguish traffic generated by self polls and crawlers.
|
46
|
-
|
47
|
-
ApacheLogReport generates HTML and SQLite outputs. Moreover, it can
|
48
|
-
also generate reports in Org Mode format, which can be then processed
|
49
|
-
to various formats (including LaTeX and HTML).
|
50
|
-
|
51
|
-
* Installation
|
52
|
-
|
53
|
-
#+begin_src bash
|
54
|
-
gem install apache_log_report
|
55
|
-
#+end_src
|
56
|
-
|
57
|
-
* Usage
|
58
|
-
|
59
|
-
#+begin_src bash :results raw output :wrap example
|
60
|
-
apache_log_report --help
|
61
|
-
#+end_src
|
62
|
-
|
63
|
-
#+RESULTS:
|
64
|
-
#+begin_example
|
65
|
-
Usage: apache_log_report [options] [logfile]
|
66
|
-
-l, --limit=N Number of entries to show (defaults to 30)
|
67
|
-
-b, --begin=DATE Consider entries after or on DATE
|
68
|
-
-e, --end=DATE Consider entries before or on DATE
|
69
|
-
-i, --ignore-crawlers Ignore crawlers
|
70
|
-
-p, --ignore-selfpoll Ignore apaches self poll entries (from ::1)
|
71
|
-
--only-crawlers Perform analysis on crawlers only
|
72
|
-
-u, --prefix=PREFIX Prefix to add to all plots (used to run multiple analyses in the same dir)
|
73
|
-
-w, --suffix=SUFFIX Suffix to add to all plots (used to run multiple analyses in the same dir)
|
74
|
-
-c, --code-export=WHAT Control :export directive in Org Mode code blocks (code, results, *both*, none)
|
75
|
-
-f, --format=FORMAT Output format: html, org, sqlite. Defaults to org mode
|
76
|
-
-v, --version Prints version information
|
77
|
-
-h, --help Prints this help
|
78
|
-
This is version 1.1.6
|
79
|
-
#+end_example
|
80
|
-
|
81
|
-
* Change Log
|
82
|
-
|
83
|
-
See the [[file:CHANGELOG.org][CHANGELOG]] file.
|
84
|
-
|
85
|
-
* Todo
|
86
|
-
|
87
|
-
** TODO Referers should only include the hostname?
|
88
|
-
** TODO Graphs in HTML output
|
89
|
-
** TODO Countries/IP Lookup
|
90
|
-
** TODO Light and Dark Theme
|
91
|
-
** TODO Embed CSS
|
92
|
-
** TODO Declare datatypes in table outputs, so that we can format data
|
93
|
-
|
94
|
-
* Compatibility
|
95
|
-
|
96
|
-
ApacheLogReport should run on any system on which Ruby runs.
|
97
|
-
|
98
|
-
Concerning the outputs:
|
99
|
-
|
100
|
-
- The HTML report uses [[https://picturepan2.github.io/spectre/][Spectre.css]] and (will use) [[https://vega.github.io/vega-lite/][Vega Light]], which
|
101
|
-
are downloaded from a CDN
|
102
|
-
- Org Mode plots data using [[http://gnuplot.info/][Gnuplot]]
|
103
|
-
|
104
|
-
* Author and Contributors
|
105
|
-
|
106
|
-
[[http://ict4g.net/adolfo][Adolfo Villafiorita]].
|
107
|
-
|
108
|
-
* Known Bugs
|
109
|
-
|
110
|
-
Some known bugs and an unknown number of unknown bugs.
|
111
|
-
|
112
|
-
(See the open issues for the known bugs.)
|
113
|
-
|
114
|
-
* License
|
115
|
-
|
116
|
-
Distributed under the terms of the [[http://opensource.org/licenses/MIT][MIT License]].
|
data/Rakefile
CHANGED
@@ -1,2 +1,15 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
task :default => :spec
|
3
|
+
|
4
|
+
require 'rake/testtask'
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs << 'test'
|
7
|
+
end
|
8
|
+
|
9
|
+
require_relative './lib/apache_log_report/ip_locator.rb'
|
10
|
+
|
11
|
+
desc "Convert Geolocation DB to sqlite"
|
12
|
+
task :dbip_to_sqlite3, [:filename] do |tasks, args|
|
13
|
+
filename = args[:filename]
|
14
|
+
ApacheLogReport::IpLocator::dbip_to_sqlite filename
|
15
|
+
end
|
data/apache_log_report.gemspec
CHANGED
@@ -29,6 +29,18 @@ Gem::Specification.new do |spec|
|
|
29
29
|
|
30
30
|
spec.add_dependency "apache_log-parser"
|
31
31
|
spec.add_dependency "browser"
|
32
|
+
spec.add_dependency "ipaddr"
|
33
|
+
spec.add_dependency "iso_country_codes"
|
32
34
|
spec.add_dependency "sqlite3"
|
33
35
|
spec.add_dependency "terminal-table"
|
36
|
+
|
37
|
+
spec.add_development_dependency "minitest"
|
38
|
+
|
39
|
+
spec.post_install_message = <<-MESSAGE
|
40
|
+
! The 'apache_log_report' gem has been deprecated and has been replaced 'log_sense'.
|
41
|
+
! See: https://rubygems.org/gems/log_sense
|
42
|
+
! And: https://www.ict4g.net/gitea/adolfo/log_sense
|
43
|
+
MESSAGE
|
44
|
+
|
45
|
+
|
34
46
|
end
|
data/exe/apache_log_report
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
|
2
1
|
module ApacheLogReport
|
3
2
|
module DataCruncher
|
4
|
-
|
5
3
|
#
|
6
4
|
# take a sqlite3 database and analyze data
|
7
5
|
#
|
@@ -103,12 +101,13 @@ module ApacheLogReport
|
|
103
101
|
|
104
102
|
@browsers = db.execute "SELECT browser, count(browser), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by browser order by count(browser) desc"
|
105
103
|
@platforms = db.execute "SELECT platform, count(platform), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by platform order by count(platform) desc"
|
106
|
-
@ips = db.execute "SELECT ip, count(ip), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by ip order by count(ip) desc limit #{options[:limit]}"
|
107
104
|
@referers = db.execute "SELECT referer, count(referer), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by referer order by count(referer) desc limit #{options[:limit]}"
|
108
105
|
|
109
|
-
@
|
106
|
+
@ips = db.execute "SELECT ip, count(ip), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by ip order by count(ip) desc limit #{options[:limit]}"
|
110
107
|
|
108
|
+
@streaks = db.execute "SELECT ip, substr(datetime, 1, 10), path from LogLine order by ip, datetime"
|
111
109
|
data = {}
|
110
|
+
|
112
111
|
self.instance_variables.each do |variable|
|
113
112
|
var_as_symbol = variable.to_s[1..-1].to_sym
|
114
113
|
data[var_as_symbol] = eval(variable.to_s)
|
@@ -116,6 +115,16 @@ module ApacheLogReport
|
|
116
115
|
data
|
117
116
|
end
|
118
117
|
|
118
|
+
# add country code to data[:ips]
|
119
|
+
def self.geolocate data
|
120
|
+
@location_db = IpLocator::load_db
|
121
|
+
data[:ips].each do |ip|
|
122
|
+
country_code = IpLocator::locate_ip ip[0], @location_db
|
123
|
+
ip << country_code
|
124
|
+
end
|
125
|
+
data
|
126
|
+
end
|
127
|
+
|
119
128
|
private
|
120
129
|
|
121
130
|
def self.date_intersect date1, date2, method
|
@@ -127,8 +136,6 @@ module ApacheLogReport
|
|
127
136
|
date2
|
128
137
|
end
|
129
138
|
end
|
130
|
-
|
131
|
-
|
132
139
|
end
|
133
140
|
end
|
134
141
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'sqlite3'
|
3
|
+
require 'ipaddr'
|
4
|
+
require 'iso_country_codes'
|
5
|
+
|
6
|
+
module ApacheLogReport
|
7
|
+
module IpLocator
|
8
|
+
DB_FILE = "ip_locations/dbip-country-lite.sqlite3"
|
9
|
+
|
10
|
+
def self.dbip_to_sqlite db_location
|
11
|
+
db = SQLite3::Database.new ":memory:"
|
12
|
+
db.execute "CREATE TABLE ip_location (
|
13
|
+
from_ip_n INTEGER,
|
14
|
+
from_ip TEXT,
|
15
|
+
to_ip TEXT,
|
16
|
+
country_code TEXT
|
17
|
+
)"
|
18
|
+
|
19
|
+
ins = db.prepare "INSERT INTO ip_location(from_ip_n, from_ip, to_ip, country_code) values (?, ?, ?, ?)"
|
20
|
+
CSV.foreach(db_location) do |row|
|
21
|
+
ip = IPAddr.new row[0]
|
22
|
+
ins.execute(ip.to_i, row[0], row[1], row[2])
|
23
|
+
end
|
24
|
+
|
25
|
+
# persist to file
|
26
|
+
ddb = SQLite3::Database.new(DB_FILE)
|
27
|
+
b = SQLite3::Backup.new(ddb, 'main', db, 'main')
|
28
|
+
b.step(-1) #=> DONE
|
29
|
+
b.finish
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.load_db
|
33
|
+
SQLite3::Database.new DB_FILE
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.locate_ip ip, db
|
37
|
+
ip_n = IPAddr.new(ip).to_i
|
38
|
+
res = db.execute "SELECT * FROM ip_location where from_ip_n <= #{ip_n} order by from_ip_n desc limit 1"
|
39
|
+
IsoCountryCodes.find(res[0][3]).name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -32,6 +32,8 @@
|
|
32
32
|
"Platforms",
|
33
33
|
"Referers",
|
34
34
|
"IPs",
|
35
|
+
"Geolocation",
|
36
|
+
"Streaks",
|
35
37
|
"Command Invocation",
|
36
38
|
"Performance"
|
37
39
|
].each do |item| %>
|
@@ -142,7 +144,7 @@
|
|
142
144
|
{ title: "Browsers", header: ["Browser", "Hits", "Visitors", "Size"], rows: data[:browsers] },
|
143
145
|
{ title: "Platforms", header: ["Platform", "Hits", "Visitors", "Size"], rows: data[:platforms] },
|
144
146
|
{ title: "Referers", header: ["Referers", "Hits", "Visitors", "Size"], rows: data[:referers], col: "col-12" },
|
145
|
-
{ title: "IPs", header: ["IPs", "Hits", "Visitors", "Size"], rows: data[:ips] },
|
147
|
+
{ title: "IPs", header: ["IPs", "Hits", "Visitors", "Size", "Country"], rows: data[:ips] },
|
146
148
|
{ },
|
147
149
|
]
|
148
150
|
%>
|
@@ -161,6 +163,31 @@
|
|
161
163
|
<% end %>
|
162
164
|
</div>
|
163
165
|
|
166
|
+
<article>
|
167
|
+
<h2 id="geolocation">Geolocation</h2>
|
168
|
+
<table class="table">
|
169
|
+
<thead>
|
170
|
+
<tr>
|
171
|
+
<th>Country Code</th>
|
172
|
+
<th>Total Hits</th>
|
173
|
+
<th>Total Visitors</th>
|
174
|
+
<th>IPs</th>
|
175
|
+
</tr>
|
176
|
+
</thead>
|
177
|
+
<tbody>
|
178
|
+
<%# IP, Hits, Visitors Size, Country%>
|
179
|
+
<% data[:ips].group_by { |x| x[4] }.each do |k, v| %>
|
180
|
+
<tr>
|
181
|
+
<td><%= k %></td>
|
182
|
+
<td><%= v.map { |x| x[1] }.inject(&:+) %></td>
|
183
|
+
<td><%= v.map { |x| x[2] }.inject(&:+) %></td>
|
184
|
+
<td><%= v.map { |x| x[0] }.join(", ") %></td>
|
185
|
+
</tr>
|
186
|
+
<% end %>
|
187
|
+
</tbody>
|
188
|
+
</table>
|
189
|
+
</article>
|
190
|
+
|
164
191
|
<article>
|
165
192
|
<h2 id="streaks">Streaks</h2>
|
166
193
|
|
data/lib/apache_log_report.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apache_log_report
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adolfo Villafiorita
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: apache_log-parser
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ipaddr
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: iso_country_codes
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: sqlite3
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +94,20 @@ dependencies:
|
|
66
94
|
- - ">="
|
67
95
|
- !ruby/object:Gem::Version
|
68
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: minitest
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
description: Generate requests reports in HTML, OrgMode, and SQLite format from an
|
70
112
|
Apache log file.
|
71
113
|
email:
|
@@ -90,6 +132,7 @@ files:
|
|
90
132
|
- lib/apache_log_report/apache_log_report.rb
|
91
133
|
- lib/apache_log_report/data_cruncher.rb
|
92
134
|
- lib/apache_log_report/emitter.rb
|
135
|
+
- lib/apache_log_report/ip_locator.rb
|
93
136
|
- lib/apache_log_report/log_parser.rb
|
94
137
|
- lib/apache_log_report/options_parser.rb
|
95
138
|
- lib/apache_log_report/templates/_output_table.html.erb
|
@@ -104,7 +147,10 @@ metadata:
|
|
104
147
|
homepage_uri: https://www.ict4g.net/gitea/adolfo/apache_log_report
|
105
148
|
source_code_uri: https://www.ict4g.net/gitea/adolfo/apache_log_report
|
106
149
|
changelog_uri: https://www.ict4g.net/gitea/adolfo/apache_log_report/CHANGELOG.org
|
107
|
-
post_install_message:
|
150
|
+
post_install_message: |2
|
151
|
+
! The 'apache_log_report' gem has been deprecated and has been replaced 'log_sense'.
|
152
|
+
! See: https://rubygems.org/gems/log_sense
|
153
|
+
! And: https://www.ict4g.net/gitea/adolfo/log_sense
|
108
154
|
rdoc_options: []
|
109
155
|
require_paths:
|
110
156
|
- lib
|
@@ -119,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
165
|
- !ruby/object:Gem::Version
|
120
166
|
version: '0'
|
121
167
|
requirements: []
|
122
|
-
rubygems_version: 3.0.3
|
168
|
+
rubygems_version: 3.0.3.1
|
123
169
|
signing_key:
|
124
170
|
specification_version: 4
|
125
171
|
summary: Generate analytics from an Apache log file.
|