log_sense 2.3.0 → 2.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a9992db2fa42d1de3dac0bacbeed543a097e351c8bc9999c60febb3f67714a9
4
- data.tar.gz: 06b9ed1329cbf3fdfdf889d154576dff85f16178e817b29fffede535eb1f12be
3
+ metadata.gz: 01b7c715a9aac207ec39985ba5791c307e64784ae1c5c3f5f5a4e0b124a796af
4
+ data.tar.gz: 7f1881b1a621ea2d1b2f3f29052d4a82016d23bcb6c0d702712b249308bbf2cc
5
5
  SHA512:
6
- metadata.gz: 0510a72e71e67e7bba948219f3ab35e7422c95a5a167815ccd30f589c172f19f7704e6e583364ac2493a7ff32c18df1316ef36d05f7e0346f582516b62d9f806
7
- data.tar.gz: a374eea7ae662ac5be2458620baa4276bd7957871ccea67e82ba2987f941257ec2ffd1d1e7b62efd764093204976759470ccf7ca08a8152ecf1776d5eb023499
6
+ metadata.gz: 0e8ccec75c78ca240320c3be45cf47779879eef0cd7033fee0e623647b29c744794e19e9f4b4f2e444e9b474b90b017ab10b60bea6661f92aaf156923aff839e
7
+ data.tar.gz: b70eb6964f19f0e7272b3953a4df5b124ea95c1d75ea6fd1a33f9ffe0ad04f6ddb2c7e9e177ccd19dded06a94ae159b3333fca9fadb1e85c279b87cccf78717c
data/.gitignore CHANGED
@@ -8,3 +8,6 @@
8
8
  /tmp/
9
9
  node_modules
10
10
  *~
11
+ TAGS
12
+ sample_logs
13
+ ip_locations/dbip-country-lite-*.csv*
data/CHANGELOG.org CHANGED
@@ -2,6 +2,17 @@
2
2
  #+AUTHOR: Adolfo Villafiorita
3
3
  #+STARTUP: showall
4
4
 
5
+ * 2.4.0
6
+
7
+ - Updates log_parser to match changes in log lines introduced from Rails 7
8
+ (or, in other words, fixes a bug which caused log_sense to miss events
9
+ from logs produced by Rails >= 7 applications)
10
+
11
+ * 2.3.1
12
+
13
+ - Updates geoip db
14
+ - Updates dependencies
15
+
5
16
  * 2.3.0
6
17
 
7
18
  - Adds average response time by day
data/Gemfile.lock CHANGED
@@ -1,83 +1,95 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- log_sense (2.2.1)
5
- browser (~> 5.3.0)
4
+ log_sense (2.3.1)
5
+ browser (~> 6.0.0)
6
+ csv
6
7
  ipaddr (~> 1.2.0)
7
8
  iso_country_codes (~> 0.7.0)
8
- sqlite3 (~> 2.0.0)
9
- terminal-table (~> 3.0.0)
9
+ ostruct
10
+ sqlite3 (~> 2.6.0)
11
+ terminal-table (~> 4.0.0)
10
12
 
11
13
  GEM
12
14
  remote: https://rubygems.org/
13
15
  specs:
14
- ast (2.4.2)
15
- browser (5.3.1)
16
+ ast (2.4.3)
17
+ browser (6.0.0)
16
18
  bundle-audit (0.1.0)
17
19
  bundler-audit
18
20
  bundler-audit (0.9.2)
19
21
  bundler (>= 1.2.0, < 3)
20
22
  thor (~> 1.0)
21
- debug (1.9.2)
23
+ csv (3.3.4)
24
+ date (3.4.1)
25
+ debug (1.10.0)
22
26
  irb (~> 1.10)
23
27
  reline (>= 0.3.8)
24
- io-console (0.7.2)
25
- ipaddr (1.2.6)
26
- irb (1.14.0)
28
+ io-console (0.8.0)
29
+ ipaddr (1.2.7)
30
+ irb (1.15.2)
31
+ pp (>= 0.6.0)
27
32
  rdoc (>= 4.0.0)
28
33
  reline (>= 0.4.2)
29
34
  iso_country_codes (0.7.8)
30
- json (2.7.2)
31
- language_server-protocol (3.17.0.3)
32
- mini_portile2 (2.8.7)
33
- minitest (5.24.1)
34
- parallel (1.26.3)
35
- parser (3.3.4.2)
35
+ json (2.12.0)
36
+ language_server-protocol (3.17.0.5)
37
+ lint_roller (1.1.0)
38
+ mini_portile2 (2.8.9)
39
+ minitest (5.25.5)
40
+ ostruct (0.6.1)
41
+ parallel (1.27.0)
42
+ parser (3.3.8.0)
36
43
  ast (~> 2.4.1)
37
44
  racc
38
- psych (5.1.2)
45
+ pp (0.6.2)
46
+ prettyprint
47
+ prettyprint (0.2.0)
48
+ prism (1.4.0)
49
+ psych (5.2.6)
50
+ date
39
51
  stringio
40
52
  racc (1.8.1)
41
53
  rainbow (3.1.1)
42
54
  rake (13.2.1)
43
- rdoc (6.7.0)
55
+ rdoc (6.13.1)
44
56
  psych (>= 4.0.0)
45
- regexp_parser (2.9.2)
46
- reline (0.5.9)
57
+ regexp_parser (2.10.0)
58
+ reline (0.6.1)
47
59
  io-console (~> 0.5)
48
- rexml (3.3.6)
49
- strscan
50
- rubocop (1.65.1)
60
+ rubocop (1.75.5)
51
61
  json (~> 2.3)
52
- language_server-protocol (>= 3.17.0)
62
+ language_server-protocol (~> 3.17.0.2)
63
+ lint_roller (~> 1.1.0)
53
64
  parallel (~> 1.10)
54
65
  parser (>= 3.3.0.2)
55
66
  rainbow (>= 2.2.2, < 4.0)
56
- regexp_parser (>= 2.4, < 3.0)
57
- rexml (>= 3.2.5, < 4.0)
58
- rubocop-ast (>= 1.31.1, < 2.0)
67
+ regexp_parser (>= 2.9.3, < 3.0)
68
+ rubocop-ast (>= 1.44.0, < 2.0)
59
69
  ruby-progressbar (~> 1.7)
60
- unicode-display_width (>= 2.4.0, < 3.0)
61
- rubocop-ast (1.32.1)
62
- parser (>= 3.3.1.0)
70
+ unicode-display_width (>= 2.4.0, < 4.0)
71
+ rubocop-ast (1.44.1)
72
+ parser (>= 3.3.7.2)
73
+ prism (~> 1.4)
63
74
  ruby-progressbar (1.13.0)
64
- sqlite3 (2.0.3)
75
+ sqlite3 (2.6.0)
65
76
  mini_portile2 (~> 2.8.0)
66
- stringio (3.1.1)
67
- strscan (3.1.0)
68
- terminal-table (3.0.2)
69
- unicode-display_width (>= 1.1.1, < 3)
70
- thor (1.3.1)
71
- unicode-display_width (2.5.0)
77
+ stringio (3.1.7)
78
+ terminal-table (4.0.0)
79
+ unicode-display_width (>= 1.1.1, < 4)
80
+ thor (1.3.2)
81
+ unicode-display_width (3.1.4)
82
+ unicode-emoji (~> 4.0, >= 4.0.4)
83
+ unicode-emoji (4.0.4)
72
84
 
73
85
  PLATFORMS
74
86
  ruby
75
87
 
76
88
  DEPENDENCIES
77
89
  bundle-audit
78
- debug (~> 1.9.0)
90
+ debug
79
91
  log_sense!
80
- minitest (~> 5.24.0)
92
+ minitest
81
93
  rake (~> 13.0)
82
94
  rubocop
83
95
 
data/README.org CHANGED
@@ -4,8 +4,8 @@
4
4
 
5
5
  * Introduction
6
6
 
7
- LogSense generates reports and statistics from Ruby on Rails and Apache/Nginx
8
- log files.
7
+ LogSense analyzes Apache and Rails log files, generating reports and statistics
8
+ about usage and performace.
9
9
 
10
10
  Main features:
11
11
 
@@ -22,10 +22,11 @@ Main features:
22
22
  self polls and crawlers.
23
23
  - Reports can be generated in HTML, txt, ufw, and SQLite. HTML reports are
24
24
  responsive and come with dark and light theme.
25
+ - It works with Rails' vanilla log format (no need to format the log)
25
26
 
26
27
  LogSense is Written in Ruby, it runs from the command line, it is fast, and it
27
28
  can be installed on any system with a relatively recent version of Ruby. We
28
- use it with Ruby 3.1.4 and 3.3.0.
29
+ started using it with Ruby 3.1.4 and we are now at version 3.4.
29
30
 
30
31
  It is fast. On a ThinkPad P16, a 277M log file is parsed in 15 seconds,
31
32
  processing, that is, about 7740 events per second; a 569M log file is parsed in
Binary file
@@ -139,7 +139,7 @@ module LogSense
139
139
 
140
140
  opts.on("-v", "--version", "Prints version information") do
141
141
  puts "log_sense version #{LogSense::VERSION}"
142
- puts "Copyright (C) 2021-2024 Shair.Tech"
142
+ puts "Copyright (C) 2021-2025 Shair.Tech"
143
143
  puts "Distributed under the terms of the MIT license"
144
144
  exit
145
145
  end
@@ -33,6 +33,9 @@ module LogSense
33
33
  duration_views_ms FLOAT,
34
34
  duration_ar_ms FLOAT,
35
35
  allocations INTEGER,
36
+ queries INTEGER,
37
+ cached_queries INTEGER,
38
+ gc_duration INTEGER,
36
39
  comment TEXT,
37
40
  source_file TEXT,
38
41
  line_number INTEGER
@@ -180,9 +183,16 @@ module LogSense
180
183
  # LOG_LEVEL, [ZULU_TIMESTAMP #NUMBER] INFO --: [ID] Processing by CONTROLLER as FORMAT
181
184
  # LOG_LEVEL, [ZULU_TIMESTAMP #NUMBER] INFO --: [ID] Parameters: JSON
182
185
  # LOG_LEVEL, [ZULU_TIMESTAMP #NUMBER] INFO --: [ID] Rendered VIEW within LAYOUT (Duration: DURATION | Allocations: ALLOCATIONS)
186
+ #
187
+ # For rails_6:
188
+ #
183
189
  # LOG_LEVEL, [ZULU_TIMESTAMP #NUMBER] INFO --: [ID] Completed STATUS STATUS_STRING in DURATION (Views: DURATION | ActiveRecord: DURATION | Allocations: NUMBER)
184
190
  #
185
- # and they appears in the order shown above: started, processing, ...
191
+ # For rails_7:
192
+ #
193
+ # LOG_LEVEL, [ZULU_TIMESTAMP #NUMBER] INFO --: [ID] Completed STATUS STATUS_STRING in DURATION (Views: DURATION | ActiveRecord: DURATION (N queries, M cached) | GC: DURATION)
194
+ #
195
+ # and they appear in the order shown above: started, processing, ...
186
196
  #
187
197
  # Different requests might be interleaved, of course
188
198
  #
@@ -434,6 +444,7 @@ module LogSense
434
444
  STATUS = '(?<status>[0-9]+)'
435
445
  STATUS_IN_WORDS = '(OK|Unauthorized|Found|Internal Server Error|Bad Request|Method Not Allowed|Request Timeout|Not Implemented|Bad Gateway|Service Unavailable)'
436
446
  MSECS = '[0-9.]+'
447
+ INT = '[0-9]+'
437
448
 
438
449
  # 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
439
450
  STARTED_REGEXP = /I, \[#{TIMESTAMP} #[0-9]+\] INFO -- : \[#{LOG_ID}\] Started #{VERB} "#{URL}" for #{IP} at/o
@@ -455,7 +466,21 @@ module LogSense
455
466
  # I, [2021-10-19T08:16:34.712331 #10477] INFO -- : [67103c0d-455d-4fe8-951e-87e97628cb66] Completed 200 OK in 367ms (Views: 216.7ms | ActiveRecord: 141.3ms | Allocations: 168792)
456
467
  # I, [2021-12-09T16:53:52.657727 #2735058] INFO -- : [0064e403-9eb2-439d-8fe1-a334c86f5532] Completed 200 OK in 13ms (Views: 11.1ms | ActiveRecord: 1.2ms)
457
468
  # I, [2021-12-06T14:28:19.736545 #2804090] INFO -- : [34091cb5-3e7b-4042-aaf8-6c6510d3f14c] Completed 500 Internal Server Error in 66ms (ActiveRecord: 8.0ms | Allocations: 24885)
458
- COMPLETED_REGEXP = /I, \[#{TIMESTAMP} #[0-9]+\] INFO -- : \[#{LOG_ID}\] Completed #{STATUS} #{STATUS_IN_WORDS} in (?<total>#{MSECS})ms \((Views: (?<views>#{MSECS})ms \| )?ActiveRecord: (?<arec>#{MSECS})ms( \| Allocations: (?<alloc>[0-9]+))?\)/o
469
+
470
+ # REGEXP Fragments
471
+
472
+ # views is optional
473
+ # In strings I need to properly escape \ or it will be mis-interpreted
474
+ VIEWS = "(Views: (?<views>#{MSECS})ms \\| )?"
475
+ # active records has two formats (according to Rails version)
476
+ ACTIVE_RECORDS_BASE = "ActiveRecord: (?<arec>#{MSECS})ms"
477
+ ACTIVE_RECORDS_QUERIES = "( \\((?<queries>#{INT}) queries, (?<cached_queries>#{INT}) cached\\))?"
478
+ ACTIVE_RECORDS = "#{ACTIVE_RECORDS_BASE}#{ACTIVE_RECORDS_QUERIES}"
479
+ # older rails versions have ALLOCATIONS, newer have GC
480
+ ALLOCATIONS = " \\| Allocations: (?<alloc>#{INT})"
481
+ GC = " \\| GC: (?<gc_duration>#{MSECS})ms"
482
+
483
+ COMPLETED_REGEXP = /I, \[#{TIMESTAMP} #[0-9]+\] INFO -- : \[#{LOG_ID}\] Completed #{STATUS} #{STATUS_IN_WORDS} in (?<total>#{MSECS})ms \(#{VIEWS}#{ACTIVE_RECORDS}(#{ALLOCATIONS}|#{GC})?\)/o
459
484
 
460
485
  def match_and_process_completed(line)
461
486
  matchdata = (COMPLETED_REGEXP.match line)
@@ -469,7 +494,10 @@ module LogSense
469
494
  duration_total_ms: matchdata[:total],
470
495
  duration_views_ms: matchdata[:views],
471
496
  duration_ar_ms: matchdata[:arec],
472
- allocations: matchdata[:alloc],
497
+ allocations: (matchdata[:alloc] || -1),
498
+ queries: (matchdata[:queries] || -1),
499
+ cached_queries: (matchdata[:cached_queries] || -1),
500
+ gc_duration: (matchdata[:gc_duration] || -1),
473
501
  comment: ""
474
502
  }
475
503
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LogSense
2
- VERSION = "2.3.0"
4
+ VERSION = "2.4.0"
3
5
  end
data/log_sense.gemspec CHANGED
@@ -6,8 +6,18 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ["Adolfo Villafiorita"]
7
7
  spec.email = ["adolfo@shair.tech"]
8
8
 
9
- spec.summary = %q{Generate analytics for Rails and Apache/Nginx log file.}
10
- spec.description = %q{Generate analytics in HTML, txt, and SQLite format for Rails and Apache/Nginx log files.}
9
+ spec.summary = %q{Analyze Rails and Apache/Nginx log file, generating statistics and reports.}
10
+ spec.description = %q{log_sense is a command-line command which analyzes Rails and Nginx logs and
11
+ provides detailed data about accesses, performances, and errors. It is a
12
+ one stop shop solution for analyzing your Rails application in production.
13
+
14
+ Simple to use and working offline, it does not require any modification to
15
+ your app (e.g., no need to change the log format, no cookies, no JavaScript
16
+ code, no infrastructure to setup).
17
+
18
+ We use it to monitor our applications in production, using a cron job which
19
+ pulls the logs and calls log_sense to generate HTML reports.
20
+ }
11
21
  spec.homepage = "https://github.com/shair-tech/log_sense/"
12
22
  spec.license = "MIT"
13
23
  spec.required_ruby_version = Gem::Requirement.new(">= 2.6.9")
@@ -26,15 +36,17 @@ Gem::Specification.new do |spec|
26
36
  spec.bindir = "exe"
27
37
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
38
  spec.require_paths = ["lib"]
29
-
30
- spec.add_dependency "browser", "~> 5.3.0"
39
+
40
+ spec.add_dependency "ostruct"
41
+ spec.add_dependency "csv"
42
+ spec.add_dependency "browser", "~> 6.0.0"
31
43
  spec.add_dependency "ipaddr", "~> 1.2.0"
32
44
  spec.add_dependency "iso_country_codes", "~> 0.7.0"
33
- spec.add_dependency "sqlite3", "~> 2.0.0"
34
- spec.add_dependency "terminal-table", "~> 3.0.0"
45
+ spec.add_dependency "sqlite3", "~> 2.6.0"
46
+ spec.add_dependency "terminal-table", "~> 4.0.0"
35
47
 
36
- spec.add_development_dependency "debug", "~> 1.9.0"
48
+ spec.add_development_dependency "debug"
37
49
  spec.add_development_dependency "rubocop"
38
50
  spec.add_development_dependency "bundle-audit"
39
- spec.add_development_dependency "minitest", "~> 5.24.0"
51
+ spec.add_development_dependency "minitest"
40
52
  end
metadata CHANGED
@@ -1,29 +1,56 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: log_sense
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adolfo Villafiorita
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-02-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ostruct
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: csv
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
13
40
  - !ruby/object:Gem::Dependency
14
41
  name: browser
15
42
  requirement: !ruby/object:Gem::Requirement
16
43
  requirements:
17
44
  - - "~>"
18
45
  - !ruby/object:Gem::Version
19
- version: 5.3.0
46
+ version: 6.0.0
20
47
  type: :runtime
21
48
  prerelease: false
22
49
  version_requirements: !ruby/object:Gem::Requirement
23
50
  requirements:
24
51
  - - "~>"
25
52
  - !ruby/object:Gem::Version
26
- version: 5.3.0
53
+ version: 6.0.0
27
54
  - !ruby/object:Gem::Dependency
28
55
  name: ipaddr
29
56
  requirement: !ruby/object:Gem::Requirement
@@ -58,42 +85,42 @@ dependencies:
58
85
  requirements:
59
86
  - - "~>"
60
87
  - !ruby/object:Gem::Version
61
- version: 2.0.0
88
+ version: 2.6.0
62
89
  type: :runtime
63
90
  prerelease: false
64
91
  version_requirements: !ruby/object:Gem::Requirement
65
92
  requirements:
66
93
  - - "~>"
67
94
  - !ruby/object:Gem::Version
68
- version: 2.0.0
95
+ version: 2.6.0
69
96
  - !ruby/object:Gem::Dependency
70
97
  name: terminal-table
71
98
  requirement: !ruby/object:Gem::Requirement
72
99
  requirements:
73
100
  - - "~>"
74
101
  - !ruby/object:Gem::Version
75
- version: 3.0.0
102
+ version: 4.0.0
76
103
  type: :runtime
77
104
  prerelease: false
78
105
  version_requirements: !ruby/object:Gem::Requirement
79
106
  requirements:
80
107
  - - "~>"
81
108
  - !ruby/object:Gem::Version
82
- version: 3.0.0
109
+ version: 4.0.0
83
110
  - !ruby/object:Gem::Dependency
84
111
  name: debug
85
112
  requirement: !ruby/object:Gem::Requirement
86
113
  requirements:
87
- - - "~>"
114
+ - - ">="
88
115
  - !ruby/object:Gem::Version
89
- version: 1.9.0
116
+ version: '0'
90
117
  type: :development
91
118
  prerelease: false
92
119
  version_requirements: !ruby/object:Gem::Requirement
93
120
  requirements:
94
- - - "~>"
121
+ - - ">="
95
122
  - !ruby/object:Gem::Version
96
- version: 1.9.0
123
+ version: '0'
97
124
  - !ruby/object:Gem::Dependency
98
125
  name: rubocop
99
126
  requirement: !ruby/object:Gem::Requirement
@@ -126,18 +153,24 @@ dependencies:
126
153
  name: minitest
127
154
  requirement: !ruby/object:Gem::Requirement
128
155
  requirements:
129
- - - "~>"
156
+ - - ">="
130
157
  - !ruby/object:Gem::Version
131
- version: 5.24.0
158
+ version: '0'
132
159
  type: :development
133
160
  prerelease: false
134
161
  version_requirements: !ruby/object:Gem::Requirement
135
162
  requirements:
136
- - - "~>"
163
+ - - ">="
137
164
  - !ruby/object:Gem::Version
138
- version: 5.24.0
139
- description: Generate analytics in HTML, txt, and SQLite format for Rails and Apache/Nginx
140
- log files.
165
+ version: '0'
166
+ description: "log_sense is a command-line command which analyzes Rails and Nginx logs
167
+ and\n provides detailed data about accesses, performances, and errors. It is
168
+ a\n one stop shop solution for analyzing your Rails application in production.\n\n
169
+ \ Simple to use and working offline, it does not require any modification to\n
170
+ \ your app (e.g., no need to change the log format, no cookies, no JavaScript\n
171
+ \ code, no infrastructure to setup).\n\n We use it to monitor our applications
172
+ in production, using a cron job which\n pulls the logs and calls log_sense to
173
+ generate HTML reports.\n "
141
174
  email:
142
175
  - adolfo@shair.tech
143
176
  executables:
@@ -203,7 +236,6 @@ metadata:
203
236
  homepage_uri: https://github.com/shair-tech/log_sense/
204
237
  source_code_uri: https://github.com/shair-tech/log_sense/
205
238
  changelog_uri: https://github.com/shair-tech/log_sense/blob/main/CHANGELOG.org
206
- post_install_message:
207
239
  rdoc_options: []
208
240
  require_paths:
209
241
  - lib
@@ -218,8 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
250
  - !ruby/object:Gem::Version
219
251
  version: '0'
220
252
  requirements: []
221
- rubygems_version: 3.5.22
222
- signing_key:
253
+ rubygems_version: 3.6.7
223
254
  specification_version: 4
224
- summary: Generate analytics for Rails and Apache/Nginx log file.
255
+ summary: Analyze Rails and Apache/Nginx log file, generating statistics and reports.
225
256
  test_files: []