log_sense 2.0.0 → 2.2.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 +23 -12
- data/Gemfile.lock +1 -1
- data/README.org +4 -3
- data/exe/log_sense +2 -0
- data/ip_locations/dbip-country-lite.sqlite3 +0 -0
- data/lib/log_sense/apache_aggregator.rb +1 -1
- data/lib/log_sense/emitter.rb +9 -0
- data/lib/log_sense/rails/log_parser.rb +373 -154
- data/lib/log_sense/rails_aggregator.rb +68 -39
- data/lib/log_sense/rails_report_shaper.rb +92 -35
- data/lib/log_sense/report_shaper.rb +9 -3
- data/lib/log_sense/templates/_output_table.html.erb +13 -16
- data/lib/log_sense/templates/_stylesheet.css +20 -1
- data/lib/log_sense/templates/report_html.erb +4 -0
- data/lib/log_sense/templates/world.svg +1 -1
- data/lib/log_sense/version.rb +1 -1
- data/todo.org +27 -3
- metadata +2 -2
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
module LogSense
|
|
2
2
|
class RailsAggregator < Aggregator
|
|
3
|
+
WORDS_SEPARATOR = ' · '
|
|
4
|
+
|
|
3
5
|
def initialize(db, options = { limit: 900 })
|
|
4
6
|
@table = "Event"
|
|
5
7
|
@date_field = "started_at"
|
|
@@ -76,6 +78,7 @@ module LogSense
|
|
|
76
78
|
sum(iif(platform != 'ios' and platform != 'android' and platform != 'mac' and platform != 'windows' and platform != 'linux', 1, 0)) as Other,
|
|
77
79
|
count(distinct(id)) as Total
|
|
78
80
|
from BrowserInfo
|
|
81
|
+
where #{filter}
|
|
79
82
|
group by controller, method, request_format
|
|
80
83
|
)
|
|
81
84
|
|
|
@@ -86,6 +89,7 @@ module LogSense
|
|
|
86
89
|
SELECT browser as Browser,
|
|
87
90
|
count(distinct(id)) as Visits
|
|
88
91
|
from BrowserInfo
|
|
92
|
+
where #{filter}
|
|
89
93
|
group by browser
|
|
90
94
|
)
|
|
91
95
|
|
|
@@ -93,58 +97,83 @@ module LogSense
|
|
|
93
97
|
SELECT platform as Platform,
|
|
94
98
|
count(distinct(id)) as Visits
|
|
95
99
|
from BrowserInfo
|
|
100
|
+
where #{filter}
|
|
96
101
|
group by platform
|
|
97
102
|
)
|
|
98
103
|
|
|
99
|
-
@
|
|
104
|
+
@fatal_plot = @db.execute %(
|
|
105
|
+
SELECT strftime("%Y-%m-%d", started_at) as Day,
|
|
106
|
+
sum(distinct(event.id)) as Errors,
|
|
107
|
+
sum(iif(context LIKE '%ActionController::RoutingError%', 1, 0)) as RoutingErrors,
|
|
108
|
+
sum(iif(context NOT LIKE '%ActionController::RoutingError%', 1, 0)) as OtherErrors
|
|
109
|
+
FROM Event JOIN Error
|
|
110
|
+
ON event.log_id == error.log_id
|
|
111
|
+
WHERE #{filter} and exit_status == 'F'
|
|
112
|
+
GROUP BY strftime("%Y-%m-%d", started_at)
|
|
113
|
+
).gsub("\n", "") || [[]]
|
|
114
|
+
|
|
115
|
+
@fatal = @db.execute %(
|
|
100
116
|
SELECT strftime("%Y-%m-%d %H:%M", started_at),
|
|
101
117
|
ip,
|
|
102
118
|
url,
|
|
103
|
-
|
|
119
|
+
context,
|
|
120
|
+
description,
|
|
104
121
|
event.log_id
|
|
105
122
|
FROM Event JOIN Error
|
|
106
123
|
ON event.log_id == error.log_id
|
|
107
|
-
WHERE #{filter} and exit_status == 'F').gsub("\n", "") || [[]]
|
|
108
|
-
|
|
109
|
-
@fatal_plot = @db.execute %Q(
|
|
110
|
-
SELECT strftime("%Y-%m-%d", started_at) as Day,
|
|
111
|
-
count(distinct(event.id)) as Errors
|
|
112
|
-
FROM Event JOIN Error
|
|
113
|
-
ON event.log_id == error.log_id
|
|
114
124
|
WHERE #{filter} and exit_status == 'F'
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
@
|
|
118
|
-
SELECT strftime("%Y-%m-%d %H:%M", started_at), status, ip, url,
|
|
119
|
-
error.description,
|
|
120
|
-
event.log_id
|
|
121
|
-
FROM Event JOIN Error
|
|
122
|
-
ON event.log_id == error.log_id
|
|
123
|
-
WHERE #{filter} and substr(status, 1, 1) == '5').gsub("\n", "") || [[]]
|
|
124
|
-
|
|
125
|
-
@internal_server_error_plot = @db.execute %Q(
|
|
126
|
-
SELECT strftime('%Y-%m-%d', started_at) as Day,
|
|
127
|
-
count(distinct(event.id)) as Errors
|
|
128
|
-
FROM Event JOIN Error
|
|
129
|
-
ON event.log_id == error.log_id
|
|
130
|
-
WHERE #{filter} and substr(status, 1, 1) == '5'
|
|
131
|
-
GROUP BY strftime('%Y-%m-%d', started_at)).gsub("\n", "") || [[]]
|
|
132
|
-
|
|
133
|
-
@error = @db.execute %Q(
|
|
125
|
+
).gsub("\n", "") || [[]]
|
|
126
|
+
|
|
127
|
+
@fatal_grouped = @db.execute %(
|
|
134
128
|
SELECT filename,
|
|
135
|
-
log_id,
|
|
129
|
+
group_concat(log_id, '#{WORDS_SEPARATOR}'),
|
|
130
|
+
context,
|
|
131
|
+
description,
|
|
132
|
+
count(distinct(error.id))
|
|
136
133
|
FROM Error
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
GROUP BY description).gsub("\n", "") || [[]]
|
|
134
|
+
GROUP BY description
|
|
135
|
+
).gsub("\n", "") || [[]]
|
|
140
136
|
|
|
141
|
-
@
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
137
|
+
@job_plot = @db.execute %(
|
|
138
|
+
SELECT strftime("%Y-%m-%d", ended_at) as Day,
|
|
139
|
+
sum(iif(exit_status == 'C', 1, 0)) as Completed,
|
|
140
|
+
sum(iif(exit_status == 'E', 1, 0)) as Errors
|
|
141
|
+
FROM Job
|
|
142
|
+
WHERE #{filter}
|
|
143
|
+
GROUP BY strftime("%Y-%m-%d", ended_at)
|
|
144
|
+
).gsub("\n", "") || [[]]
|
|
145
|
+
|
|
146
|
+
# worker,
|
|
147
|
+
# host,
|
|
148
|
+
# pid,
|
|
149
|
+
@jobs = @db.execute %(
|
|
150
|
+
SELECT strftime("%Y-%m-%d %H:%M", started_at),
|
|
151
|
+
duration_total_ms,
|
|
152
|
+
pid,
|
|
153
|
+
object_id,
|
|
154
|
+
exit_status,
|
|
155
|
+
method,
|
|
156
|
+
arguments,
|
|
157
|
+
error_msg,
|
|
158
|
+
attempt
|
|
159
|
+
FROM Job
|
|
160
|
+
WHERE #{filter}
|
|
161
|
+
).gsub("\n", "") || [[]]
|
|
162
|
+
|
|
163
|
+
@job_error_grouped = @db.execute %(
|
|
164
|
+
SELECT worker,
|
|
165
|
+
host,
|
|
166
|
+
pid,
|
|
167
|
+
exit_status,
|
|
168
|
+
object_id,
|
|
169
|
+
GROUP_CONCAT(DISTINCT(error_msg)),
|
|
170
|
+
method,
|
|
171
|
+
arguments,
|
|
172
|
+
max(attempt)
|
|
173
|
+
FROM Job
|
|
174
|
+
WHERE #{filter} and exit_status == 'E'
|
|
175
|
+
GROUP BY object_id
|
|
176
|
+
).gsub("\n", "") || [[]]
|
|
148
177
|
|
|
149
178
|
instance_vars_to_hash
|
|
150
179
|
end
|
|
@@ -48,27 +48,51 @@ module LogSense
|
|
|
48
48
|
column_alignment: %i[left right right right right],
|
|
49
49
|
rows: data[:performance],
|
|
50
50
|
col: "small-12 cell",
|
|
51
|
-
echarts_height: "
|
|
51
|
+
echarts_height: "800px",
|
|
52
52
|
echarts_spec: "{
|
|
53
53
|
xAxis: {
|
|
54
|
+
name: 'Hits',
|
|
55
|
+
type: 'value',
|
|
56
|
+
minInterval: 1,
|
|
57
|
+
axisLabel: {
|
|
58
|
+
formatter: function(val) {
|
|
59
|
+
return val.toFixed(0);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
54
62
|
},
|
|
55
63
|
yAxis: {
|
|
64
|
+
name: 'Average Time',
|
|
65
|
+
type: 'value',
|
|
66
|
+
axisLabel: {
|
|
67
|
+
formatter: function(val) {
|
|
68
|
+
return val.toFixed(0) + ' ms';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
56
71
|
},
|
|
57
72
|
tooltip: {
|
|
58
|
-
trigger: '
|
|
73
|
+
trigger: 'item',
|
|
74
|
+
formatter: function(params) {
|
|
75
|
+
var index = params.dataIndex
|
|
76
|
+
var row = SERIES_DATA[index]
|
|
77
|
+
var controller = row['Controller']
|
|
78
|
+
var hits = Number(params.value[0]).toFixed(0).toLocaleString('en')
|
|
79
|
+
var average = Number(params.value[1]).toFixed(0).toLocaleString('en') + ' ms'
|
|
80
|
+
return `<b>${controller}</b><br/>Hits: ${hits}<br>Average Time: ${average}`;
|
|
81
|
+
}
|
|
59
82
|
},
|
|
60
83
|
series: [
|
|
61
84
|
{
|
|
62
|
-
data: SERIES_DATA.map(row => [row['
|
|
85
|
+
data: SERIES_DATA.map(row => [row['Hits'], row['Avg']]),
|
|
63
86
|
type: 'scatter',
|
|
64
87
|
color: '#D30001',
|
|
65
88
|
label: {
|
|
66
89
|
show: true,
|
|
67
90
|
position: 'right',
|
|
68
|
-
formatter: function
|
|
91
|
+
formatter: function(params) {
|
|
69
92
|
var row = SERIES_DATA[params.dataIndex]
|
|
70
|
-
return row['Controller']
|
|
71
|
-
|
|
93
|
+
return row['Controller'];
|
|
94
|
+
// +
|
|
95
|
+
// ':\\n(' + row['Hits'] + ', ' + row['Avg'] + ')';
|
|
72
96
|
}
|
|
73
97
|
},
|
|
74
98
|
}
|
|
@@ -125,8 +149,9 @@ module LogSense
|
|
|
125
149
|
},
|
|
126
150
|
{
|
|
127
151
|
title: "Fatal Events",
|
|
128
|
-
header: %w[Date IP URL Description
|
|
129
|
-
column_alignment: %i[left left left left left],
|
|
152
|
+
header: %w[Date IP URL Context Description ID],
|
|
153
|
+
column_alignment: %i[left left left left left left],
|
|
154
|
+
column_width: ["10%", "10%", "20%", "10%", "30%", "20%"],
|
|
130
155
|
rows: data[:fatal],
|
|
131
156
|
col: "small-12 cell",
|
|
132
157
|
echarts_extra: "var fatal_plot=#{data[:fatal_plot].to_json}",
|
|
@@ -154,7 +179,18 @@ module LogSense
|
|
|
154
179
|
},
|
|
155
180
|
series: [
|
|
156
181
|
{
|
|
157
|
-
|
|
182
|
+
name: 'Routing Errors',
|
|
183
|
+
data: fatal_plot.filter(row => row[0] != '').map(row => row[2]),
|
|
184
|
+
type: 'bar',
|
|
185
|
+
color: '#D0D0D0',
|
|
186
|
+
label: {
|
|
187
|
+
show: true,
|
|
188
|
+
position: 'top'
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: 'Other Errors',
|
|
193
|
+
data: fatal_plot.filter(row => row[0] != '').map(row => row[3]),
|
|
158
194
|
type: 'bar',
|
|
159
195
|
color: '#D30001',
|
|
160
196
|
label: {
|
|
@@ -166,12 +202,34 @@ module LogSense
|
|
|
166
202
|
};"
|
|
167
203
|
},
|
|
168
204
|
{
|
|
169
|
-
title: "
|
|
170
|
-
header: %w[
|
|
171
|
-
column_alignment: %i[left left left left
|
|
172
|
-
|
|
205
|
+
title: "Fatal Events (grouped by type)",
|
|
206
|
+
header: %w[Log ID Context Description Count],
|
|
207
|
+
column_alignment: %i[left left left left right],
|
|
208
|
+
column_width: ["10%", "20%", "10%", "60%", "5%"],
|
|
209
|
+
rows: data[:fatal_grouped],
|
|
210
|
+
col: "small-12 cell"
|
|
211
|
+
},
|
|
212
|
+
browsers(data),
|
|
213
|
+
platforms(data),
|
|
214
|
+
ips(data),
|
|
215
|
+
countries(data),
|
|
216
|
+
ip_per_hour_report_spec(ips_per_hour(data[:ips_per_hour])),
|
|
217
|
+
session_report_spec(ips_detailed(data[:ips_per_day_detailed])),
|
|
218
|
+
{
|
|
219
|
+
title: "Jobs (Completed and Failed)",
|
|
220
|
+
explanation: %(
|
|
221
|
+
This report includes completed and failed jobs, parsing lines
|
|
222
|
+
marked as COMPLETED or ERROR/FAILED.
|
|
223
|
+
|
|
224
|
+
This excludes from the table entries marked as RUNNING and then
|
|
225
|
+
completed with "performed".
|
|
226
|
+
),
|
|
227
|
+
header: %w[Date Duration PID ID Exit_Status Method Arguments Error_Msg Attempts],
|
|
228
|
+
column_alignment: %i[left left right left left left left left right],
|
|
229
|
+
column_width: ["10%", "5%", "5%", "5%", "5%", "15%", "25%", "25%", "5%"],
|
|
230
|
+
rows: data[:jobs],
|
|
173
231
|
col: "small-12 cell",
|
|
174
|
-
echarts_extra: "var
|
|
232
|
+
echarts_extra: "var fatal_plot=#{data[:job_plot].to_json}",
|
|
175
233
|
echarts_spec: "{
|
|
176
234
|
toolbox: {
|
|
177
235
|
feature: {
|
|
@@ -183,7 +241,7 @@ module LogSense
|
|
|
183
241
|
},
|
|
184
242
|
xAxis: {
|
|
185
243
|
type: 'category',
|
|
186
|
-
data:
|
|
244
|
+
data: fatal_plot.filter(row => row[0] != '').map(row => row[0]),
|
|
187
245
|
showGrid: true,
|
|
188
246
|
axisLabel: {
|
|
189
247
|
rotate: 45 // Rotate the labels
|
|
@@ -196,37 +254,36 @@ module LogSense
|
|
|
196
254
|
},
|
|
197
255
|
series: [
|
|
198
256
|
{
|
|
199
|
-
|
|
257
|
+
name: 'Completed',
|
|
258
|
+
data: fatal_plot.filter(row => row[0] != '').map(row => row[1]),
|
|
200
259
|
type: 'bar',
|
|
201
|
-
color: '#
|
|
260
|
+
color: '#D0D0D0',
|
|
202
261
|
label: {
|
|
203
262
|
show: true,
|
|
204
263
|
position: 'top'
|
|
205
264
|
},
|
|
206
265
|
},
|
|
266
|
+
{
|
|
267
|
+
name: 'Errors',
|
|
268
|
+
data: fatal_plot.filter(row => row[0] != '').map(row => row[2]),
|
|
269
|
+
type: 'bar',
|
|
270
|
+
color: '#D30001',
|
|
271
|
+
label: {
|
|
272
|
+
show: true,
|
|
273
|
+
position: 'top'
|
|
274
|
+
},
|
|
275
|
+
}
|
|
207
276
|
]
|
|
208
277
|
};"
|
|
209
278
|
},
|
|
210
279
|
{
|
|
211
|
-
title: "Errors",
|
|
212
|
-
header: %w[
|
|
213
|
-
column_alignment: %i[left left left right],
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
title: "Potential Attacks",
|
|
219
|
-
header: %w[Log ID Description Count],
|
|
220
|
-
column_alignment: %i[left left left right],
|
|
221
|
-
rows: data[:possible_attacks],
|
|
280
|
+
title: "Job Errors (grouped)",
|
|
281
|
+
header: %w[Worker Host PID ID Error Method Arguments Attempts],
|
|
282
|
+
column_alignment: %i[left left left left left left left right],
|
|
283
|
+
column_width: ["5%", "5%", "5%", "5%", "20%", "30%", "20%", "10%"],
|
|
284
|
+
rows: data[:job_error_grouped],
|
|
222
285
|
col: "small-12 cell"
|
|
223
|
-
}
|
|
224
|
-
browsers(data),
|
|
225
|
-
platforms(data),
|
|
226
|
-
ips(data),
|
|
227
|
-
countries(data),
|
|
228
|
-
ip_per_hour_report_spec(ips_per_hour(data[:ips_per_hour])),
|
|
229
|
-
session_report_spec(ips_detailed(data[:ips_per_day_detailed]))
|
|
286
|
+
}
|
|
230
287
|
]
|
|
231
288
|
end
|
|
232
289
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
module LogSense
|
|
2
2
|
class ReportShaper
|
|
3
|
+
SESSION_URL_LIMIT = 300
|
|
3
4
|
WORDS_SEPARATOR = ' · '
|
|
4
5
|
|
|
5
6
|
# return { [ip,day] => { [ hits, list of urls ] } }
|
|
@@ -14,7 +15,11 @@ module LogSense
|
|
|
14
15
|
date,
|
|
15
16
|
hash[ip][date].size,
|
|
16
17
|
hash[ip][date].uniq.size,
|
|
17
|
-
hash[ip][date].uniq.size <
|
|
18
|
+
if hash[ip][date].uniq.size < SESSION_URL_LIMIT
|
|
19
|
+
hash[ip][date].uniq.join(WORDS_SEPARATOR)
|
|
20
|
+
else
|
|
21
|
+
"[too many]"
|
|
22
|
+
end
|
|
18
23
|
]
|
|
19
24
|
end
|
|
20
25
|
end
|
|
@@ -277,7 +282,7 @@ module LogSense
|
|
|
277
282
|
title: "Sessions",
|
|
278
283
|
report: :html,
|
|
279
284
|
header: ["IP", "Days", "Date", "Visits", "Distinct URL", "URL List"],
|
|
280
|
-
column_alignment: %i[left left right right right
|
|
285
|
+
column_alignment: %i[left left right right right left],
|
|
281
286
|
rows: data,
|
|
282
287
|
col: "small-12 cell"
|
|
283
288
|
}
|
|
@@ -288,6 +293,7 @@ module LogSense
|
|
|
288
293
|
title: "IP per hour",
|
|
289
294
|
header: ["IP"] + (0..23).map { |hour| hour.to_s },
|
|
290
295
|
column_alignment: %i[left] + (%i[right] * 24),
|
|
296
|
+
column_width: ["10%"] + (["3.75%"] * 24),
|
|
291
297
|
rows: data,
|
|
292
298
|
col: "small-12 cell"
|
|
293
299
|
}
|
|
@@ -419,7 +425,7 @@ module LogSense
|
|
|
419
425
|
max = country_and_hits.map { |x| x[1] }.max
|
|
420
426
|
|
|
421
427
|
country_and_hits.map do |element|
|
|
422
|
-
underscored = (element[0] || "").gsub(" ", "_")
|
|
428
|
+
underscored = (element[0] || "").gsub(" ", "_").gsub(/[()]/, "")
|
|
423
429
|
bin = bin(element[1], max:)
|
|
424
430
|
<<-EOS
|
|
425
431
|
/* bin: #{bin} */
|
|
@@ -16,15 +16,20 @@
|
|
|
16
16
|
pageLength: 25,
|
|
17
17
|
<%= report[:datatable_options] + "," if report[:datatable_options] %>
|
|
18
18
|
columns: [
|
|
19
|
-
<% report[:header].
|
|
20
|
-
<% if header == "Size" -%>
|
|
19
|
+
<% report[:header].each_with_index do |header, index| %>
|
|
21
20
|
{
|
|
22
|
-
data: '
|
|
23
|
-
className: '<%= Emitter::slugify(
|
|
21
|
+
data: '<%= header %>',
|
|
22
|
+
className: '<%= Emitter::slugify(header) %> <%= Emitter.alignment_class(report, index) %>',
|
|
23
|
+
<% if report[:column_width] %>
|
|
24
|
+
width: '<%= report[:column_width][index] %>',
|
|
25
|
+
<% end %>
|
|
26
|
+
|
|
27
|
+
<%# USE A SPECIFIC RENDERER FOR SOME TYPES OF COLUMNS %>
|
|
28
|
+
<% if header == "Size" -%>
|
|
24
29
|
render: function(data, type, row) {
|
|
25
30
|
// If display or filter data is requested, format the date
|
|
26
31
|
if ( type === 'display' || type === 'filter' ) {
|
|
27
|
-
|
|
32
|
+
return data;
|
|
28
33
|
}
|
|
29
34
|
// Otherwise the data type requested (`type`) is type detection or
|
|
30
35
|
// sorting data, for which we want to use an integer value
|
|
@@ -48,11 +53,7 @@
|
|
|
48
53
|
}
|
|
49
54
|
return size * multiplier;
|
|
50
55
|
}
|
|
51
|
-
|
|
52
|
-
<% elsif header == "IP" -%>
|
|
53
|
-
{
|
|
54
|
-
data: 'IP',
|
|
55
|
-
className: '<%= Emitter::slugify("IP") %>',
|
|
56
|
+
<% elsif header == "IP" -%>
|
|
56
57
|
render: function(data, type, row) {
|
|
57
58
|
// If display or filter data is requested, format the data
|
|
58
59
|
if ( type === 'display' || type === 'filter' ) {
|
|
@@ -61,15 +62,11 @@
|
|
|
61
62
|
// For any other purpose return data
|
|
62
63
|
return data;
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
-
<% else -%>
|
|
66
|
-
{
|
|
67
|
-
data: '<%= header %>',
|
|
68
|
-
className: '<%= Emitter::slugify(header) %>',
|
|
65
|
+
<% else -%>
|
|
69
66
|
render: DataTable.render.text()
|
|
67
|
+
<% end -%>
|
|
70
68
|
},
|
|
71
69
|
<% end -%>
|
|
72
|
-
<% end -%>
|
|
73
70
|
]
|
|
74
71
|
});
|
|
75
72
|
});
|
|
@@ -85,6 +85,12 @@ h2 {
|
|
|
85
85
|
background: var(--background-color);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
table {
|
|
89
|
+
width: 100% !important;
|
|
90
|
+
/* table-layout: fixed !important;*/
|
|
91
|
+
word-wrap: break-word;
|
|
92
|
+
}
|
|
93
|
+
|
|
88
94
|
table thead, table tbody, table tfoot {
|
|
89
95
|
border-color: var(--row-border) !important;
|
|
90
96
|
}
|
|
@@ -174,7 +180,16 @@ ul.pagination, li.paginate_button {
|
|
|
174
180
|
font-weight: normal;
|
|
175
181
|
}
|
|
176
182
|
|
|
177
|
-
|
|
183
|
+
/* datatable resists aligment directives. We make them important */
|
|
184
|
+
.text-left {
|
|
185
|
+
text-align: left !important;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.text-center {
|
|
189
|
+
text-align: center !important;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.text-right {
|
|
178
193
|
text-align: right !important;
|
|
179
194
|
}
|
|
180
195
|
|
|
@@ -182,3 +197,7 @@ td {
|
|
|
182
197
|
vertical-align: top;
|
|
183
198
|
}
|
|
184
199
|
|
|
200
|
+
.url {
|
|
201
|
+
overflow: hidden;
|
|
202
|
+
text-overflow: ellipsis;
|
|
203
|
+
}
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
<% if report[:rows] %>
|
|
62
62
|
<%= render "report_data.html.erb", report: report, index: index %>
|
|
63
63
|
<% end %>
|
|
64
|
+
|
|
64
65
|
<% if report[:vega_spec] %>
|
|
65
66
|
<div id="<%= "plot-#{index}" %>" class="plot-canvas">
|
|
66
67
|
</div>
|
|
@@ -78,6 +79,7 @@
|
|
|
78
79
|
vegaEmbed('#<%= "plot-#{index}"%>', plot_spec_<%= index %>);
|
|
79
80
|
</script>
|
|
80
81
|
<% end %>
|
|
82
|
+
|
|
81
83
|
<% if report[:echarts_spec] %>
|
|
82
84
|
<% height = report[:echarts_height] || "400px"%>
|
|
83
85
|
<div id="<%= "echart-#{index}" %>" style="width: 100%;height: <%= height %>;"></div>
|
|
@@ -91,12 +93,14 @@
|
|
|
91
93
|
|
|
92
94
|
</script>
|
|
93
95
|
<% end %>
|
|
96
|
+
|
|
94
97
|
<% if report[:raw_html] %>
|
|
95
98
|
<% height = report[:raw_html_height] || "400px"%>
|
|
96
99
|
<div id="raw-html-#{index}" style="width: 100%;height: <%= height %>">
|
|
97
100
|
<%= report[:raw_html] %>
|
|
98
101
|
</div>
|
|
99
102
|
<% end %>
|
|
103
|
+
|
|
100
104
|
<% if report[:rows] %>
|
|
101
105
|
<%= render "output_table.html.erb", report: report, index: index %>
|
|
102
106
|
<% end %>
|
|
@@ -312,7 +312,7 @@ THE SOFTWARE.
|
|
|
312
312
|
</path>
|
|
313
313
|
<path d="M974.8 276l1.9 4.1 0.3 3.9 1.9 6.8 1.4 1.4-1 2.5-7.1 1.1-2.5 2.3-3.1 0.6-0.3 4.8-6.4 2.5-2.1 3.2-4.5 1.7-5.4 1-8.9 4.8-0.1 7.6-0.9 0 0.1 3.4-3.4 0.2-1.8 1.5-2.5 0-2-0.9-4.6 0.7-1.9 5-1.8 0.5-2.7 8.1-7.9 6.9-2 8.9-2.4 2.9-0.7 2.3-12.5 0.5-0.1 0 0.3-3 2.2-1.7 1.9-3.4-0.3-2.2 2-4.5 3.2-4.1 1.9-1 1.6-3.7 0.2-3.5 2.1-3.9 3.8-2.4 3.6-6.5 0.1-0.1 2.9-2.5 5.1-0.7 4.4-4.4 2.8-1.7 4.7-5.4-1.2-7.9 2.2-5.6 0.9-3.4 3.6-4.3 5.4-2.9 4.1-2.7 3.7-6.6 1.8-4 3.9 0.1 3.1 2.7 5.1-0.4 5.5 1.4 2.4 0z" id="MA" name="Morocco">
|
|
314
314
|
</path>
|
|
315
|
-
<path d="M1129.4 210.3l-1.3-2.9 0.2-2.7-0.6-2.7-3.4-3.8-2-2.6-1.8-1.8-1.6-0.7 1.1-0.9 3.2-0.6 4 1.9 2 0.3 2.6 1.7-0.1 2.1 2 1 1.1 2.6 2 1.6-0.2 1 1 0.6-1.3 0.5-3-0.2-0.6-0.9-1 0.5 0.6 1.1-1.1 2.1-0.6 2.1-1.2 0.7z" id="MD" name="
|
|
315
|
+
<path d="M1129.4 210.3l-1.3-2.9 0.2-2.7-0.6-2.7-3.4-3.8-2-2.6-1.8-1.8-1.6-0.7 1.1-0.9 3.2-0.6 4 1.9 2 0.3 2.6 1.7-0.1 2.1 2 1 1.1 2.6 2 1.6-0.2 1 1 0.6-1.3 0.5-3-0.2-0.6-0.9-1 0.5 0.6 1.1-1.1 2.1-0.6 2.1-1.2 0.7z" id="MD" name="Moldova_Republic_of">
|
|
316
316
|
</path>
|
|
317
317
|
<path d="M1267.9 588.9l0.4 7.7 1.3 3-0.7 3.1-1.2 1.8-1.6-3.7-1.2 1.9 0.8 4.7-0.7 2.8-1.7 1.4-0.7 5.5-2.7 7.5-3.4 8.8-4.3 12.2-2.9 8.9-3.1 7.5-4.6 1.5-5.1 2.7-3-1.6-4.2-2.3-1.2-3.4 0-5.7-1.5-5.1-0.2-4.7 1.3-4.6 2.6-1.1 0.2-2.1 2.9-4.9 0.8-4.1-1.1-3-0.8-4.1-0.1-5.9 2.2-3.6 1-4.1 2.8-0.2 3.2-1.3 2.2-1.2 2.4-0.1 3.4-3.6 4.9-4 1.8-3.2-0.6-2.8 2.4 0.8 3.3-4.4 0.3-3.9 2-2.9 1.8 2.8 1.4 2.7 1.2 4.3z" id="MG" name="Madagascar">
|
|
318
318
|
</path>
|
data/lib/log_sense/version.rb
CHANGED
data/todo.org
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
* Todo (2024-08-01)
|
|
4
4
|
|
|
5
|
+
** T Break rails log_parser in subclasses (one per log type)
|
|
6
|
+
|
|
7
|
+
** T Distinguish between exceptions, errors with no timestamps and errors with timestamps :feature:
|
|
8
|
+
- In rails reports some errors don't have a timestamp, whereas other have.
|
|
9
|
+
|
|
10
|
+
1. Check whether we can always get an ID of an event
|
|
11
|
+
|
|
5
12
|
** T Move geolocation to aggregator, so that we can perform queries more efficiently :refactoring:
|
|
6
13
|
** T Filter on dates :feature:
|
|
7
14
|
** T Visits/Hits :feature:
|
|
@@ -11,9 +18,7 @@
|
|
|
11
18
|
** T error on data
|
|
12
19
|
- The data reported by echarts on the number of hits of a controller
|
|
13
20
|
differs from the data shown in the table?
|
|
14
|
-
** T
|
|
15
|
-
** T Dark style
|
|
16
|
-
** T Remove dependency from Zurb Foundation (native css grid instead)
|
|
21
|
+
** T Remove dependency from Zurb Foundation (native css grid instead) :refactoring:
|
|
17
22
|
** T refactor report specifications in their own class :refactoring:
|
|
18
23
|
** T Add lines not parsed to the report :feature:
|
|
19
24
|
** T Using an empty log as input raises an error :feature:
|
|
@@ -307,3 +312,22 @@
|
|
|
307
312
|
:ARCHIVE_CATEGORY: todo
|
|
308
313
|
:ARCHIVE_TODO: REJECTED
|
|
309
314
|
:END:
|
|
315
|
+
|
|
316
|
+
** D Dark style
|
|
317
|
+
:PROPERTIES:
|
|
318
|
+
:ARCHIVE_TIME: 2024-08-23 Fri 16:25
|
|
319
|
+
:ARCHIVE_FILE: ~/Sources/ruby/log_sense/todo.org
|
|
320
|
+
:ARCHIVE_OLPATH: Todo (2024-08-01)
|
|
321
|
+
:ARCHIVE_CATEGORY: todo
|
|
322
|
+
:ARCHIVE_TODO: D
|
|
323
|
+
:END:
|
|
324
|
+
|
|
325
|
+
** D Sidebar foreground color in new apache report
|
|
326
|
+
:PROPERTIES:
|
|
327
|
+
:ARCHIVE_TIME: 2024-08-23 Fri 16:25
|
|
328
|
+
:ARCHIVE_FILE: ~/Sources/ruby/log_sense/todo.org
|
|
329
|
+
:ARCHIVE_OLPATH: Todo (2024-08-01)
|
|
330
|
+
:ARCHIVE_CATEGORY: todo
|
|
331
|
+
:ARCHIVE_TODO: D
|
|
332
|
+
:END:
|
|
333
|
+
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: log_sense
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adolfo Villafiorita
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-08-
|
|
11
|
+
date: 2024-08-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: browser
|