log_sense 1.9.0 → 2.0.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.
@@ -64,38 +64,12 @@ module LogSense
64
64
  }
65
65
  ",
66
66
  },
67
- {
68
- title: "Time Distribution",
67
+ time_distribution(
68
+ data,
69
69
  header: %w[Hour Hits Visits Size],
70
70
  column_alignment: %i[left right right right],
71
- rows: data[:time_distribution],
72
- echarts_spec: "{
73
- xAxis: {
74
- type: 'category',
75
- data: SERIES_DATA.map(row => row['Hour'])
76
- /* data: ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
77
- '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',
78
- '20', '21', '22', '23', '24'] */
79
- },
80
- yAxis: {
81
- type: 'value'
82
- },
83
- tooltip: {
84
- trigger: 'axis'
85
- },
86
- series: [
87
- {
88
- data: SERIES_DATA.map(row => row['Hits']),
89
- type: 'bar',
90
- color: '#4C78A8',
91
- label: {
92
- show: true,
93
- position: 'top'
94
- },
95
- }
96
- ]
97
- }",
98
- },
71
+ color: "#4C78A8"
72
+ ),
99
73
  {
100
74
  title: "20_ and 30_ on HTML pages",
101
75
  header: %w[Path Hits Visits Size Status],
@@ -154,242 +128,27 @@ module LogSense
154
128
  ]
155
129
  }&.sort { |x, y| y[1] <=> x[1] }
156
130
  },
157
- {
158
- title: "Statuses",
159
- header: %w[Status Count],
160
- column_alignment: %i[left right],
161
- rows: data[:statuses],
162
- echarts_spec: "{
163
- xAxis: {
164
- type: 'category',
165
- data: SERIES_DATA.map(row => row['Status'])
166
- /* data: ['100', '101', '102', '103',
167
- '200', '201', '202', '203', '204', '205', '206', '207', '208', '226',
168
- '300', '301', '302', '303', '304', '305', '306', '307', '308',
169
- '400', '401', '402', '403', '404', '405', '406', '407', '408', '409', '410', '411', '412', '413', '414', '415', '416', '417', '418', '421', '422', '423', '424', '425', '426', '428', '429', '431', '451',
170
- '500', '501', '502', '503', '504', '505', '506', '507', '508', '510', '511'] */
171
- },
172
- yAxis: {
173
- type: 'value'
174
- },
175
- tooltip: {
176
- trigger: 'axis'
177
- },
178
- series: [
179
- {
180
- data: SERIES_DATA.map(row => row['Count']),
181
- type: 'bar',
182
- color: '#4C78A8',
183
- label: {
184
- show: true,
185
- position: 'top'
186
- },
187
- }
188
- ]
189
- }",
190
- },
191
- {
192
- title: "Daily Statuses",
193
- header: %w[Date S_2xx S_3xx S_4xx S_5xx],
194
- column_alignment: %i[left right right right right],
195
- rows: data[:statuses_by_day],
196
- echarts_spec: "{
197
- xAxis: {
198
- type: 'category',
199
- data: SERIES_DATA.map(row => row['Date'])
200
- },
201
- yAxis: {
202
- type: 'value'
203
- },
204
- tooltip: {
205
- trigger: 'axis'
206
- },
207
- series: [
208
- {
209
- data: SERIES_DATA.map(row => row['S_2xx']),
210
- type: 'bar',
211
- color: '#218521',
212
- stack: 'total',
213
- label: {
214
- show: true,
215
- position: 'right'
216
- },
217
- },
218
- {
219
- data: SERIES_DATA.map(row => row['S_3xx']),
220
- type: 'bar',
221
- color: '#FF8C00',
222
- stack: 'total',
223
- label: {
224
- show: true,
225
- position: 'right'
226
- },
227
- },
228
- {
229
- data: SERIES_DATA.map(row => row['S_4xx']),
230
- type: 'bar',
231
- color: '#A52A2A',
232
- stack: 'total',
233
- label: {
234
- show: true,
235
- position: 'right'
236
- },
237
- },
238
- {
239
- data: SERIES_DATA.map(row => row['S_5xx']),
240
- type: 'bar',
241
- color: '#000000',
242
- stack: 'total',
243
- label: {
244
- show: true,
245
- position: 'right'
246
- },
247
- },
248
- ]
249
- }",
250
- },
251
- {
252
- title: "Browsers",
131
+ total_statuses(data),
132
+ daily_statuses(data),
133
+ browsers(
134
+ data,
253
135
  header: %w[Browser Hits Visits Size],
254
136
  column_alignment: %i[left right right right],
255
- rows: data[:browsers],
256
- echarts_spec: "{
257
- toolbox: {
258
- feature: {
259
- saveAsImage: {},
260
- }
261
- },
262
- tooltip: {
263
- trigger: 'axis'
264
- },
265
- xAxis: {
266
- type: 'category',
267
- data: SERIES_DATA.sort(order_by_name).map(row => row['Browser']),
268
- showGrid: true,
269
- axisLabel: {
270
- rotate: 45 // Rotate the labels by 90 degrees
271
- }
272
- },
273
- yAxis: {
274
- type: 'value',
275
- name: 'Browser Hits',
276
- showGrid: true,
277
- },
278
- series: [
279
- {
280
- name: 'Hits',
281
- data: SERIES_DATA.sort(order_by_name).map(row => row['Hits']),
282
- type: 'bar',
283
- color: '#4C78A8',
284
- label: {
285
- show: true,
286
- position: 'top'
287
- },
288
- },
289
- ]
290
- }
291
- function order_by_name(a, b) {
292
- return a['Browser'] < b['Browser'] ? -1 : 1
293
- }
294
- ",
295
- },
296
- {
297
- title: "Platforms",
137
+ color: '#4C78A8'
138
+ ),
139
+ platforms(
140
+ data,
298
141
  header: %w[Platform Hits Visits Size],
299
142
  column_alignment: %i[left right right right],
300
- rows: data[:platforms],
301
- echarts_spec: "{
302
- toolbox: {
303
- feature: {
304
- saveAsImage: {},
305
- }
306
- },
307
- tooltip: {
308
- trigger: 'axis'
309
- },
310
- xAxis: {
311
- type: 'category',
312
- data: SERIES_DATA.sort(order_by_platform).map(row => row['Platform']),
313
- showGrid: true,
314
- axisLabel: {
315
- rotate: 45 // Rotate the labels by 90 degrees
316
- }
317
- },
318
- yAxis: {
319
- type: 'value',
320
- name: 'Platform Hits',
321
- showGrid: true,
322
- },
323
- series: [
324
- {
325
- name: 'Hits',
326
- data: SERIES_DATA.sort(order_by_platform).map(row => row['Hits']),
327
- type: 'bar',
328
- color: '#4C78A8',
329
- label: {
330
- show: true,
331
- position: 'top'
332
- },
333
- },
334
- ]
335
- }
336
- function order_by_platform(a, b) {
337
- return a['Platform'] < b['Platform'] ? -1 : 1
338
- }",
339
- },
340
- {
341
- title: "IPs",
143
+ color: '#4C78A8'
144
+ ),
145
+ ips(
146
+ data,
342
147
  header: %w[IP Hits Visits Size Country],
343
148
  column_alignment: %i[left right right right left],
344
- rows: data[:ips]
345
- },
346
- {
347
- title: "Countries",
348
- header: ["Country", "Hits", "Visits", "IPs", "IP List"],
349
- column_alignment: %i[left right right right left],
350
- rows: data[:countries]&.map { |k, v|
351
- [
352
- k,
353
- v.map { |x| x[1] }.inject(&:+),
354
- v.map { |x| x[2] }.inject(&:+),
355
- v.map { |x| x[0] }.uniq.size,
356
- v.map { |x| x[0] }.join(WORDS_SEPARATOR)
357
- ]
358
- }&.sort { |x, y| y[3] <=> x[3] },
359
- echarts_height: "600px",
360
- echarts_spec: "{
361
- tooltip: {
362
- trigger: 'axis',
363
- axisPointer: {
364
- type: 'shadow'
365
- }
366
- },
367
- xAxis: {
368
- type: 'value',
369
- boundaryGap: [0, 0.01]
370
- },
371
- yAxis: {
372
- type: 'category',
373
- data: SERIES_DATA.sort(order_by_hits).map(row => row['Country'] ),
374
- },
375
- series: [
376
- {
377
- type: 'bar',
378
- data: SERIES_DATA.sort(order_by_hits).map(row => row['Hits'] ),
379
- color: '#4C78A8',
380
- label: {
381
- show: true,
382
- position: 'right'
383
- },
384
- },
385
- ]
386
- };
387
-
388
- function order_by_hits(a, b) {
389
- return Number(a['Hits']) < Number(b['Hits']) ? -1 : 1
390
- }
391
- "
392
- },
149
+ palette: :apache
150
+ ),
151
+ countries(data, color: '#4C78A8'),
393
152
  ip_per_hour_report_spec(ips_per_hour(data[:ips_per_hour])),
394
153
  {
395
154
  title: "Combined Platform Data",
@@ -28,6 +28,8 @@ module LogSense
28
28
  @data = data
29
29
  @options = options
30
30
  @report_title = options[:input_format].capitalize
31
+
32
+ @format_specific_theme = "#{@options[:input_format]}_theme.css"
31
33
  @format_specific_css = "#{@options[:input_format]}.css.erb"
32
34
 
33
35
  # Chooses template and destination
@@ -122,15 +122,25 @@ module LogSense
122
122
  ON event.log_id == error.log_id
123
123
  WHERE #{filter} and substr(status, 1, 1) == '5').gsub("\n", "") || [[]]
124
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
+
125
133
  @error = @db.execute %Q(
126
- SELECT filename, log_id, description, count(log_id)
134
+ SELECT filename,
135
+ log_id, description, count(log_id)
127
136
  FROM Error
128
137
  WHERE (description NOT LIKE '%No route matches%' and
129
138
  description NOT LIKE '%Couldn''t find%')
130
139
  GROUP BY description).gsub("\n", "") || [[]]
131
140
 
132
141
  @possible_attacks = @db.execute %Q(
133
- SELECT filename, log_id, description, count(log_id)
142
+ SELECT filename,
143
+ log_id, description, count(log_id)
134
144
  FROM Error
135
145
  WHERE (description LIKE '%No route matches%' or
136
146
  description LIKE '%Couldn''t find%')
@@ -39,73 +39,9 @@ module LogSense
39
39
  ]
40
40
  };",
41
41
  },
42
- {
43
- title: "Time Distribution",
44
- header: %w[Hour Hits],
45
- column_alignment: %i[left right],
46
- rows: data[:time_distribution],
47
- echarts_spec: "{
48
- xAxis: {
49
- type: 'category',
50
- data: SERIES_DATA.map(row => row['Hour'])
51
- /* data: ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
52
- '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',
53
- '20', '21', '22', '23', '24'] */
54
- },
55
- yAxis: {
56
- type: 'value'
57
- },
58
- tooltip: {
59
- trigger: 'axis'
60
- },
61
- series: [
62
- {
63
- data: SERIES_DATA.map(row => row['Hits']),
64
- type: 'bar',
65
- color: '#D30001',
66
- label: {
67
- show: true,
68
- position: 'top'
69
- },
70
- }
71
- ]
72
- }",
73
- },
74
- {
75
- title: "Statuses",
76
- header: %w[Status Count],
77
- column_alignment: %i[left right],
78
- rows: data[:statuses],
79
- col: "small-12 cell",
80
- echarts_spec: "{
81
- xAxis: {
82
- type: 'category',
83
- data: SERIES_DATA.map(row => row['Status'])
84
- /* data: ['100', '101', '102', '103',
85
- '200', '201', '202', '203', '204', '205', '206', '207', '208', '226',
86
- '300', '301', '302', '303', '304', '305', '306', '307', '308',
87
- '400', '401', '402', '403', '404', '405', '406', '407', '408', '409', '410', '411', '412', '413', '414', '415', '416', '417', '418', '421', '422', '423', '424', '425', '426', '428', '429', '431', '451',
88
- '500', '501', '502', '503', '504', '505', '506', '507', '508', '510', '511'] */
89
- },
90
- yAxis: {
91
- type: 'value'
92
- },
93
- tooltip: {
94
- trigger: 'axis'
95
- },
96
- series: [
97
- {
98
- data: SERIES_DATA.map(row => row['Count']),
99
- type: 'bar',
100
- color: '#D30001',
101
- label: {
102
- show: true,
103
- position: 'top'
104
- },
105
- }
106
- ]
107
- }",
108
- },
42
+ time_distribution(data),
43
+ total_statuses(data),
44
+ daily_statuses(data),
109
45
  {
110
46
  title: "Rails Performance",
111
47
  header: %w[Controller Hits Min Avg Max],
@@ -208,7 +144,7 @@ module LogSense
208
144
  data: fatal_plot.filter(row => row[0] != '').map(row => row[0]),
209
145
  showGrid: true,
210
146
  axisLabel: {
211
- rotate: 45 // Rotate the labels by 90 degrees
147
+ rotate: 45 // Rotate the labels
212
148
  }
213
149
  },
214
150
  yAxis: {
@@ -234,72 +170,8 @@ module LogSense
234
170
  header: %w[Date Status IP URL Description Log ID],
235
171
  column_alignment: %i[left left left left left left],
236
172
  rows: data[:internal_server_error],
237
- col: "small-12 cell"
238
- },
239
- {
240
- title: "Errors",
241
- header: %w[Log ID Description Count],
242
- column_alignment: %i[left left left],
243
- rows: data[:error],
244
- col: "large-6 cell"
245
- },
246
- {
247
- title: "Possible Attacks",
248
- header: %w[Log ID Description Count],
249
- column_alignment: %i[left left left],
250
- rows: data[:possible_attacks],
251
- col: "large-6 cell"
252
- },
253
- {
254
- title: "Browsers",
255
- header: %w[Browser Visits],
256
- column_alignment: %i[left right],
257
- rows: data[:browsers],
258
- echarts_spec: "{
259
- toolbox: {
260
- feature: {
261
- saveAsImage: {},
262
- }
263
- },
264
- tooltip: {
265
- trigger: 'axis'
266
- },
267
- xAxis: {
268
- type: 'category',
269
- data: SERIES_DATA.sort(order_by_name).map(row => row['Browser']),
270
- showGrid: true,
271
- axisLabel: {
272
- rotate: 45 // Rotate the labels by 90 degrees
273
- }
274
- },
275
- yAxis: {
276
- type: 'value',
277
- name: 'Browser Visits',
278
- showGrid: true,
279
- },
280
- series: [
281
- {
282
- name: 'Hits',
283
- data: SERIES_DATA.sort(order_by_name).map(row => row['Visits']),
284
- type: 'bar',
285
- color: '#D30001',
286
- label: {
287
- show: true,
288
- position: 'top'
289
- },
290
- },
291
- ]
292
- }
293
- function order_by_name(a, b) {
294
- return a['Browser'] < b['Browser'] ? -1 : 1
295
- }
296
- ",
297
- },
298
- {
299
- title: "Platforms",
300
- header: %w[Platform Visits],
301
- column_alignment: %i[left right],
302
- rows: data[:platforms],
173
+ col: "small-12 cell",
174
+ echarts_extra: "var internal_server_error_plot=#{data[:internal_server_error_plot].to_json}",
303
175
  echarts_spec: "{
304
176
  toolbox: {
305
177
  feature: {
@@ -311,21 +183,20 @@ module LogSense
311
183
  },
312
184
  xAxis: {
313
185
  type: 'category',
314
- data: SERIES_DATA.sort(order_by_platform).map(row => row['Platform']),
186
+ data: internal_server_error_plot.filter(row => row[0] != '').map(row => row[0]),
315
187
  showGrid: true,
316
188
  axisLabel: {
317
- rotate: 45 // Rotate the labels by 90 degrees
189
+ rotate: 45 // Rotate the labels
318
190
  }
319
191
  },
320
192
  yAxis: {
321
193
  type: 'value',
322
- name: 'Platform Visits',
194
+ name: 'Errors',
323
195
  showGrid: true,
324
196
  },
325
197
  series: [
326
198
  {
327
- name: 'Visits',
328
- data: SERIES_DATA.sort(order_by_platform).map(row => row['Visits']),
199
+ data: internal_server_error_plot.filter(row => row[0] != '').map(row => row[1]),
329
200
  type: 'bar',
330
201
  color: '#D30001',
331
202
  label: {
@@ -334,73 +205,29 @@ module LogSense
334
205
  },
335
206
  },
336
207
  ]
337
- }
338
- function order_by_platform(a, b) {
339
- return a['Platform'] < b['Platform'] ? -1 : 1
340
- }",
208
+ };"
341
209
  },
342
210
  {
343
- title: "IPs",
344
- header: %w[IPs Hits Country],
345
- column_alignment: %i[left right left],
346
- rows: data[:ips]
211
+ title: "Errors",
212
+ header: %w[Log ID Description Count],
213
+ column_alignment: %i[left left left right],
214
+ rows: data[:error],
215
+ col: "small-12 cell"
347
216
  },
348
217
  {
349
- title: "Countries",
350
- header: ["Country", "Hits", "IPs", "IP List"],
351
- column_alignment: %i[left right left],
352
- rows: countries_table(data[:countries]),
353
- echarts_height: "600px",
354
- echarts_spec: "{
355
- tooltip: {
356
- trigger: 'axis',
357
- axisPointer: {
358
- type: 'shadow'
359
- }
360
- },
361
- xAxis: {
362
- type: 'value',
363
- boundaryGap: [0, 0.01]
364
- },
365
- yAxis: {
366
- type: 'category',
367
- data: SERIES_DATA.sort(order_by_hits).map(row => row['Country'] ),
368
- },
369
- series: [
370
- {
371
- type: 'bar',
372
- data: SERIES_DATA.sort(order_by_hits).map(row => row['Hits'] ),
373
- color: '#D30001',
374
- label: {
375
- show: true,
376
- position: 'right'
377
- },
378
- },
379
- ]
380
- };
381
-
382
- function order_by_hits(a, b) {
383
- return Number(a['Hits']) < Number(b['Hits']) ? -1 : 1
384
- }
385
- "
218
+ title: "Potential Attacks",
219
+ header: %w[Log ID Description Count],
220
+ column_alignment: %i[left left left right],
221
+ rows: data[:possible_attacks],
222
+ col: "small-12 cell"
386
223
  },
224
+ browsers(data),
225
+ platforms(data),
226
+ ips(data),
227
+ countries(data),
387
228
  ip_per_hour_report_spec(ips_per_hour(data[:ips_per_hour])),
388
229
  session_report_spec(ips_detailed(data[:ips_per_day_detailed]))
389
230
  ]
390
231
  end
391
-
392
- private
393
-
394
- # { country => [[ip, visit, country], ...]
395
- def countries_table(data)
396
- data&.map { |k, v|
397
- [
398
- k || "-",
399
- v.map { |x| x[1] }.inject(&:+),
400
- v.map { |x| x[0] }.uniq.size,
401
- v.map { |x| x[0] }.join(WORDS_SEPARATOR)
402
- ]
403
- }&.sort { |x, y| x[0] <=> y[0] }
404
- end
405
232
  end
406
233
  end