log_sense 1.5.2 → 1.6.0
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/CHANGELOG.org +27 -0
- data/Gemfile.lock +6 -4
- data/README.org +108 -34
- data/Rakefile +6 -6
- data/exe/log_sense +110 -39
- data/ip_locations/dbip-country-lite.sqlite3 +0 -0
- data/lib/log_sense/aggregator.rb +191 -0
- data/lib/log_sense/apache_aggregator.rb +122 -0
- data/lib/log_sense/apache_log_line_parser.rb +23 -21
- data/lib/log_sense/apache_log_parser.rb +15 -12
- data/lib/log_sense/apache_report_shaper.rb +309 -0
- data/lib/log_sense/emitter.rb +55 -553
- data/lib/log_sense/ip_locator.rb +24 -12
- data/lib/log_sense/options_checker.rb +24 -0
- data/lib/log_sense/options_parser.rb +81 -51
- data/lib/log_sense/rails_aggregator.rb +69 -0
- data/lib/log_sense/rails_log_parser.rb +82 -68
- data/lib/log_sense/rails_report_shaper.rb +183 -0
- data/lib/log_sense/report_shaper.rb +105 -0
- data/lib/log_sense/templates/_cdn_links.html.erb +11 -0
- data/lib/log_sense/templates/_command_invocation.html.erb +4 -0
- data/lib/log_sense/templates/_log_structure.html.erb +7 -1
- data/lib/log_sense/templates/_output_table.html.erb +6 -2
- data/lib/log_sense/templates/_rails.css.erb +7 -0
- data/lib/log_sense/templates/_summary.html.erb +9 -7
- data/lib/log_sense/templates/_summary.txt.erb +2 -2
- data/lib/log_sense/templates/{rails.html.erb → report_html.erb} +19 -37
- data/lib/log_sense/templates/{apache.txt.erb → report_txt.erb} +1 -1
- data/lib/log_sense/version.rb +1 -1
- data/lib/log_sense.rb +19 -9
- data/log_sense.gemspec +1 -1
- data/{apache-screenshot.png → screenshots/apache-screenshot.png} +0 -0
- data/screenshots/rails-screenshot.png +0 -0
- metadata +17 -11
- data/lib/log_sense/apache_data_cruncher.rb +0 -147
- data/lib/log_sense/rails_data_cruncher.rb +0 -141
- data/lib/log_sense/templates/apache.html.erb +0 -115
- data/lib/log_sense/templates/rails.txt.erb +0 -22
@@ -0,0 +1,183 @@
|
|
1
|
+
module LogSense
|
2
|
+
class RailsReportShaper < ReportShaper
|
3
|
+
def shape(data)
|
4
|
+
[
|
5
|
+
{
|
6
|
+
title: "Daily Distribution",
|
7
|
+
header: %w[Day DOW Hits],
|
8
|
+
column_alignment: %i[left left right],
|
9
|
+
rows: data[:daily_distribution],
|
10
|
+
vega_spec: {
|
11
|
+
"encoding": {
|
12
|
+
"x": {"field": "Day", "type": "temporal"},
|
13
|
+
"y": {"field": "Hits", "type": "quantitative"}
|
14
|
+
},
|
15
|
+
"layer": [
|
16
|
+
{
|
17
|
+
"mark": {
|
18
|
+
"type": "line",
|
19
|
+
"point": {
|
20
|
+
"filled": false,
|
21
|
+
"fill": "white"
|
22
|
+
}
|
23
|
+
}
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"mark": {
|
27
|
+
"type": "text",
|
28
|
+
"align": "left",
|
29
|
+
"baseline": "middle",
|
30
|
+
"dx": 5
|
31
|
+
},
|
32
|
+
"encoding": {
|
33
|
+
"text": {"field": "Hits", "type": "quantitative"}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
]
|
37
|
+
}
|
38
|
+
},
|
39
|
+
{
|
40
|
+
title: "Time Distribution",
|
41
|
+
header: %w[Hour Hits],
|
42
|
+
column_alignment: %i[left right],
|
43
|
+
rows: data[:time_distribution],
|
44
|
+
vega_spec: {
|
45
|
+
"layer": [
|
46
|
+
{
|
47
|
+
"mark": "bar",
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"mark": {
|
51
|
+
"type": "text",
|
52
|
+
"align": "middle",
|
53
|
+
"baseline": "top",
|
54
|
+
"dx": -10,
|
55
|
+
"yOffset": -15
|
56
|
+
},
|
57
|
+
"encoding": {
|
58
|
+
"text": {"field": "Hits", "type": "quantitative"}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
],
|
62
|
+
"encoding": {
|
63
|
+
"x": {"field": "Hour", "type": "nominal"},
|
64
|
+
"y": {"field": "Hits", "type": "quantitative"}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
},
|
68
|
+
{
|
69
|
+
title: "Statuses",
|
70
|
+
header: %w[Status Count],
|
71
|
+
column_alignment: %i[left right],
|
72
|
+
rows: data[:statuses],
|
73
|
+
vega_spec: {
|
74
|
+
"layer": [
|
75
|
+
{
|
76
|
+
"mark": "bar"
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"mark": {
|
80
|
+
"type": "text",
|
81
|
+
"align": "left",
|
82
|
+
"baseline": "top",
|
83
|
+
"dx": -10,
|
84
|
+
"yOffset": -20
|
85
|
+
},
|
86
|
+
"encoding": {
|
87
|
+
"text": {"field": "Count", "type": "quantitative"}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
],
|
91
|
+
"encoding": {
|
92
|
+
"x": {"field": "Status", "type": "nominal"},
|
93
|
+
"y": {"field": "Count", "type": "quantitative"}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
},
|
97
|
+
{
|
98
|
+
title: "Rails Performance",
|
99
|
+
header: %w[Controller Hits Min Avg Max],
|
100
|
+
column_alignment: %i[left right right right right],
|
101
|
+
rows: data[:performance],
|
102
|
+
vega_spec: {
|
103
|
+
"layer": [
|
104
|
+
{
|
105
|
+
"mark": { "type": "point",
|
106
|
+
"name": "data_points"
|
107
|
+
}
|
108
|
+
},
|
109
|
+
{
|
110
|
+
"mark": { "name": "label",
|
111
|
+
"type": "text",
|
112
|
+
"align": "left",
|
113
|
+
"baseline": "middle",
|
114
|
+
"dx": 5,
|
115
|
+
"yOffset": 0
|
116
|
+
},
|
117
|
+
"encoding": { "text": {"field": "Controller"},
|
118
|
+
"fontSize": {"value": 8}
|
119
|
+
},
|
120
|
+
},
|
121
|
+
],
|
122
|
+
"encoding": { "x": { "field": "Avg",
|
123
|
+
"type": "quantitative"
|
124
|
+
},
|
125
|
+
"y": { "field": "Hits",
|
126
|
+
"type": "quantitative"
|
127
|
+
}
|
128
|
+
},
|
129
|
+
}
|
130
|
+
},
|
131
|
+
{
|
132
|
+
title: "Fatal Events",
|
133
|
+
header: %w[Date IP URL Description Log ID],
|
134
|
+
column_alignment: %i[left left left left left],
|
135
|
+
rows: data[:fatal],
|
136
|
+
col: "small-12 cell"
|
137
|
+
},
|
138
|
+
{
|
139
|
+
title: "Internal Server Errors",
|
140
|
+
header: %w[Date Status IP URL Description Log ID],
|
141
|
+
column_alignment: %i[left left left left left left],
|
142
|
+
rows: data[:internal_server_error],
|
143
|
+
col: "small-12 cell"
|
144
|
+
},
|
145
|
+
{
|
146
|
+
title: "Errors",
|
147
|
+
header: %w[Log ID Context Description Count],
|
148
|
+
column_alignment: %i[left left left left],
|
149
|
+
rows: data[:error],
|
150
|
+
col: "small-12 cell"
|
151
|
+
},
|
152
|
+
{
|
153
|
+
title: "IPs",
|
154
|
+
header: %w[IPs Hits Country],
|
155
|
+
column_alignment: %i[left right left],
|
156
|
+
rows: data[:ips]
|
157
|
+
},
|
158
|
+
{
|
159
|
+
title: "Countries",
|
160
|
+
header: ["Country", "Hits", "IPs", "IP List"],
|
161
|
+
column_alignment: %i[left right left],
|
162
|
+
rows: countries_table(data[:countries])
|
163
|
+
},
|
164
|
+
ip_per_hour_report_spec(ips_per_hour(data[:ips_per_hour])),
|
165
|
+
session_report_spec(ips_detailed(data[:ips_per_day_detailed]))
|
166
|
+
]
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
|
171
|
+
# { country => [[ip, visit, country], ...]
|
172
|
+
def countries_table(data)
|
173
|
+
data&.map { |k, v|
|
174
|
+
[
|
175
|
+
k,
|
176
|
+
v.map { |x| x[1] }.inject(&:+),
|
177
|
+
v.map { |x| x[0] }.uniq.size,
|
178
|
+
v.map { |x| x[0] }.join(WORDS_SEPARATOR)
|
179
|
+
]
|
180
|
+
}&.sort { |x, y| x[0] <=> y[0] }
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module LogSense
|
2
|
+
class ReportShaper
|
3
|
+
WORDS_SEPARATOR = ' · '
|
4
|
+
|
5
|
+
# return { [ip,day] => { [ hits, list of urls ] } }
|
6
|
+
def ips_detailed(ips_per_day)
|
7
|
+
hash = pivot(ips_per_day, 0, 1, lambda { |array| array.map { |x| x[2] } })
|
8
|
+
array = []
|
9
|
+
hash.keys.map do |ip|
|
10
|
+
array += hash[ip].keys.map do |date|
|
11
|
+
[
|
12
|
+
ip,
|
13
|
+
hash[ip].keys.size,
|
14
|
+
date,
|
15
|
+
hash[ip][date].size,
|
16
|
+
hash[ip][date].uniq.size,
|
17
|
+
hash[ip][date].uniq.size < 100 ? hash[ip][date].uniq.join(WORDS_SEPARATOR) : "[too many]"
|
18
|
+
]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
array
|
22
|
+
end
|
23
|
+
|
24
|
+
def ips_per_hour(ips_per_hour)
|
25
|
+
hash = pivot(ips_per_hour, 0, 1)
|
26
|
+
hash.keys.map do |ip|
|
27
|
+
[
|
28
|
+
ip,
|
29
|
+
(0..23).map { |hour| hash[ip][hour.to_s]&.to_i }
|
30
|
+
].flatten
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Shape an array of arrays into a hash of hashes (row, cols)
|
35
|
+
# Params:
|
36
|
+
# +input_data+:: array of array
|
37
|
+
# +row_key+:: index of the inner array or lambda, used to group data
|
38
|
+
# by rows
|
39
|
+
# +col_key+:: index of the inner array or lambda, will be used
|
40
|
+
# to group cols
|
41
|
+
# +cell+:: lambda to get the value of the cells to put in the hashes.
|
42
|
+
# Takes and array as input (that is, an array of all the
|
43
|
+
# elements resulting from grouping)
|
44
|
+
#
|
45
|
+
# Example
|
46
|
+
#
|
47
|
+
# input_array: [[IP, HOUR, VISITS], [...]],
|
48
|
+
# row_key: 0
|
49
|
+
# col_key: 1
|
50
|
+
# cell: lambda { |x| x[2] }
|
51
|
+
#
|
52
|
+
# Will output:
|
53
|
+
#
|
54
|
+
# { IP => { HOUR => VISITS, HOUR => VISITS }, ... }
|
55
|
+
#
|
56
|
+
def pivot(input_data,
|
57
|
+
row_key,
|
58
|
+
col_key,
|
59
|
+
cell_maker = lambda { |x| x[0].last })
|
60
|
+
# here we build:
|
61
|
+
# "95.108.213.66"=>{12=>1, 18=>2, 19=>1, 20=>1, 5=>3, 6=>2, 7=>2, 3=>1},
|
62
|
+
#
|
63
|
+
# first transform: IP => [ HOUR => [[IP,HOUR,T], [IP,HOUR,T]] ]
|
64
|
+
# second transform: [IP,HOUR,T] -> T
|
65
|
+
input_data.group_by { |entry|
|
66
|
+
if row_key.class == Integer
|
67
|
+
entry[row_key]
|
68
|
+
else
|
69
|
+
row_key.call(entry)
|
70
|
+
end
|
71
|
+
}.transform_values { |rows|
|
72
|
+
rows.group_by { |cols|
|
73
|
+
if col_key.class == Integer
|
74
|
+
cols[col_key]
|
75
|
+
else
|
76
|
+
col_key.call(cols)
|
77
|
+
end
|
78
|
+
}.transform_values { |array|
|
79
|
+
cell_maker.call(array)
|
80
|
+
}
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
def session_report_spec(data)
|
85
|
+
{
|
86
|
+
title: "Sessions",
|
87
|
+
report: :html,
|
88
|
+
header: ["IP", "Days", "Date", "Visits", "Distinct URL", "URL List"],
|
89
|
+
column_alignment: %i[left left right right right right],
|
90
|
+
rows: data,
|
91
|
+
col: "small-12 cell"
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
def ip_per_hour_report_spec(data)
|
96
|
+
{
|
97
|
+
title: "IP per hour",
|
98
|
+
header: ["IP"] + (0..23).map { |hour| hour.to_s },
|
99
|
+
column_alignment: [:left] + [:right] * 24,
|
100
|
+
rows: data,
|
101
|
+
col: "small-12 cell"
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
2
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
3
|
+
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@300;700&display=swap" rel="stylesheet">
|
4
|
+
|
5
|
+
<% LogSense::Emitter::CDN_CSS.each do |link| %>
|
6
|
+
<link rel="stylesheet" type="text/css" href="<%= link %>">
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<% LogSense::Emitter::CDN_JS.each do |link| %>
|
10
|
+
<script type="text/javascript" src="<%= link %>"></script>
|
11
|
+
<% end %>
|
@@ -11,17 +11,23 @@
|
|
11
11
|
<%= data[:total_days] %>
|
12
12
|
<span class="stats-list-label">Days in Log</span>
|
13
13
|
</li>
|
14
|
+
<% if data[:log_size] %>
|
14
15
|
<li class="stats-list-negative">
|
15
16
|
<%= data[:log_size] %>
|
16
17
|
<span class="stats-list-label">Total Entries</span>
|
17
18
|
</li>
|
19
|
+
<% end %>
|
20
|
+
<% if data[:selfpolls_size] %>
|
18
21
|
<li class="stats-list-negative">
|
19
22
|
<%= data[:selfpolls_size] %>
|
20
23
|
<span class="stats-list-label">Self Polls</span>
|
21
24
|
</li>
|
22
|
-
|
25
|
+
<% end %>
|
26
|
+
<% if data[:crawlers] %>
|
27
|
+
<li class="stats-list-negative">
|
23
28
|
<td><%= data[:crawlers_size] %></td>
|
24
29
|
<span class="stats-list-label">Crawlers</span>
|
30
|
+
<% end %>
|
25
31
|
</li>
|
26
32
|
</ul>
|
27
33
|
|
@@ -54,7 +54,7 @@
|
|
54
54
|
data: 'IP',
|
55
55
|
className: '<%= Emitter::slugify("IP") %>',
|
56
56
|
render: function(data, type, row) {
|
57
|
-
// If display or filter data is requested, format the
|
57
|
+
// If display or filter data is requested, format the data
|
58
58
|
if ( type === 'display' || type === 'filter' ) {
|
59
59
|
return "<a target=\"_blank\" href=\"https://db-ip.com/" + data + "\">" + data + "</a>";
|
60
60
|
}
|
@@ -63,7 +63,11 @@
|
|
63
63
|
}
|
64
64
|
},
|
65
65
|
<% else -%>
|
66
|
-
{
|
66
|
+
{
|
67
|
+
data: '<%= header %>',
|
68
|
+
className: '<%= Emitter::slugify(header) %>',
|
69
|
+
render: DataTable.render.text()
|
70
|
+
},
|
67
71
|
<% end -%>
|
68
72
|
<% end -%>
|
69
73
|
]
|
@@ -11,12 +11,14 @@
|
|
11
11
|
<%= data[:total_days_in_analysis] %>
|
12
12
|
<span class="stats-list-label">Days</span>
|
13
13
|
</li>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
<% if data[:total_size] %>
|
15
|
+
<li class="stats-list-positive">
|
16
|
+
<%= data[:total_size] %>
|
17
|
+
<span class="stats-list-label">Data Transferred</span>
|
18
|
+
</li>
|
19
|
+
<% end %>
|
18
20
|
<li class="stats-list-negative">
|
19
|
-
<%= data[:
|
21
|
+
<%= data[:events] %>
|
20
22
|
<span class="stats-list-label">Hits</span>
|
21
23
|
</li>
|
22
24
|
<li class="stats-list-negative">
|
@@ -24,12 +26,12 @@
|
|
24
26
|
<span class="stats-list-label">Unique Visits</span>
|
25
27
|
</li>
|
26
28
|
<li class="stats-list-negative">
|
27
|
-
<% days = data[:
|
29
|
+
<% days = data[:total_days_in_analysis] %>
|
28
30
|
<%= days > 0 ? "%d" % (data[:total_unique_visits] / days) : "N/A" %>
|
29
31
|
<span class="stats-list-label">Unique Visits / Day</span>
|
30
32
|
</li>
|
31
33
|
<li class="stats-list-negative">
|
32
|
-
<%= data[:total_unique_visits] != 0 ? data[:
|
34
|
+
<%= data[:total_unique_visits] != 0 ? data[:events] / data[:total_unique_visits] : "N/A" %>
|
33
35
|
<span class="stats-list-label">Hits / Unique Visitor</span>
|
34
36
|
</li>
|
35
37
|
</ul>
|
@@ -3,10 +3,10 @@ table = Terminal::Table.new rows: [
|
|
3
3
|
["From", data[:first_day_in_analysis]],
|
4
4
|
["To", data[:last_day_in_analysis]],
|
5
5
|
["Days", data[:total_days_in_analysis]],
|
6
|
-
["Hits", data[:
|
6
|
+
["Hits", data[:events]],
|
7
7
|
["Unique Visits", data[:total_unique_visits]],
|
8
8
|
["Unique Visits / Day", data[:total_days_in_analysis] > 0 ? "%d" % (data[:total_unique_visits] / data[:total_days_in_analysis]) : "N/A"],
|
9
|
-
["Hits/Unique Visitor", data[:total_unique_visits] != 0 ? data[:
|
9
|
+
["Hits/Unique Visitor", data[:total_unique_visits] != 0 ? data[:events] / data[:total_unique_visits] : "N/A"]
|
10
10
|
]
|
11
11
|
table.style = { border_i: "|" }
|
12
12
|
table
|
@@ -1,42 +1,22 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<html class="no-js" lang="en">
|
3
3
|
<head>
|
4
|
-
<title>
|
5
|
-
<%= options[:title] || "Log Sense: #{data[:filenames].empty? ? "stdin" : data[:filenames].join(", ")}" %>
|
6
|
-
</title>
|
4
|
+
<title><%= @report_title %></title>
|
7
5
|
|
8
6
|
<meta charset="utf-8" />
|
9
7
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
10
8
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
11
9
|
|
12
10
|
<meta name="author" content="Shair.Tech">
|
13
|
-
<meta name="description"
|
11
|
+
<meta name="description"
|
12
|
+
content="Analysis of <%= @data[:filenames].join(', ') %>">
|
14
13
|
|
15
|
-
|
16
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
17
|
-
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@300;700&display=swap" rel="stylesheet">
|
18
|
-
|
19
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.min.css">
|
20
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/css/foundation.min.css">
|
21
|
-
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.css"/>
|
22
|
-
|
23
|
-
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
24
|
-
<script type="text/javascript" src="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.js"></script>
|
25
|
-
|
26
|
-
<script src="https://cdn.jsdelivr.net/npm/vega@5.21.0"></script>
|
27
|
-
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5.2.0"></script>
|
28
|
-
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6.20.2"></script>
|
14
|
+
<%= render "cdn_links.html.erb" %>
|
29
15
|
|
30
16
|
<style>
|
31
17
|
<%= render "stylesheet.css" %>
|
32
|
-
|
33
|
-
|
34
|
-
#offCanvas {
|
35
|
-
background: #d30001 !important;
|
36
|
-
}
|
37
|
-
h2 {
|
38
|
-
background: #d30001 !important;
|
39
|
-
}
|
18
|
+
|
19
|
+
<%= render @format_specific_css %>
|
40
20
|
</style>
|
41
21
|
</head>
|
42
22
|
|
@@ -44,7 +24,7 @@
|
|
44
24
|
<div class="off-canvas-wrapper">
|
45
25
|
<div class="off-canvas position-left" id="offCanvas" data-off-canvas>
|
46
26
|
<%= render "navigation.html.erb",
|
47
|
-
menus:
|
27
|
+
menus: @reports.map { |x| x[:title] } %>
|
48
28
|
</div>
|
49
29
|
<div class="off-canvas-content" data-off-canvas-content>
|
50
30
|
<button id="toggle-button" type="button" data-toggle="offCanvas">
|
@@ -52,24 +32,29 @@
|
|
52
32
|
</button>
|
53
33
|
|
54
34
|
<section class="main-section grid-container fluid">
|
55
|
-
<h1><%= options[:title] || "Log Sense
|
35
|
+
<h1><%= options[:title] || "Log Sense #{@report_title} Log Report" %></h1>
|
56
36
|
|
57
|
-
<p
|
37
|
+
<p>
|
38
|
+
<b>Input File(s):</b>
|
39
|
+
<%= @data[:filenames].empty? ? "stdin" : @data[:filenames].join(", ") %>
|
40
|
+
</p>
|
58
41
|
|
59
42
|
<div class="grid-x grid-padding-x">
|
60
43
|
<article class="small-12 large-6 cell">
|
61
44
|
<h2 id="<%= Emitter::slugify "Summary" %>">Summary</h2>
|
62
|
-
<%= render "summary.html.erb", data: data %>
|
45
|
+
<%= render "summary.html.erb", data: @data %>
|
63
46
|
</article>
|
64
47
|
|
65
48
|
<article class="small-12 large-6 cell">
|
66
49
|
<h2 id="<%= Emitter::slugify "Summary" %>">Log Structure</h2>
|
67
|
-
<%= render "log_structure.html.erb", data: data %>
|
50
|
+
<%= render "log_structure.html.erb", data: @data %>
|
68
51
|
</article>
|
69
52
|
|
70
53
|
<% @reports.each_with_index do |report, index| %>
|
71
54
|
<article class="cell <%= report[:col] || "small-12 large-6" %>" >
|
72
|
-
<h2 id="<%= Emitter::slugify report[:title] %>"
|
55
|
+
<h2 id="<%= Emitter::slugify report[:title] %>">
|
56
|
+
<%= report[:title] %>
|
57
|
+
</h2>
|
73
58
|
|
74
59
|
<%= render "report_data.html.erb", report: report, index: index %>
|
75
60
|
<% if report[:vega_spec] %>
|
@@ -95,21 +80,18 @@
|
|
95
80
|
|
96
81
|
<article class="small-12 large-6 cell">
|
97
82
|
<h2 id="<%= Emitter::slugify "Command Invocation" %>">Command Invocation</h2>
|
98
|
-
<%= render "command_invocation.html.erb", data: data, options: options %>
|
83
|
+
<%= render "command_invocation.html.erb", data: @data, options: options %>
|
99
84
|
</article>
|
100
85
|
|
101
86
|
<article class="small-12 large-6 cell">
|
102
87
|
<h2 id="<%= Emitter::slugify "Performance" %>">Performance</h2>
|
103
|
-
<%= render "performance.html.erb", data: data %>
|
88
|
+
<%= render "performance.html.erb", data: @data %>
|
104
89
|
</article>
|
105
90
|
</div>
|
106
91
|
</section>
|
107
92
|
</div>
|
108
93
|
</div>
|
109
94
|
|
110
|
-
<script type="text/javascript" src="js/vendor/what-input.js"></script>
|
111
|
-
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
|
112
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/js/foundation.min.js" crossorigin="anonymous"></script>
|
113
95
|
<script>
|
114
96
|
$(document).foundation();
|
115
97
|
|
data/lib/log_sense/version.rb
CHANGED
data/lib/log_sense.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
6
|
-
require
|
7
|
-
require
|
8
|
-
|
9
|
-
require
|
1
|
+
require "log_sense/version"
|
2
|
+
|
3
|
+
require "log_sense/options_parser"
|
4
|
+
require "log_sense/options_checker"
|
5
|
+
|
6
|
+
require "log_sense/apache_log_parser"
|
7
|
+
require "log_sense/rails_log_parser"
|
8
|
+
|
9
|
+
require "log_sense/aggregator"
|
10
|
+
require "log_sense/apache_aggregator"
|
11
|
+
require "log_sense/rails_aggregator"
|
12
|
+
|
13
|
+
require "log_sense/ip_locator"
|
14
|
+
|
15
|
+
require "log_sense/report_shaper"
|
16
|
+
require "log_sense/apache_report_shaper"
|
17
|
+
require "log_sense/rails_report_shaper"
|
18
|
+
|
19
|
+
require "log_sense/emitter"
|
data/log_sense.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
|
9
9
|
spec.summary = %q{Generate analytics for Apache and Rails log file.}
|
10
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/
|
11
|
+
spec.homepage = "https://github.com/shair-tech/log_sense/"
|
12
12
|
spec.license = "MIT"
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.9")
|
14
14
|
|
File without changes
|
Binary file
|