apache_log_report 1.1.2 → 1.1.6
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/README.org +6 -0
- data/apache_log_report.gemspec +2 -2
- data/lib/apache_log_report/data_cruncher.rb +53 -5
- data/lib/apache_log_report/options_parser.rb +2 -2
- data/lib/apache_log_report/templates/_output_table.html.erb +1 -1
- data/lib/apache_log_report/templates/template.html.erb +259 -182
- data/lib/apache_log_report/templates/template.org.erb +5 -1
- data/lib/apache_log_report/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 742584032338664834cd5c1b669289980e083e68d172827f6517ce040543aa4d
|
4
|
+
data.tar.gz: 1bf08e255feb434ded62589d5c70ea5a6eb83dc1f6a69e60a31cb520eea6b48f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 955dbe90321c68f5694aaa892cae97926172ca47b684a0eee1b9f7644dc26a13f853b3b3d20e35cf06872b29db0c06bc16c4c86e69c740ea86fe8768ae92b2a1
|
7
|
+
data.tar.gz: e6d9ebc88435442bfb77faa3cb2eccb94a355e9ca7af44548a7b443531c9fae923e41f5d97201044f71414f2d9894162b593cd15170e255030ab49bd9992e3f0
|
data/README.org
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
|
5
5
|
* Introduction
|
6
6
|
|
7
|
+
ApacheLogReport is an Apache log analyzer.
|
8
|
+
|
7
9
|
* Installation
|
8
10
|
|
9
11
|
* Usage
|
@@ -14,8 +16,12 @@ See the [[file:CHANGELOG.org][CHANGELOG]] file.
|
|
14
16
|
|
15
17
|
* Todo
|
16
18
|
|
19
|
+
** TODO Referers should only include the hostname?
|
17
20
|
** TODO Graphs in HTML output
|
18
21
|
** TODO Countries
|
22
|
+
** TODO Light and Dark Theme
|
23
|
+
** TODO Embed CSS
|
24
|
+
** TODO Declare datatypes in table outputs, so that we can format data
|
19
25
|
|
20
26
|
* Compatibility
|
21
27
|
|
data/apache_log_report.gemspec
CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new do |spec|
|
|
6
6
|
spec.authors = ["Adolfo Villafiorita"]
|
7
7
|
spec.email = ["adolfo.villafiorita@ict4g.net"]
|
8
8
|
|
9
|
-
spec.summary = %q{Generate
|
10
|
-
spec.description = %q{Generate
|
9
|
+
spec.summary = %q{Generate analytics from an Apache log file.}
|
10
|
+
spec.description = %q{Generate requests reports in HTML, OrgMode, and SQLite format from an Apache log file.}
|
11
11
|
spec.homepage = "https://www.ict4g.net/gitea/adolfo/apache_log_report"
|
12
12
|
spec.license = "MIT"
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
@@ -1,17 +1,41 @@
|
|
1
|
+
|
1
2
|
module ApacheLogReport
|
2
3
|
module DataCruncher
|
3
4
|
|
4
5
|
#
|
5
6
|
# take a sqlite3 database and analyze data
|
6
7
|
#
|
8
|
+
# @ variables are automatically put in the returned data
|
9
|
+
#
|
7
10
|
|
8
11
|
def self.crunch db, options = {}
|
9
|
-
|
10
|
-
|
12
|
+
first_day_s = db.execute "SELECT datetime from LogLine order by datetime limit 1"
|
13
|
+
last_day_s = db.execute "SELECT datetime from LogLine order by datetime desc limit 1"
|
14
|
+
|
15
|
+
# make first and last day into dates or nil
|
16
|
+
@first_day = first_day_s.empty? ? nil : Date.parse(first_day_s[0][0])
|
17
|
+
@last_day = last_day_s.empty? ? nil : Date.parse(last_day_s[0][0])
|
18
|
+
|
19
|
+
@total_days = 0
|
20
|
+
if @first_day and @last_day
|
21
|
+
@total_days = (@last_day - @first_day).to_i
|
22
|
+
end
|
23
|
+
|
11
24
|
@log_size = db.execute "SELECT count(datetime) from LogLine"
|
12
25
|
@crawlers_size = db.execute "SELECT count(datetime) from LogLine where bot == 1"
|
13
26
|
@selfpolls_size = db.execute "SELECT count(datetime) from LogLine where ip == '::1'"
|
14
27
|
|
28
|
+
@first_day_requested = options[:from_date]
|
29
|
+
@last_day_requested = options[:to_date]
|
30
|
+
|
31
|
+
@first_day_in_analysis = date_intersect options[:from_date], @first_day, :max
|
32
|
+
@last_day_in_analysis = date_intersect options[:to_date], @last_day, :min
|
33
|
+
|
34
|
+
@total_days_in_analysis = 0
|
35
|
+
if @first_day_in_analysis and @last_day_in_analysis
|
36
|
+
@total_days_in_analysis = (@last_day_in_analysis - @first_day_in_analysis).to_i
|
37
|
+
end
|
38
|
+
|
15
39
|
#
|
16
40
|
# generate the where clause corresponding to the command line options to filter data
|
17
41
|
#
|
@@ -39,12 +63,23 @@ module ApacheLogReport
|
|
39
63
|
END AS size
|
40
64
|
EOS
|
41
65
|
|
66
|
+
human_readable_day = <<-EOS
|
67
|
+
case cast (strftime('%w', datetime) as integer)
|
68
|
+
when 0 then 'Sunday'
|
69
|
+
when 1 then 'Monday'
|
70
|
+
when 2 then 'Tuesday'
|
71
|
+
when 3 then 'Wednesday'
|
72
|
+
when 4 then 'Thursday'
|
73
|
+
when 5 then 'Friday'
|
74
|
+
else 'Saturday'
|
75
|
+
end as dow
|
76
|
+
EOS
|
77
|
+
|
42
78
|
@total_hits = db.execute "SELECT count(datetime) from LogLine where #{filter}"
|
43
79
|
@total_unique_visitors = db.execute "SELECT count(distinct(unique_visitor)) from LogLine where #{filter}"
|
44
80
|
@total_size = db.execute "SELECT #{human_readable_size} from LogLine where #{filter}"
|
45
|
-
@total_days = (Date.parse(@last_day[0][0]) - Date.parse(@first_day[0][0])).to_i
|
46
81
|
|
47
|
-
@daily_distribution = db.execute "SELECT date(datetime), count(datetime), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by date(datetime)"
|
82
|
+
@daily_distribution = db.execute "SELECT date(datetime), #{human_readable_day}, count(datetime), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by date(datetime)"
|
48
83
|
@time_distribution = db.execute "SELECT strftime('%H', datetime), count(datetime), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by strftime('%H', datetime)"
|
49
84
|
@most_requested_pages = db.execute "SELECT path, count(path), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where extension == '.html' and #{filter} group by path order by count(path) desc limit #{options[:limit]}"
|
50
85
|
@most_requested_resources = db.execute "SELECT path, count(path), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by path order by count(path) desc limit #{options[:limit]}"
|
@@ -80,7 +115,20 @@ module ApacheLogReport
|
|
80
115
|
end
|
81
116
|
data
|
82
117
|
end
|
83
|
-
end
|
84
118
|
|
119
|
+
private
|
120
|
+
|
121
|
+
def self.date_intersect date1, date2, method
|
122
|
+
if date1 and date2
|
123
|
+
[date1, date2].send(method)
|
124
|
+
elsif date1
|
125
|
+
date1
|
126
|
+
else
|
127
|
+
date2
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
end
|
85
133
|
end
|
86
134
|
|
@@ -18,11 +18,11 @@ module ApacheLogReport
|
|
18
18
|
args[:limit] = n
|
19
19
|
end
|
20
20
|
|
21
|
-
opts.on("-bDATE", "--begin=DATE",
|
21
|
+
opts.on("-bDATE", "--begin=DATE", Date, "Consider entries after or on DATE") do |n|
|
22
22
|
args[:from_date] = n
|
23
23
|
end
|
24
24
|
|
25
|
-
opts.on("-eDATE", "--end=DATE",
|
25
|
+
opts.on("-eDATE", "--end=DATE", Date, "Consider entries before or on DATE") do |n|
|
26
26
|
args[:to_date] = n
|
27
27
|
end
|
28
28
|
|
@@ -4,194 +4,271 @@
|
|
4
4
|
<meta name="author" content="apache_log_report">
|
5
5
|
|
6
6
|
<link rel="stylesheet" href="alr-styles.css"></style>
|
7
|
+
|
8
|
+
<link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre.min.css">
|
9
|
+
<link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre-exp.min.css">
|
10
|
+
<link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre-icons.min.css">
|
7
11
|
</head>
|
8
12
|
|
9
13
|
<body>
|
10
|
-
<
|
11
|
-
<
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
%>
|
60
|
-
<% @reports.each do |report| %>
|
61
|
-
<article>
|
62
|
-
<h2><%= report[:title] %></h2>
|
63
|
-
<%= render "output_table", report %>
|
64
|
-
</article>
|
65
|
-
<% end %>
|
66
|
-
|
67
|
-
<article>
|
68
|
-
<h2>Streaks</h2>
|
69
|
-
|
70
|
-
<table class="streaks">
|
71
|
-
<thead>
|
72
|
-
<tr>
|
73
|
-
<th>IP</th>
|
74
|
-
<th>Day</th>
|
75
|
-
<th>URL</th>
|
76
|
-
</tr>
|
77
|
-
</thead>
|
78
|
-
<tbody>
|
79
|
-
<% data[:streaks].group_by(&:first).each do |ip, date_urls| %>
|
14
|
+
<div class="container">
|
15
|
+
<nav>
|
16
|
+
<ul class="nav">
|
17
|
+
<li class="nav-item active">
|
18
|
+
<a href="#">Navigation</a>
|
19
|
+
<ul class="nav">
|
20
|
+
<% [ "Summary",
|
21
|
+
"Log Structure",
|
22
|
+
"Daily Distribution",
|
23
|
+
"Time Distribution",
|
24
|
+
"Most Requested Pages",
|
25
|
+
"Most Requested Resources",
|
26
|
+
"404 on HTML Files",
|
27
|
+
"404 on other Resources",
|
28
|
+
"Attacks",
|
29
|
+
"Statuses",
|
30
|
+
"Daily Statuses",
|
31
|
+
"Browsers",
|
32
|
+
"Platforms",
|
33
|
+
"Referers",
|
34
|
+
"IPs",
|
35
|
+
"Command Invocation",
|
36
|
+
"Performance"
|
37
|
+
].each do |item| %>
|
38
|
+
<li class="nav-item">
|
39
|
+
<a href="#<%= item.downcase.gsub(' ', '-') %>"><%= item %></a>
|
40
|
+
</li>
|
41
|
+
<% end %>
|
42
|
+
</ul>
|
43
|
+
</li>
|
44
|
+
</ul>
|
45
|
+
<p>
|
46
|
+
Generated by<br />
|
47
|
+
<a href="https://www.ict4g.net/gitea/adolfo/apache_log_report">
|
48
|
+
Apache Log Report
|
49
|
+
</a> <br />
|
50
|
+
on <%= DateTime.now.strftime("%Y-%m-%d %H:%M") %>.<br />
|
51
|
+
The lean log analyzer.
|
52
|
+
</p>
|
53
|
+
</nav>
|
54
|
+
|
55
|
+
<section>
|
56
|
+
<h1>Apache Log Analysis: <%= data[:log_file] || "stdin" %></h1>
|
57
|
+
|
58
|
+
<div class="columns">
|
59
|
+
<article class="col-6 column">
|
60
|
+
<h2 id="summary">Summary</h2>
|
61
|
+
|
62
|
+
<table class="table summary">
|
80
63
|
<tr>
|
81
|
-
<
|
82
|
-
<td
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
64
|
+
<th>Input file</th>
|
65
|
+
<td><b><%= (data[:log_file] || "stdin") %></b></td>
|
66
|
+
</tr>
|
67
|
+
<tr>
|
68
|
+
<th class="period">Period Analyzed</th>
|
69
|
+
<td class="period">
|
70
|
+
<%= data[:first_day_in_analysis] %>
|
71
|
+
--
|
72
|
+
<%= data[:last_day_in_analysis] %>
|
88
73
|
</td>
|
89
74
|
</tr>
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
<
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
<
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
</
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
75
|
+
<tr>
|
76
|
+
<th class="days">Days </th>
|
77
|
+
<td class="days"><%= data[:total_days_in_analysis] %></td>
|
78
|
+
</tr>
|
79
|
+
<tr>
|
80
|
+
<th class="hits">Hits</th>
|
81
|
+
<td class="hits"><%= data[:total_hits][0][0] %></td>
|
82
|
+
</tr>
|
83
|
+
<tr>
|
84
|
+
<th class="unique-visitors">Unique Visitors</th>
|
85
|
+
<td class="unique-visitors"><%= data[:total_unique_visitors][0][0] %></td>
|
86
|
+
</tr>
|
87
|
+
<tr>
|
88
|
+
<th class="tx">Tx</th>
|
89
|
+
<td class="tx"><%= data[:total_size][0][0] %></td>
|
90
|
+
</tr>
|
91
|
+
</table>
|
92
|
+
</article>
|
93
|
+
<article class="column col-6">
|
94
|
+
<h2 id="log-structure">Log Structure</h2>
|
95
|
+
|
96
|
+
<table class="table log-structure">
|
97
|
+
<tbody>
|
98
|
+
<tr>
|
99
|
+
<th>Input file</th>
|
100
|
+
<td><b><%= (data[:log_file] || "stdin") %></b></td>
|
101
|
+
</tr>
|
102
|
+
<tr>
|
103
|
+
<th>Period in Log</th>
|
104
|
+
<td><%= data[:first_day] %> -- <%= data[:last_day] %></td>
|
105
|
+
</tr>
|
106
|
+
<tr>
|
107
|
+
<th>Total days</th>
|
108
|
+
<td><%= data[:total_days] %></td>
|
109
|
+
</tr>
|
110
|
+
<tr>
|
111
|
+
<th>Log size</th>
|
112
|
+
<td><%= data[:log_size][0][0] %></td>
|
113
|
+
</tr>
|
114
|
+
<tr>
|
115
|
+
<th>Self poll entries</th>
|
116
|
+
<td><%= data[:selfpolls_size][0][0] %></td>
|
117
|
+
</tr>
|
118
|
+
<tr>
|
119
|
+
<th>Crawlers</th>
|
120
|
+
<td><%= data[:crawlers_size][0][0] %></td>
|
121
|
+
</tr>
|
122
|
+
<tr>
|
123
|
+
<th>Entries considered</th>
|
124
|
+
<td><%= data[:total_hits][0][0] %></td>
|
125
|
+
</tr>
|
126
|
+
</tbody>
|
127
|
+
</table>
|
128
|
+
</article>
|
129
|
+
</div>
|
130
|
+
|
131
|
+
<% @reports = [
|
132
|
+
{ title: "Daily Distribution", header: ["Day", "DOW", "Hits", "Visits", "Size"], rows: data[:daily_distribution] },
|
133
|
+
{ title: "Time Distribution", header: ["Hour", "Hits", "Visits", "Size"], rows: data[:time_distribution] },
|
134
|
+
{ title: "Most Requested Pages", header: ["Path", "Hits", "Visits", "Size"], rows: data[:most_requested_pages] },
|
135
|
+
{ title: "Most Requested Resources", header: ["Path", "Hits", "Visits", "Size"], rows: data[:most_requested_resources] },
|
136
|
+
{ title: "404 on HTML Files", header: ["Path", "Hits", "Visitors"], rows: data[:missed_pages] },
|
137
|
+
{ title: "404 on other Resources", header: ["Path", "Hits", "Visitors"], rows: data[:missed_resources] },
|
138
|
+
{ title: "Attacks", header: ["Path", "Hits", "Visitors"], rows: data[:attacks] },
|
139
|
+
{ },
|
140
|
+
{ title: "Statuses", header: ["Status", "Count"], rows: data[:statuses] },
|
141
|
+
{ title: "Daily Statuses", header: ["Status", "2xx", "3xx", "4xx"], rows: data[:statuses_by_day] },
|
142
|
+
{ title: "Browsers", header: ["Browser", "Hits", "Visitors", "Size"], rows: data[:browsers] },
|
143
|
+
{ title: "Platforms", header: ["Platform", "Hits", "Visitors", "Size"], rows: data[:platforms] },
|
144
|
+
{ title: "Referers", header: ["Referers", "Hits", "Visitors", "Size"], rows: data[:referers], col: "col-12" },
|
145
|
+
{ title: "IPs", header: ["IPs", "Hits", "Visitors", "Size"], rows: data[:ips] },
|
146
|
+
{ },
|
147
|
+
]
|
148
|
+
%>
|
149
|
+
<div class="columns">
|
150
|
+
<% @reports.each do |report| %>
|
151
|
+
<div class="column <%= report[:col] || "col-6" %>">
|
152
|
+
<article>
|
153
|
+
<% if report[:title] != nil %>
|
154
|
+
<h2 id="<%= report[:title].downcase.gsub(/ +/, '-') %>">
|
155
|
+
<%= report[:title] %>
|
156
|
+
</h2>
|
157
|
+
<%= render "output_table", report %>
|
158
|
+
<% end %>
|
159
|
+
</article>
|
160
|
+
</div>
|
161
|
+
<% end %>
|
162
|
+
</div>
|
163
|
+
|
164
|
+
<article>
|
165
|
+
<h2 id="streaks">Streaks</h2>
|
166
|
+
|
167
|
+
<table class="table streaks">
|
168
|
+
<thead>
|
169
|
+
<tr>
|
170
|
+
<th>IP</th>
|
171
|
+
<th>Day and URL</th>
|
172
|
+
</tr>
|
173
|
+
</thead>
|
174
|
+
<tbody>
|
175
|
+
<% data[:streaks].group_by(&:first).each do |ip, date_urls| %>
|
176
|
+
<tr>
|
177
|
+
<td class="ip"><%= ip %></td>
|
178
|
+
<td class="streaks">
|
179
|
+
<% date_urls.group_by(&:first).each do |date, urls| %>
|
180
|
+
<% urls.each do |url| %>
|
181
|
+
<b><%= url[1] %>:</b> <%= url[2] %> <br />
|
182
|
+
<% end %>
|
183
|
+
<% end %>
|
184
|
+
</td>
|
185
|
+
</tr>
|
186
|
+
<% end %>
|
187
|
+
</tbody>
|
188
|
+
</table>
|
189
|
+
</article>
|
190
|
+
|
191
|
+
<div class="columns">
|
192
|
+
<div class="column col-6">
|
193
|
+
<article>
|
194
|
+
<h2 id="command-invocation">Command Invocation</h2>
|
195
|
+
|
196
|
+
<table class="table command-invocation">
|
197
|
+
<tbody>
|
198
|
+
<tr>
|
199
|
+
<th>CLI Command</th>
|
200
|
+
<td><code><%= data[:command] %></code></td>
|
201
|
+
</tr>
|
202
|
+
<tr>
|
203
|
+
<th>Input file</th>
|
204
|
+
<td><code><%= (data[:log_file] || "stdin") %></code></td>
|
205
|
+
</tr>
|
206
|
+
<tr>
|
207
|
+
<th>Ignore crawlers</th>
|
208
|
+
<td><code><%= options[:ignore_crawlers] %></code></td></tr>
|
209
|
+
<tr>
|
210
|
+
<th>Only crawlers</th>
|
211
|
+
<td><code><%= options[:only_crawlers] %></code></td>
|
212
|
+
</tr>
|
213
|
+
<tr>
|
214
|
+
<th>No selfpoll</th>
|
215
|
+
<td><code><%= options[:no_selfpoll] %></code></td>
|
216
|
+
</tr>
|
217
|
+
<tr>
|
218
|
+
<th>Filter by date</th>
|
219
|
+
<td>
|
220
|
+
<code><%= (options[:from_date] != nil or options[:to_date] != nil) %></code>
|
221
|
+
</td>
|
222
|
+
</tr>
|
223
|
+
<tr>
|
224
|
+
<th>Prefix</th>
|
225
|
+
<td><code><%= @prefix %></code></td>
|
226
|
+
</tr>
|
227
|
+
<tr>
|
228
|
+
<th>Suffix</th>
|
229
|
+
<td><code><%= @suffix %></code></td>
|
230
|
+
</tr>
|
231
|
+
</tbody>
|
232
|
+
</table>
|
233
|
+
</article>
|
234
|
+
</div>
|
235
|
+
|
236
|
+
<div class="column col-6">
|
237
|
+
<article>
|
238
|
+
<h2 id="performance"> Performance</h2>
|
239
|
+
|
240
|
+
<table class="table performance">
|
241
|
+
<tbody>
|
242
|
+
<tr>
|
243
|
+
<th>Analysis started at</th>
|
244
|
+
<td><%= data[:started_at].to_s %></td>
|
245
|
+
</tr>
|
246
|
+
<tr>
|
247
|
+
<th>Analysis ended at</th>
|
248
|
+
<td><%= data[:ended_at].to_s %></td>
|
249
|
+
</tr>
|
250
|
+
<tr>
|
251
|
+
<th>Duration (sec)</th>
|
252
|
+
<td><%= "%.1f" % data[:duration] %></td>
|
253
|
+
</tr>
|
254
|
+
<tr>
|
255
|
+
<th>Duration (min)</th>
|
256
|
+
<td><%= "%d" % (data[:duration] / 60 ) %></td>
|
257
|
+
</tr>
|
258
|
+
<tr>
|
259
|
+
<th>Log size</th>
|
260
|
+
<td><%= data[:log_size][0][0] %></td>
|
261
|
+
</tr>
|
262
|
+
<tr>
|
263
|
+
<th>Lines/sec</th>
|
264
|
+
<td><%= "%.2f" % (data[:log_size][0][0] / data[:duration]) %></td></tr>
|
265
|
+
</tbody>
|
266
|
+
</table>
|
267
|
+
</article>
|
268
|
+
</div>
|
269
|
+
</div>
|
270
|
+
</section>
|
271
|
+
</div>
|
195
272
|
</body>
|
196
273
|
</html>
|
197
274
|
|
@@ -10,7 +10,11 @@
|
|
10
10
|
| Hits | <%= "%10d" % data[:total_hits][0][0] %> |
|
11
11
|
| Unique Visitors | <%= "%10d" % data[:total_unique_visitors][0][0] %> |
|
12
12
|
| Tx | <%= "%10s" % data[:total_size][0][0] %> |
|
13
|
-
|
|
13
|
+
| Logged Period | <%= data[:first_day] %> -- <%= data[:last_day] %> |
|
14
|
+
| Days | <%= "%10d" % data[:total_days] %> |
|
15
|
+
| Period Requested | <%= data[:first_day_requested] %> -- <%= data[:last_day_requested] %> |
|
16
|
+
| Period Analyzed | <%= data[:first_day_in_analysis] %> -- <%= data[:last_day_in_analysis] %> |
|
17
|
+
| Days in Analysis | <%= data[:total_days_in_analysis] %> |
|
14
18
|
|
15
19
|
* Daily Distribution
|
16
20
|
|
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.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adolfo Villafiorita
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: apache_log-parser
|
@@ -66,7 +66,8 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: Generate
|
69
|
+
description: Generate requests reports in HTML, OrgMode, and SQLite format from an
|
70
|
+
Apache log file.
|
70
71
|
email:
|
71
72
|
- adolfo.villafiorita@ict4g.net
|
72
73
|
executables:
|
@@ -121,5 +122,5 @@ requirements: []
|
|
121
122
|
rubygems_version: 3.2.22
|
122
123
|
signing_key:
|
123
124
|
specification_version: 4
|
124
|
-
summary: Generate
|
125
|
+
summary: Generate analytics from an Apache log file.
|
125
126
|
test_files: []
|