log_sense 1.7.0 → 1.8.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.
@@ -37,7 +37,7 @@ module LogSense
37
37
  source_file TEXT,
38
38
  line_number INTEGER
39
39
  )
40
- EOS
40
+ EOS
41
41
 
42
42
  ins = db.prepare <<-EOS
43
43
  insert into Event(
@@ -60,7 +60,7 @@ module LogSense
60
60
  line_number
61
61
  )
62
62
  values (#{Array.new(17, "?").join(", ")})
63
- EOS
63
+ EOS
64
64
 
65
65
  db.execute <<-EOS
66
66
  CREATE TABLE IF NOT EXISTS Error(
@@ -71,18 +71,18 @@ module LogSense
71
71
  filename TEXT,
72
72
  line_number INTEGER
73
73
  )
74
- EOS
74
+ EOS
75
75
 
76
76
  ins_error = db.prepare <<-EOS
77
- insert into Error(
77
+ insert into Error(
78
78
  log_id,
79
79
  context,
80
80
  description,
81
81
  filename,
82
82
  line_number
83
- )
84
- values (?, ?, ?, ?, ?)
85
- EOS
83
+ )
84
+ values (?, ?, ?, ?, ?)
85
+ EOS
86
86
 
87
87
  db.execute <<-EOS
88
88
  CREATE TABLE IF NOT EXISTS Render(
@@ -93,18 +93,46 @@ module LogSense
93
93
  filename TEXT,
94
94
  line_number INTEGER
95
95
  )
96
- EOS
96
+ EOS
97
97
 
98
98
  ins_rendered = db.prepare <<-EOS
99
- insert into Render(
99
+ insert into Render(
100
100
  partial,
101
101
  duration_ms,
102
102
  allocations,
103
103
  filename,
104
104
  line_number
105
- )
106
- values (?, ?, ?, ?, ?)
107
- EOS
105
+ )
106
+ values (?, ?, ?, ?, ?)
107
+ EOS
108
+
109
+ db.execute <<-EOS
110
+ CREATE TABLE IF NOT EXISTS BrowserInfo(
111
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
112
+ browser TEXT,
113
+ platform TEXT,
114
+ device_name TEXT,
115
+ controller TEXT,
116
+ method TEXT,
117
+ request_format TEXT,
118
+ anon_ip TEXT,
119
+ timestamp TEXT
120
+ )
121
+ EOS
122
+
123
+ ins_browser_info = db.prepare <<-EOS
124
+ insert into BrowserInfo(
125
+ browser,
126
+ platform,
127
+ device_name,
128
+ controller,
129
+ method,
130
+ request_format,
131
+ anon_ip,
132
+ timestamp
133
+ )
134
+ values (?, ?, ?, ?, ?, ?, ?, ?)
135
+ EOS
108
136
 
109
137
  # requests in the log might be interleaved.
110
138
  #
@@ -149,6 +177,19 @@ module LogSense
149
177
  # I and F for completed requests, [ is for error messages
150
178
  next if line[0] != 'I' and line[0] != 'F' and line[0] != '['
151
179
 
180
+ data = match_and_process_browser_info line
181
+ if data
182
+ ins_browser_info.execute(data[:browser],
183
+ data[:platform],
184
+ data[:device_name],
185
+ data[:controller],
186
+ data[:method],
187
+ data[:request_format],
188
+ data[:anon_ip],
189
+ data[:timestamp])
190
+ next
191
+ end
192
+
152
193
  data = match_and_process_error line
153
194
  if data
154
195
  ins_error.execute(data[:log_id],
@@ -245,6 +286,7 @@ module LogSense
245
286
  db
246
287
  end
247
288
 
289
+
248
290
  TIMESTAMP = /(?<timestamp>[^ ]+)/
249
291
  ID = /(?<id>[a-z0-9-]+)/
250
292
  VERB = /(?<verb>GET|POST|PATCH|PUT|DELETE)/
@@ -254,6 +296,24 @@ module LogSense
254
296
  STATUS_IN_WORDS = /(OK|Unauthorized|Found|Internal Server Error|Bad Request|Method Not Allowed|Request Timeout|Not Implemented|Bad Gateway|Service Unavailable)/
255
297
  MSECS = /[0-9.]+/
256
298
 
299
+ # I, [2024-07-01T02:21:34.339058 #1392909] INFO -- : [815b3e28-8d6e-4741-8605-87654a9ff58c] BrowserInfo: "Unknown Browser","unknown_platform","Unknown","Devise::SessionsController","new","html","4db749654a0fcacbf3868f87723926e7405262f8d596e8514f4997dc80a3cd7e","2024-07-01T02:21:34+02:00"
300
+ BROWSER_INFO_REGEXP = /BrowserInfo: "(?<browser>.+)","(?<platform>.+)","(?<device_name>.+)","(?<controller>.+)","(?<method>.+)","(?<request_format>.+)","(?<anon_ip>.+)","(?<timestamp>.+)"/
301
+ def match_and_process_browser_info(line)
302
+ matchdata = BROWSER_INFO_REGEXP.match line
303
+ if matchdata
304
+ {
305
+ browser: matchdata[:browser],
306
+ platform: matchdata[:platform],
307
+ device_name: matchdata[:device_name],
308
+ controller: matchdata[:controller],
309
+ method: matchdata[:method],
310
+ request_format: matchdata[:request_format],
311
+ anon_ip: matchdata[:anon_ip],
312
+ timestamp: matchdata[:timestamp],
313
+ }
314
+ end
315
+ end
316
+
257
317
  # Error Messages
258
318
  # [584cffcc-f1fd-4b5c-bb8b-b89621bd4921] ActionController::RoutingError (No route matches [GET] "/assets/foundation-icons.svg"):
259
319
  # [fd8df8b5-83c9-48b5-a056-e5026e31bd5e] ActionView::Template::Error (undefined method `all_my_ancestor' for nil:NilClass):
@@ -261,7 +321,7 @@ module LogSense
261
321
  EXCEPTION = /[A-Za-z_0-9:]+(Error)?/
262
322
  ERROR_REGEXP = /^\[#{ID}\] (?<context>#{EXCEPTION}) \((?<description>(#{EXCEPTION})?.*)\):/
263
323
 
264
- def match_and_process_error line
324
+ def match_and_process_error(line)
265
325
  matchdata = ERROR_REGEXP.match line
266
326
  if matchdata
267
327
  {
@@ -275,7 +335,7 @@ module LogSense
275
335
  # I, [2021-10-19T08:16:34.343858 #10477] INFO -- : [67103c0d-455d-4fe8-951e-87e97628cb66] Started GET "/grow/people/471" for 217.77.80.35 at 2021-10-19 08:16:34 +0000
276
336
  STARTED_REGEXP = /I, \[#{TIMESTAMP} #[0-9]+\] INFO -- : \[#{ID}\] Started #{VERB} "#{URL}" for #{IP} at/
277
337
 
278
- def match_and_process_start line
338
+ def match_and_process_start(line)
279
339
  matchdata = STARTED_REGEXP.match line
280
340
  if matchdata
281
341
  {
@@ -40,6 +40,62 @@ module LogSense
40
40
  where #{filter}
41
41
  group by controller order by controller).gsub("\n", "")
42
42
 
43
+ #
44
+ # Use the performance information to build a tree map.
45
+ # We then compute by device and show the treemap and the table by device
46
+ # together
47
+ #
48
+
49
+ # ["CompletedSurveysController#new", 14, "22.00", "51.57", "116.00"]
50
+ controller_and_methods = @performance.group_by { |element|
51
+ (element[0] || "#").split("#")[0]
52
+ }
53
+
54
+ @controller_and_methods_treemap = controller_and_methods.map do |key, values|
55
+ {
56
+ name: key,
57
+ value: values.map { |value| value[1] || 0.0 }.inject(&:+),
58
+ children: values.map { |value|
59
+ {
60
+ name: (value[0] || "#").split("#")[1],
61
+ value: value[1]
62
+ }
63
+ }
64
+ }
65
+ end
66
+
67
+ @controller_and_methods_by_device = @db.execute %Q(
68
+ SELECT controller as Controller,
69
+ method as Method,
70
+ request_format as Format,
71
+ sum(iif(platform = 'ios', 1, 0)) as iOS,
72
+ sum(iif(platform = 'android', 1, 0)) as Android,
73
+ sum(iif(platform = 'mac', 1, 0)) as Mac,
74
+ sum(iif(platform = 'windows', 1, 0)) as Windows,
75
+ sum(iif(platform = 'linux', 1, 0)) as Linux,
76
+ sum(iif(platform != 'ios' and platform != 'android' and platform != 'mac' and platform != 'windows' and platform != 'linux', 1, 0)) as Other,
77
+ count(distinct(id)) as Total
78
+ from BrowserInfo
79
+ group by controller, method, request_format
80
+ )
81
+
82
+ #
83
+ # Browser Info data
84
+ #
85
+ @browsers = @db.execute %Q(
86
+ SELECT browser as Browser,
87
+ count(distinct(id)) as Visits
88
+ from BrowserInfo
89
+ group by browser
90
+ )
91
+
92
+ @platforms = @db.execute %Q(
93
+ SELECT platform as Platform,
94
+ count(distinct(id)) as Visits
95
+ from BrowserInfo
96
+ group by platform
97
+ )
98
+
43
99
  @fatal = @db.execute %Q(
44
100
  SELECT strftime("%Y-%m-%d %H:%M", started_at),
45
101
  ip,
@@ -50,6 +106,14 @@ module LogSense
50
106
  ON event.log_id == error.log_id
51
107
  WHERE #{filter} and exit_status == 'F').gsub("\n", "") || [[]]
52
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
+ WHERE #{filter} and exit_status == 'F'
115
+ GROUP BY strftime("%Y-%m-%d", started_at)).gsub("\n", "") || [[]]
116
+
53
117
  @internal_server_error = @db.execute %Q(
54
118
  SELECT strftime("%Y-%m-%d %H:%M", started_at), status, ip, url,
55
119
  error.description,
@@ -59,10 +123,19 @@ module LogSense
59
123
  WHERE #{filter} and substr(status, 1, 1) == '5').gsub("\n", "") || [[]]
60
124
 
61
125
  @error = @db.execute %Q(
62
- SELECT filename, log_id, context, description, count(log_id)
126
+ SELECT filename, log_id, description, count(log_id)
63
127
  FROM Error
128
+ WHERE (description NOT LIKE '%No route matches%' and
129
+ description NOT LIKE '%Couldn''t find%')
64
130
  GROUP BY description).gsub("\n", "") || [[]]
65
131
 
132
+ @possible_attacks = @db.execute %Q(
133
+ SELECT filename, log_id, description, count(log_id)
134
+ FROM Error
135
+ WHERE (description LIKE '%No route matches%' or
136
+ description LIKE '%Couldn''t find%')
137
+ GROUP BY description).gsub("\n", "") || [[]]
138
+
66
139
  instance_vars_to_hash
67
140
  end
68
141
  end