log_sense 1.9.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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