log_sense 1.2.3 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.org +13 -6
- data/Gemfile.lock +1 -3
- data/README.org +53 -35
- data/apache-screenshot.png +0 -0
- data/lib/log_sense/apache_log_line_parser.rb +56 -0
- data/lib/log_sense/apache_log_parser.rb +14 -12
- data/lib/log_sense/templates/_output_table.html.erb +15 -11
- data/lib/log_sense/templates/_report_data.html.erb +12 -0
- data/lib/log_sense/templates/apache.html.erb +11 -18
- data/lib/log_sense/templates/rails.html.erb +8 -16
- data/lib/log_sense/version.rb +1 -1
- data/lib/log_sense.rb +1 -0
- data/log_sense.gemspec +20 -21
- metadata +16 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8250028b7a7038e07f2bd9fa069bfdf0ab1815a8711a0b6971a91030d529882
|
4
|
+
data.tar.gz: 236e1ba2c3ada9272f1e7eaa649cd1664776da933a90e41b6e70fffbbe002043
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72b6284cd6f09ebf16c4fe34fc7098da44e993a2946fb09f72ccaa7898eb462b9fcb49ce2e37e06b206a3f00650f8a033ec034ffeeab3afe587b6b607d079302
|
7
|
+
data.tar.gz: 6b96590430caa4e9717180c1812b0227b661f1fef4c99e10515da6da8acbe8fd596b91a9e0d536eff2ce525ba1fc01f4819a5c3f649bb59f4c77754edbbd5b0c
|
data/CHANGELOG.org
CHANGED
@@ -2,13 +2,20 @@
|
|
2
2
|
#+AUTHOR: Adolfo Villafiorita
|
3
3
|
#+STARTUP: showall
|
4
4
|
|
5
|
-
*
|
6
|
-
<2021-12-17 Fri>
|
5
|
+
* 1.3.2
|
7
6
|
|
8
|
-
-
|
7
|
+
- [Code] HTML reports now generate JSON data which is shared between
|
8
|
+
DataTable and Vega Light: this should reduce page size and loading
|
9
|
+
time of HTML reports
|
10
|
+
- [Doc] Added screenshot and fixed some text
|
11
|
+
- [Doc] Fixes requirements on Ruby version
|
9
12
|
|
10
|
-
*
|
11
|
-
<2021-12-17 Fri>
|
13
|
+
* 1.3.1
|
12
14
|
|
13
|
-
-
|
15
|
+
- [Code] Strengthened parsing of Apache Logs (added WebDav and other methods)
|
14
16
|
|
17
|
+
* 1.3.0
|
18
|
+
|
19
|
+
- [Code] Removed dependency from =apache_log-parser= and implemented our own
|
20
|
+
parser for the combined format.
|
21
|
+
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
log_sense (1.
|
5
|
-
apache_log-parser
|
4
|
+
log_sense (1.3.1)
|
6
5
|
browser
|
7
6
|
ipaddr
|
8
7
|
iso_country_codes
|
@@ -12,7 +11,6 @@ PATH
|
|
12
11
|
GEM
|
13
12
|
remote: https://rubygems.org/
|
14
13
|
specs:
|
15
|
-
apache_log-parser (3.1.2)
|
16
14
|
browser (5.3.1)
|
17
15
|
byebug (11.1.3)
|
18
16
|
ipaddr (1.2.3)
|
data/README.org
CHANGED
@@ -4,24 +4,10 @@
|
|
4
4
|
|
5
5
|
* Introduction
|
6
6
|
|
7
|
-
LogSense generates reports and statistics from Apache
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
LogSense 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 LogSense is stored on your computer and owned by
|
15
|
-
you (like it should be).
|
16
|
-
|
17
|
-
LogSense is also inspired by *static websites generators*: statistics
|
18
|
-
are generated from the command line and accessed as static HTML files.
|
19
|
-
By generating static resources, LogSense significantly reduces the
|
20
|
-
attack surface of your webserver and installation headaches.
|
21
|
-
|
22
|
-
We have, for instance, a cron job running on our servers, generating
|
23
|
-
statistics at night. The generated files are then made available on a
|
24
|
-
private area on the web.
|
7
|
+
LogSense generates reports and statistics from Apache and Ruby on
|
8
|
+
Rails logs. Written in Ruby, it runs from the command line, it is
|
9
|
+
fast, and it can be installed on any system with a relatively recent
|
10
|
+
version of Ruby. We tested on Ruby 2.6.9, Ruby 3.0.x and later.
|
25
11
|
|
26
12
|
LogSense reports the following data:
|
27
13
|
|
@@ -40,7 +26,27 @@ LogSense reports the following data:
|
|
40
26
|
Filters from the command line allow to analyze specific periods and
|
41
27
|
distinguish traffic generated by self polls and crawlers.
|
42
28
|
|
43
|
-
LogSense generates HTML, txt
|
29
|
+
LogSense generates HTML, txt, and SQLite outputs.
|
30
|
+
|
31
|
+
And, of course, the compulsory screenshot:
|
32
|
+
|
33
|
+
#+ATTR_HTML: :width 80%
|
34
|
+
[[file:./apache-screenshot.png]]
|
35
|
+
|
36
|
+
* Motivation
|
37
|
+
|
38
|
+
LogSense moves along the lines of tools such as [[https://goaccess.io/][GoAccess]] (which
|
39
|
+
strongly inspired the development of Log Sense) and [[https://umami.is/][Umami]], focusing on
|
40
|
+
*privacy* and *data-ownership*: the data generated by LogSense is
|
41
|
+
stored on your computer and owned by you (like it should be)[fn:1].
|
42
|
+
|
43
|
+
LogSense is also inspired by *static websites generators*: statistics
|
44
|
+
are generated from the command line and accessed as static HTML files.
|
45
|
+
LogSense thus significantly reduces the attack surface of your
|
46
|
+
web server and installation headaches. We have, for instance, a cron
|
47
|
+
job running on our servers, generating statistics at night. The
|
48
|
+
generated files are then made available on a private area on the web.
|
49
|
+
|
44
50
|
|
45
51
|
* Installation
|
46
52
|
|
@@ -70,48 +76,60 @@ LogSense generates HTML, txt (Org Mode), and SQLite outputs.
|
|
70
76
|
-v, --version Prints version information
|
71
77
|
-h, --help Prints this help
|
72
78
|
|
73
|
-
This is version 1.
|
79
|
+
This is version 1.3.1
|
74
80
|
|
75
81
|
Output formats
|
76
|
-
apache parsing can produce the following outputs:
|
77
|
-
- sqlite
|
78
|
-
- html
|
79
82
|
rails parsing can produce the following outputs:
|
80
83
|
- sqlite
|
81
84
|
- txt
|
85
|
+
- html
|
86
|
+
apache parsing can produce the following outputs:
|
87
|
+
- sqlite
|
88
|
+
- html
|
82
89
|
#+end_example
|
83
90
|
|
91
|
+
Examples:
|
92
|
+
|
93
|
+
#+begin_example sh
|
94
|
+
log_sense -f apache -i access.log -t txt > access-data.txt
|
95
|
+
log_sense -f rails -i production.log -t html -o performance.txt
|
96
|
+
#+end_example
|
97
|
+
|
84
98
|
* Change Log
|
85
99
|
|
86
100
|
See the [[file:CHANGELOG.org][CHANGELOG]] file.
|
87
101
|
|
88
102
|
* Compatibility
|
89
103
|
|
90
|
-
LogSense should run on any system on which Ruby
|
104
|
+
LogSense should run on any system on which a recent version of Ruby
|
105
|
+
runs. We tested it with Ruby 2.6.9 and Ruby 3.x.x.
|
91
106
|
|
92
107
|
Concerning the outputs:
|
93
108
|
|
94
|
-
-
|
95
|
-
are downloaded from a CDN
|
96
|
-
- The textual format is compatible with Org Mode and can be further
|
97
|
-
processed to any format Org Mode can be exported to (including HTML
|
98
|
-
and PDF)
|
109
|
+
- HTML reports use [[https://get.foundation/][Zurb Foundation]], [[https://www.datatables.net/][Data Tables]], and [[https://vega.github.io/vega-lite/][Vega Light]], which
|
110
|
+
are all downloaded from a CDN
|
111
|
+
- The textual format is compatible with [[https://orgmode.org/][Org Mode]] and can be further
|
112
|
+
processed to any format [[https://orgmode.org/][Org Mode]] can be exported to (including HTML
|
113
|
+
and PDF)
|
99
114
|
|
100
115
|
* Author and Contributors
|
101
116
|
|
102
|
-
[[
|
117
|
+
[[https://shair.tech][Shair.Tech]]
|
103
118
|
|
104
119
|
* Known Bugs
|
105
120
|
|
106
|
-
|
107
|
-
|
121
|
+
No known bugs; an unknown number of unknown bugs.
|
108
122
|
(See the open issues for the known bugs.)
|
109
123
|
|
110
124
|
* License
|
111
125
|
|
112
126
|
Distributed under the terms of the [[http://opensource.org/licenses/MIT][MIT License]].
|
113
127
|
|
114
|
-
Geolocation is made possible by the DB-IP.com IP to City database,
|
115
|
-
a CC license.
|
116
|
-
|
128
|
+
Geolocation is made possible by the DB-IP.com IP to City database,
|
129
|
+
released under a CC license.
|
117
130
|
|
131
|
+
[fn:1] There is a small catch: CSS and JavaScript for layout and plots
|
132
|
+
are downloaded from a CDN. Technically, thus, if you generate HTML
|
133
|
+
reports and open them, a request is performed and the CDN might keep a
|
134
|
+
track (see [[https://en.wikipedia.org/wiki/Content_delivery_network#Security_and_privacy][CDN Security and Privacy on Wikipedia]] for more details).
|
135
|
+
Textual reports don't have this issue.
|
Binary file
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module LogSense
|
2
|
+
class ApacheLogLineParser
|
3
|
+
# parses a query and makes it into an expression which can be evaluated
|
4
|
+
# LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
|
5
|
+
#
|
6
|
+
# %h: IP
|
7
|
+
# %l: ident or -
|
8
|
+
# %u: userid or -
|
9
|
+
# %t: [10/Oct/2000:13:55:36 -0700]
|
10
|
+
# day = 2*digit
|
11
|
+
# month = 3*letter
|
12
|
+
# year = 4*digit
|
13
|
+
# hour = 2*digit
|
14
|
+
# minute = 2*digit
|
15
|
+
# second = 2*digit
|
16
|
+
# zone = (`+' | `-') 4*digit
|
17
|
+
# %r: GET /apache_pb.gif HTTP/1.0
|
18
|
+
# %{User-agent}: "
|
19
|
+
#
|
20
|
+
# 116.179.32.16 - - [19/Dec/2021:22:35:11 +0100] "GET / HTTP/1.1" 200 135 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
|
21
|
+
|
22
|
+
DAY = /[0-9]{2}/
|
23
|
+
MONTH = /[A-Za-z]{3}/
|
24
|
+
YEAR = /[0-9]{4}/
|
25
|
+
TIMEC = /[0-9]{2}/
|
26
|
+
TIMEZONE = /(\+|-)[0-9]{4}/
|
27
|
+
|
28
|
+
IP = /(?<ip>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|::1)/
|
29
|
+
IDENT = /(?<ident>[^ ]+|-)/
|
30
|
+
USERID = /(?<userid>[^ ]+|-)/
|
31
|
+
|
32
|
+
TIMESTAMP = /(?<date>#{DAY}\/#{MONTH}\/#{YEAR}):(?<time>#{TIMEC}:#{TIMEC}:#{TIMEC} #{TIMEZONE})/
|
33
|
+
|
34
|
+
HTTP_METHODS=/GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH/
|
35
|
+
WEBDAV_METHODS=/COPY|LOCK|MKCOL|MOVE|PROPFIND|PROPPATCH|UNLOCK/
|
36
|
+
OTHER_METHODS=/SEARCH|REPORT/
|
37
|
+
METHOD=/(?<method>#{HTTP_METHODS}|#{WEBDAV_METHODS}|#{OTHER_METHODS})/
|
38
|
+
PROTOCOL=/(?<protocol>HTTP\/[0-9]\.[0-9])/
|
39
|
+
URL=/(?<url>[^ ]+)/
|
40
|
+
REFERER=/(?<referer>[^ ]+)/
|
41
|
+
RETURN_CODE=/(?<status>[1-5][0-9][0-9])/
|
42
|
+
SIZE=/(?<size>[0-9]+|-)/
|
43
|
+
|
44
|
+
USER_AGENT = /(?<user_agent>[^"]+)/
|
45
|
+
|
46
|
+
attr_reader :format
|
47
|
+
|
48
|
+
def initialize
|
49
|
+
@format = /#{IP} #{IDENT} #{USERID} \[#{TIMESTAMP}\] "#{METHOD} #{URL} #{PROTOCOL}" #{RETURN_CODE} #{SIZE} "#{REFERER}" "#{USER_AGENT}"/
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse line
|
53
|
+
hash = @format.match(line) || raise("Apache LogLine Parser Error: Could not parse #{line}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'apache_log/parser'
|
2
1
|
require 'sqlite3'
|
3
2
|
require 'browser'
|
4
3
|
|
@@ -50,21 +49,20 @@ module LogSense
|
|
50
49
|
platform_version)
|
51
50
|
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
|
52
51
|
|
53
|
-
parser =
|
52
|
+
parser = ApacheLogLineParser.new
|
54
53
|
|
55
54
|
content.each do |line|
|
56
55
|
begin
|
57
56
|
hash = parser.parse line
|
58
|
-
|
59
57
|
ua = Browser.new(hash[:user_agent], accept_language: "en-us")
|
60
58
|
ins.execute(
|
61
|
-
hash[:
|
62
|
-
hash[:
|
63
|
-
hash[:
|
64
|
-
hash
|
65
|
-
hash[:
|
66
|
-
hash[:
|
67
|
-
(hash[:
|
59
|
+
DateTime.parse("#{hash[:date]}T#{hash[:time]}").iso8601,
|
60
|
+
hash[:ip],
|
61
|
+
hash[:userid],
|
62
|
+
unique_visitor_id(hash),
|
63
|
+
hash[:method],
|
64
|
+
hash[:url],
|
65
|
+
(hash[:url] ? File.extname(hash[:url]) : ""),
|
68
66
|
hash[:status],
|
69
67
|
hash[:size].to_i,
|
70
68
|
hash[:referer],
|
@@ -75,13 +73,17 @@ module LogSense
|
|
75
73
|
(ua.platform.name || ""),
|
76
74
|
(ua.platform.version || "")
|
77
75
|
)
|
78
|
-
rescue
|
79
|
-
STDERR.puts
|
76
|
+
rescue StandardError => e
|
77
|
+
STDERR.puts e.message
|
80
78
|
end
|
81
79
|
end
|
82
80
|
|
83
81
|
db
|
84
82
|
end
|
85
83
|
|
84
|
+
def self.unique_visitor_id hash
|
85
|
+
"#{hash[:date]} #{hash[:ip]} #{hash[:user_agent]}"
|
86
|
+
end
|
87
|
+
|
86
88
|
end
|
87
89
|
end
|
@@ -4,22 +4,26 @@ def slugify string
|
|
4
4
|
end
|
5
5
|
%>
|
6
6
|
|
7
|
-
<table id="
|
7
|
+
<table id="table-<%= index %>" class="table unstriped">
|
8
8
|
<thead>
|
9
9
|
<tr>
|
10
|
-
<% header.each do |
|
11
|
-
<th
|
10
|
+
<% report[:header].each do |header| %>
|
11
|
+
<th><%= header %></th>
|
12
12
|
<% end %>
|
13
13
|
</tr>
|
14
14
|
</thead>
|
15
15
|
<tbody>
|
16
|
-
<% rows.each do |row| %>
|
17
|
-
<tr>
|
18
|
-
<% row.each_with_index do |cell, i| %>
|
19
|
-
<td class="<%= slugify (header[i] || "") %>"><%= cell %></td>
|
20
|
-
<% end %>
|
21
|
-
</tr>
|
22
|
-
<% end %>
|
23
16
|
</tbody>
|
24
17
|
</table>
|
25
|
-
|
18
|
+
<script>
|
19
|
+
$(document).ready(function(){
|
20
|
+
$('#table-<%= index %>').dataTable({
|
21
|
+
data: data_<%= index %>,
|
22
|
+
columns: [
|
23
|
+
<% report[:header].each do |header| %>
|
24
|
+
{ data: '<%= header %>', className: '<%= slugify(header) %>' },
|
25
|
+
<% end %>
|
26
|
+
]
|
27
|
+
});
|
28
|
+
});
|
29
|
+
</script>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<script>
|
2
|
+
/* this is used both by Vega and DataTable */
|
3
|
+
data_<%= index %> = [
|
4
|
+
<% report[:rows].each do |row| %>
|
5
|
+
{
|
6
|
+
<% report[:header].each_with_index do |h, i| %>
|
7
|
+
"<%= h %>": <%= (row[i].class == Integer or row[i].class == Float) ? row[i] : "\"#{row[i]}\"" %>,
|
8
|
+
<% end %>
|
9
|
+
},
|
10
|
+
<% end %>
|
11
|
+
]
|
12
|
+
</script>
|
@@ -17,6 +17,8 @@
|
|
17
17
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/css/foundation.min.css">
|
18
18
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.css"/>
|
19
19
|
|
20
|
+
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
21
|
+
<script type="text/javascript" src="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.js"></script>
|
20
22
|
|
21
23
|
<script src="https://cdn.jsdelivr.net/npm/vega@5.21.0"></script>
|
22
24
|
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5.2.0"></script>
|
@@ -29,14 +31,14 @@
|
|
29
31
|
}
|
30
32
|
|
31
33
|
#offCanvas {
|
32
|
-
color:
|
33
|
-
background: #
|
34
|
+
color: #DEDEDE;
|
35
|
+
background: #1C1C1C;
|
34
36
|
border-right: none;
|
35
37
|
box-shadow: none;
|
36
38
|
padding: 0.5rem;
|
37
39
|
}
|
38
40
|
#offCanvas a {
|
39
|
-
color: #
|
41
|
+
color: #FFFFFF;
|
40
42
|
}
|
41
43
|
|
42
44
|
.contents-button {
|
@@ -69,7 +71,7 @@
|
|
69
71
|
|
70
72
|
.card-divider {
|
71
73
|
padding: 0.2rem 0.4rem 0.2rem 0.4rem;
|
72
|
-
background: #
|
74
|
+
background: #1C1C1C;
|
73
75
|
color: white;
|
74
76
|
}
|
75
77
|
|
@@ -426,7 +428,7 @@
|
|
426
428
|
<%= report[:title] %>
|
427
429
|
</h2>
|
428
430
|
</div>
|
429
|
-
|
431
|
+
<%= render "report_data.html.erb", report: report, index: index %>
|
430
432
|
<% if report[:vega_spec] %>
|
431
433
|
<div id="<%= "plot-#{index}" %>"></div>
|
432
434
|
<script>
|
@@ -436,22 +438,15 @@
|
|
436
438
|
width: "container",
|
437
439
|
description: "<%= report[:title] %>",
|
438
440
|
data: {
|
439
|
-
values:
|
440
|
-
<% report[:rows].each do |row| %>
|
441
|
-
{
|
442
|
-
<% report[:header].each_with_index do |h, i| %>
|
443
|
-
"<%= h %>": <%= (row[i].class == Integer or row[i].class == Float) ? row[i] : "\"#{row[i]}\"" %>,
|
444
|
-
<% end %>
|
445
|
-
},
|
446
|
-
<% end %>
|
447
|
-
]
|
441
|
+
values: data_<%= index %>
|
448
442
|
},
|
449
443
|
});
|
450
444
|
vegaEmbed('#<%= "plot-#{index}"%>', plot_spec_<%= index %>);
|
451
445
|
</script>
|
452
446
|
<% end %>
|
453
|
-
|
454
|
-
|
447
|
+
|
448
|
+
<div class="card-section">
|
449
|
+
<%= render "output_table.html.erb", report: report, index: index %>
|
455
450
|
</div>
|
456
451
|
</article>
|
457
452
|
<% end %>
|
@@ -569,9 +564,7 @@
|
|
569
564
|
</section>
|
570
565
|
</div>
|
571
566
|
|
572
|
-
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
573
567
|
<script type="text/javascript" src="js/vendor/what-input.js"></script>
|
574
|
-
<script type="text/javascript" src="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.js"></script>
|
575
568
|
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
|
576
569
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/js/foundation.min.js" crossorigin="anonymous"></script>
|
577
570
|
<script>
|
@@ -17,6 +17,8 @@
|
|
17
17
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/css/foundation.min.css">
|
18
18
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.css"/>
|
19
19
|
|
20
|
+
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
21
|
+
<script type="text/javascript" src="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.js"></script>
|
20
22
|
|
21
23
|
<script src="https://cdn.jsdelivr.net/npm/vega@5.21.0"></script>
|
22
24
|
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5.2.0"></script>
|
@@ -29,14 +31,14 @@
|
|
29
31
|
}
|
30
32
|
|
31
33
|
#offCanvas {
|
32
|
-
color:
|
33
|
-
background: #
|
34
|
+
color: #CECECE;
|
35
|
+
background: #BD000D;
|
34
36
|
border-right: none;
|
35
37
|
box-shadow: none;
|
36
38
|
padding: 0.5rem;
|
37
39
|
}
|
38
40
|
#offCanvas a {
|
39
|
-
color: #
|
41
|
+
color: #FFFFFF;
|
40
42
|
}
|
41
43
|
|
42
44
|
.contents-button {
|
@@ -341,7 +343,7 @@
|
|
341
343
|
<%= report[:title] %>
|
342
344
|
</h2>
|
343
345
|
</div>
|
344
|
-
|
346
|
+
<%= render "report_data.html.erb", report: report, index: index %>
|
345
347
|
<% if report[:vega_spec] %>
|
346
348
|
<div id="<%= "plot-#{index}" %>"></div>
|
347
349
|
<script>
|
@@ -351,22 +353,14 @@
|
|
351
353
|
width: "container",
|
352
354
|
description: "<%= report[:title] %>",
|
353
355
|
data: {
|
354
|
-
values:
|
355
|
-
<% report[:rows].each do |row| %>
|
356
|
-
{
|
357
|
-
<% report[:header].each_with_index do |h, i| %>
|
358
|
-
"<%= h %>": <%= (row[i].class == Integer or row[i].class == Float) ? row[i] : "\"#{row[i]}\"" %>,
|
359
|
-
<% end %>
|
360
|
-
},
|
361
|
-
<% end %>
|
362
|
-
]
|
356
|
+
values: data_<%= index %>
|
363
357
|
},
|
364
358
|
});
|
365
359
|
vegaEmbed('#<%= "plot-#{index}"%>', plot_spec_<%= index %>);
|
366
360
|
</script>
|
367
361
|
<% end %>
|
368
362
|
<div class="card-section">
|
369
|
-
<%= render "output_table.html.erb", report %>
|
363
|
+
<%= render "output_table.html.erb", report: report, index: index %>
|
370
364
|
</div>
|
371
365
|
</article>
|
372
366
|
<% end %>
|
@@ -392,9 +386,7 @@
|
|
392
386
|
</section>
|
393
387
|
</div>
|
394
388
|
|
395
|
-
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
396
389
|
<script type="text/javascript" src="js/vendor/what-input.js"></script>
|
397
|
-
<script type="text/javascript" src="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.js"></script>
|
398
390
|
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
|
399
391
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/js/foundation.min.js" crossorigin="anonymous"></script>
|
400
392
|
<script>
|
data/lib/log_sense/version.rb
CHANGED
data/lib/log_sense.rb
CHANGED
data/log_sense.gemspec
CHANGED
@@ -1,39 +1,38 @@
|
|
1
1
|
require_relative 'lib/log_sense/version'
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
|
-
spec.name =
|
4
|
+
spec.name = 'log_sense'
|
5
5
|
spec.version = LogSense::VERSION
|
6
|
-
spec.authors = [
|
7
|
-
spec.email = [
|
6
|
+
spec.authors = ['Adolfo Fibrillation']
|
7
|
+
spec.email = ['adolfo@shair.tech']
|
8
8
|
|
9
|
-
spec.summary = %q{Generate analytics
|
10
|
-
spec.description = %q{Generate
|
11
|
-
spec.homepage =
|
12
|
-
spec.license =
|
13
|
-
spec.required_ruby_version = Gem::Requirement.new(
|
9
|
+
spec.summary = %q{Generate analytics for Apache and Rails log file.}
|
10
|
+
spec.description = %q{Generate analytics in HTML, txt, and SQLite format for Apache and Rails log files.}
|
11
|
+
spec.homepage = 'https://github.com/shair-tech/log_sense/log_sense'
|
12
|
+
spec.license = 'MIT'
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.6.9')
|
14
14
|
|
15
|
-
spec.metadata[
|
15
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
|
16
16
|
|
17
|
-
spec.metadata[
|
18
|
-
spec.metadata[
|
19
|
-
spec.metadata[
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
+
spec.metadata['source_code_uri'] = 'https://github.com/shair-tech/log_sense/log_sense'
|
19
|
+
spec.metadata['changelog_uri'] = 'https://github.com/shair-tech/log_sense/blob/main/CHANGELOG.org'
|
20
20
|
|
21
21
|
# Specify which files should be added to the gem when it is released.
|
22
22
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
23
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
24
24
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
25
|
end
|
26
|
-
spec.bindir =
|
26
|
+
spec.bindir = 'exe'
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
-
spec.require_paths = [
|
28
|
+
spec.require_paths = ['lib']
|
29
29
|
|
30
|
-
spec.add_dependency
|
31
|
-
spec.add_dependency
|
32
|
-
spec.add_dependency
|
33
|
-
spec.add_dependency
|
34
|
-
spec.add_dependency
|
35
|
-
spec.add_dependency "terminal-table"
|
30
|
+
spec.add_dependency 'browser'
|
31
|
+
spec.add_dependency 'ipaddr'
|
32
|
+
spec.add_dependency 'iso_country_codes'
|
33
|
+
spec.add_dependency 'sqlite3'
|
34
|
+
spec.add_dependency 'terminal-table'
|
36
35
|
|
37
36
|
spec.add_development_dependency 'byebug'
|
38
|
-
spec.add_development_dependency
|
37
|
+
spec.add_development_dependency 'minitest'
|
39
38
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: log_sense
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Adolfo
|
7
|
+
- Adolfo Fibrillation
|
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
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: apache_log-parser
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: browser
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,10 +108,10 @@ dependencies:
|
|
122
108
|
- - ">="
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: '0'
|
125
|
-
description: Generate
|
126
|
-
|
111
|
+
description: Generate analytics in HTML, txt, and SQLite format for Apache and Rails
|
112
|
+
log files.
|
127
113
|
email:
|
128
|
-
- adolfo
|
114
|
+
- adolfo@shair.tech
|
129
115
|
executables:
|
130
116
|
- log_sense
|
131
117
|
extensions: []
|
@@ -138,12 +124,14 @@ files:
|
|
138
124
|
- LICENSE.txt
|
139
125
|
- README.org
|
140
126
|
- Rakefile
|
127
|
+
- apache-screenshot.png
|
141
128
|
- bin/console
|
142
129
|
- bin/setup
|
143
130
|
- exe/log_sense
|
144
131
|
- ip_locations/dbip-country-lite.sqlite3
|
145
132
|
- lib/log_sense.rb
|
146
133
|
- lib/log_sense/apache_data_cruncher.rb
|
134
|
+
- lib/log_sense/apache_log_line_parser.rb
|
147
135
|
- lib/log_sense/apache_log_parser.rb
|
148
136
|
- lib/log_sense/emitter.rb
|
149
137
|
- lib/log_sense/ip_locator.rb
|
@@ -156,6 +144,7 @@ files:
|
|
156
144
|
- lib/log_sense/templates/_output_table.html.erb
|
157
145
|
- lib/log_sense/templates/_performance.html.erb
|
158
146
|
- lib/log_sense/templates/_performance.txt.erb
|
147
|
+
- lib/log_sense/templates/_report_data.html.erb
|
159
148
|
- lib/log_sense/templates/_summary.html.erb
|
160
149
|
- lib/log_sense/templates/_summary.txt.erb
|
161
150
|
- lib/log_sense/templates/apache.html.erb
|
@@ -166,14 +155,14 @@ files:
|
|
166
155
|
- sample_logs/empty_log.log
|
167
156
|
- sample_logs/safety-critical_org.log
|
168
157
|
- sample_logs/spmbook_com.log
|
169
|
-
homepage: https://
|
158
|
+
homepage: https://github.com/shair-tech/log_sense/log_sense
|
170
159
|
licenses:
|
171
160
|
- MIT
|
172
161
|
metadata:
|
173
162
|
allowed_push_host: https://rubygems.org/
|
174
|
-
homepage_uri: https://
|
175
|
-
source_code_uri: https://
|
176
|
-
changelog_uri: https://
|
163
|
+
homepage_uri: https://github.com/shair-tech/log_sense/log_sense
|
164
|
+
source_code_uri: https://github.com/shair-tech/log_sense/log_sense
|
165
|
+
changelog_uri: https://github.com/shair-tech/log_sense/blob/main/CHANGELOG.org
|
177
166
|
post_install_message:
|
178
167
|
rdoc_options: []
|
179
168
|
require_paths:
|
@@ -182,15 +171,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
171
|
requirements:
|
183
172
|
- - ">="
|
184
173
|
- !ruby/object:Gem::Version
|
185
|
-
version: 2.
|
174
|
+
version: 2.6.9
|
186
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
176
|
requirements:
|
188
177
|
- - ">="
|
189
178
|
- !ruby/object:Gem::Version
|
190
179
|
version: '0'
|
191
180
|
requirements: []
|
192
|
-
rubygems_version: 3.
|
181
|
+
rubygems_version: 3.0.3.1
|
193
182
|
signing_key:
|
194
183
|
specification_version: 4
|
195
|
-
summary: Generate analytics
|
184
|
+
summary: Generate analytics for Apache and Rails log file.
|
196
185
|
test_files: []
|