log_bench 0.1.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 +7 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +230 -0
- data/Rakefile +10 -0
- data/exe/log_bench +87 -0
- data/lib/log_bench/app/filter.rb +60 -0
- data/lib/log_bench/app/input_handler.rb +245 -0
- data/lib/log_bench/app/main.rb +96 -0
- data/lib/log_bench/app/monitor.rb +59 -0
- data/lib/log_bench/app/renderer/ansi.rb +176 -0
- data/lib/log_bench/app/renderer/details.rb +488 -0
- data/lib/log_bench/app/renderer/header.rb +99 -0
- data/lib/log_bench/app/renderer/main.rb +30 -0
- data/lib/log_bench/app/renderer/request_list.rb +211 -0
- data/lib/log_bench/app/renderer/scrollbar.rb +38 -0
- data/lib/log_bench/app/screen.rb +96 -0
- data/lib/log_bench/app/sort.rb +61 -0
- data/lib/log_bench/app/state.rb +175 -0
- data/lib/log_bench/json_formatter.rb +92 -0
- data/lib/log_bench/log/cache_entry.rb +82 -0
- data/lib/log_bench/log/call_line_entry.rb +60 -0
- data/lib/log_bench/log/collection.rb +98 -0
- data/lib/log_bench/log/entry.rb +108 -0
- data/lib/log_bench/log/file.rb +103 -0
- data/lib/log_bench/log/parser.rb +64 -0
- data/lib/log_bench/log/query_entry.rb +132 -0
- data/lib/log_bench/log/request.rb +90 -0
- data/lib/log_bench/railtie.rb +45 -0
- data/lib/log_bench/version.rb +5 -0
- data/lib/log_bench.rb +26 -0
- data/lib/tasks/log_bench.rake +97 -0
- data/logbench-preview.png +0 -0
- metadata +171 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LogBench
|
4
|
+
module Log
|
5
|
+
class Request < Entry
|
6
|
+
attr_reader :method, :path, :status, :duration, :controller, :action
|
7
|
+
attr_accessor :related_logs
|
8
|
+
|
9
|
+
def initialize(raw_line)
|
10
|
+
super
|
11
|
+
self.related_logs = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.build(raw_line)
|
15
|
+
return unless parseable?(raw_line)
|
16
|
+
|
17
|
+
entry = Entry.new(raw_line)
|
18
|
+
return unless entry.http_request?
|
19
|
+
|
20
|
+
new(raw_line)
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_related_log(log_entry)
|
24
|
+
related_logs << log_entry if log_entry.related_log?
|
25
|
+
self.related_logs = related_logs.sort_by(&:timestamp)
|
26
|
+
end
|
27
|
+
|
28
|
+
def queries
|
29
|
+
related_logs.select { |log| log.is_a?(QueryEntry) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def cache_operations
|
33
|
+
related_logs.select { |log| log.is_a?(CacheEntry) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def query_count
|
37
|
+
queries.size
|
38
|
+
end
|
39
|
+
|
40
|
+
def total_query_time
|
41
|
+
queries.sum(&:duration_ms)
|
42
|
+
end
|
43
|
+
|
44
|
+
def cached_query_count
|
45
|
+
cache_operations.size
|
46
|
+
end
|
47
|
+
|
48
|
+
def success?
|
49
|
+
status && status >= 200 && status < 300
|
50
|
+
end
|
51
|
+
|
52
|
+
def client_error?
|
53
|
+
status && status >= 400 && status < 500
|
54
|
+
end
|
55
|
+
|
56
|
+
def server_error?
|
57
|
+
status && status >= 500
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_h
|
61
|
+
super.merge(
|
62
|
+
method: method,
|
63
|
+
path: path,
|
64
|
+
status: status,
|
65
|
+
duration: duration,
|
66
|
+
controller: controller,
|
67
|
+
action: action,
|
68
|
+
related_logs: related_logs.map(&:to_h)
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
attr_writer :method, :path, :status, :duration, :controller, :action
|
75
|
+
|
76
|
+
def extract_from_json(data)
|
77
|
+
return false unless super
|
78
|
+
|
79
|
+
self.method = data["method"]
|
80
|
+
self.path = data["path"]
|
81
|
+
self.status = data["status"]
|
82
|
+
self.duration = data["duration"]
|
83
|
+
self.controller = data["controller"]
|
84
|
+
self.action = data["action"]
|
85
|
+
self.request_id = data["request_id"]
|
86
|
+
true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "rails/railtie"
|
2
|
+
|
3
|
+
module LogBench
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
railtie_name :log_bench
|
6
|
+
|
7
|
+
# Add LogBench generators to Rails
|
8
|
+
generators do
|
9
|
+
require "generators/log_bench/install_generator"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Provide helpful rake tasks
|
13
|
+
rake_tasks do
|
14
|
+
load "tasks/log_bench.rake"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Show installation instructions when Rails starts in development
|
18
|
+
initializer "log_bench.show_instructions", after: :load_config_initializers do
|
19
|
+
if Rails.env.development?
|
20
|
+
# Check if lograge is properly configured
|
21
|
+
puts "\n" + "=" * 70
|
22
|
+
puts "\n" + "=" * 70
|
23
|
+
if Rails.application.config.respond_to?(:lograge) &&
|
24
|
+
Rails.application.config.lograge.enabled
|
25
|
+
puts "✅ LogBench is ready to use!"
|
26
|
+
puts "=" * 70
|
27
|
+
puts "View your logs: bundle exec log_bench log/development.log"
|
28
|
+
else
|
29
|
+
|
30
|
+
puts "🚀 LogBench is ready to configure!"
|
31
|
+
puts "=" * 70
|
32
|
+
puts "To start using LogBench:"
|
33
|
+
puts " 1. Configure lograge: bundle exec rails generate log_bench:install"
|
34
|
+
puts " 2. Restart your Rails server"
|
35
|
+
puts " 3. Make some requests to generate logs"
|
36
|
+
puts " 4. View logs: bundle exec log_bench log/development.log"
|
37
|
+
puts
|
38
|
+
end
|
39
|
+
puts "For help: bundle exec log_bench --help"
|
40
|
+
puts "=" * 70 + "\n"
|
41
|
+
puts "=" * 70 + "\n"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/log_bench.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "zeitwerk"
|
4
|
+
require "json"
|
5
|
+
require "time"
|
6
|
+
require "curses"
|
7
|
+
require_relative "log_bench/version"
|
8
|
+
|
9
|
+
loader = Zeitwerk::Loader.for_gem
|
10
|
+
loader.ignore("#{__dir__}/generators")
|
11
|
+
loader.setup
|
12
|
+
|
13
|
+
module LogBench
|
14
|
+
class Error < StandardError; end
|
15
|
+
|
16
|
+
# Parse log lines and return an array of entries
|
17
|
+
def self.parse(lines)
|
18
|
+
lines = [lines] if lines.is_a?(String)
|
19
|
+
|
20
|
+
collection = Log::Collection.new(lines)
|
21
|
+
collection.requests
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Load Railtie if Rails is available
|
26
|
+
require "log_bench/railtie" if defined?(Rails)
|
@@ -0,0 +1,97 @@
|
|
1
|
+
namespace :log_bench do
|
2
|
+
desc "Install and configure LogBench with lograge"
|
3
|
+
task :install do
|
4
|
+
puts "Installing LogBench configuration..."
|
5
|
+
|
6
|
+
if defined?(Rails)
|
7
|
+
# Run the Rails generator
|
8
|
+
system("rails generate log_bench:install")
|
9
|
+
else
|
10
|
+
puts "This task should be run from a Rails application directory."
|
11
|
+
puts "Alternatively, run: rails generate log_bench:install"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Check LogBench configuration"
|
16
|
+
task check: :environment do
|
17
|
+
puts "\n" + "=" * 60
|
18
|
+
puts "🔍 LogBench Configuration Check"
|
19
|
+
puts "=" * 60
|
20
|
+
|
21
|
+
if Rails.application.config.respond_to?(:lograge) &&
|
22
|
+
Rails.application.config.lograge.enabled
|
23
|
+
puts "✅ Lograge is enabled"
|
24
|
+
|
25
|
+
if Rails.application.config.lograge.formatter.is_a?(Lograge::Formatters::Json)
|
26
|
+
puts "✅ JSON formatter is configured"
|
27
|
+
else
|
28
|
+
puts "⚠️ JSON formatter is not configured"
|
29
|
+
puts " LogBench requires JSON format"
|
30
|
+
puts " Run: rails generate log_bench:install"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Check if log file exists and has content
|
34
|
+
log_file = "log/#{Rails.env}.log"
|
35
|
+
if File.exist?(log_file) && File.size(log_file) > 0
|
36
|
+
puts "✅ Log file exists: #{log_file}"
|
37
|
+
else
|
38
|
+
puts "⚠️ Log file is empty or doesn't exist: #{log_file}"
|
39
|
+
puts " Make some requests to generate logs"
|
40
|
+
end
|
41
|
+
|
42
|
+
puts
|
43
|
+
puts "🎉 LogBench is ready to use!"
|
44
|
+
puts " Command: bundle exec log_bench #{log_file}"
|
45
|
+
else
|
46
|
+
puts "❌ Lograge is not enabled"
|
47
|
+
puts
|
48
|
+
puts "To fix this:"
|
49
|
+
puts " 1. Run: bundle exec rails generate log_bench:install"
|
50
|
+
puts " 2. Restart your Rails server"
|
51
|
+
puts " 3. Make some requests"
|
52
|
+
puts " 4. Run: bundle exec log_bench log/development.log"
|
53
|
+
end
|
54
|
+
puts "=" * 60 + "\n"
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "Show LogBench usage instructions"
|
58
|
+
task :help do
|
59
|
+
puts <<~HELP
|
60
|
+
LogBench - Rails Log Viewer
|
61
|
+
|
62
|
+
Installation:
|
63
|
+
1. Add to your Gemfile (development group):
|
64
|
+
gem 'log_bench', group: :development
|
65
|
+
|
66
|
+
2. Run bundle install:
|
67
|
+
bundle install
|
68
|
+
|
69
|
+
3. Configure lograge:
|
70
|
+
rails generate log_bench:install
|
71
|
+
|
72
|
+
4. Restart your Rails server
|
73
|
+
|
74
|
+
Usage:
|
75
|
+
# View current development log
|
76
|
+
log_bench
|
77
|
+
|
78
|
+
# View specific log file
|
79
|
+
log_bench log/development.log
|
80
|
+
log_bench log/production.log
|
81
|
+
|
82
|
+
# View log file from another directory
|
83
|
+
log_bench /path/to/your/app/log/development.log
|
84
|
+
|
85
|
+
Features:
|
86
|
+
- Real-time log monitoring
|
87
|
+
- Interactive TUI with dual panes
|
88
|
+
- Request filtering and sorting
|
89
|
+
- SQL query analysis
|
90
|
+
- Color-coded HTTP methods and status codes
|
91
|
+
|
92
|
+
Requirements:
|
93
|
+
- Lograge gem with JSON formatter
|
94
|
+
- Rails application logs in lograge format
|
95
|
+
HELP
|
96
|
+
end
|
97
|
+
end
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: log_bench
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Benjamín Silva
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-06-05 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: zeitwerk
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '2.7'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '2.7'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: curses
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.5'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.5'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: lograge
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.14'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.14'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rake
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '13.3'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '13.3'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: minitest
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '5.25'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '5.25'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: standard
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.5'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1.5'
|
96
|
+
description: LogBench is a well-structured Ruby gem for parsing and analyzing Rails
|
97
|
+
log files with a focus on lograge format. Features include real-time log monitoring,
|
98
|
+
interactive TUI with filtering and sorting, domain objects for clean code organization,
|
99
|
+
and support for SQL query analysis.
|
100
|
+
executables:
|
101
|
+
- log_bench
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".standard.yml"
|
106
|
+
- CHANGELOG.md
|
107
|
+
- CODE_OF_CONDUCT.md
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- exe/log_bench
|
112
|
+
- lib/log_bench.rb
|
113
|
+
- lib/log_bench/app/filter.rb
|
114
|
+
- lib/log_bench/app/input_handler.rb
|
115
|
+
- lib/log_bench/app/main.rb
|
116
|
+
- lib/log_bench/app/monitor.rb
|
117
|
+
- lib/log_bench/app/renderer/ansi.rb
|
118
|
+
- lib/log_bench/app/renderer/details.rb
|
119
|
+
- lib/log_bench/app/renderer/header.rb
|
120
|
+
- lib/log_bench/app/renderer/main.rb
|
121
|
+
- lib/log_bench/app/renderer/request_list.rb
|
122
|
+
- lib/log_bench/app/renderer/scrollbar.rb
|
123
|
+
- lib/log_bench/app/screen.rb
|
124
|
+
- lib/log_bench/app/sort.rb
|
125
|
+
- lib/log_bench/app/state.rb
|
126
|
+
- lib/log_bench/json_formatter.rb
|
127
|
+
- lib/log_bench/log/cache_entry.rb
|
128
|
+
- lib/log_bench/log/call_line_entry.rb
|
129
|
+
- lib/log_bench/log/collection.rb
|
130
|
+
- lib/log_bench/log/entry.rb
|
131
|
+
- lib/log_bench/log/file.rb
|
132
|
+
- lib/log_bench/log/parser.rb
|
133
|
+
- lib/log_bench/log/query_entry.rb
|
134
|
+
- lib/log_bench/log/request.rb
|
135
|
+
- lib/log_bench/railtie.rb
|
136
|
+
- lib/log_bench/version.rb
|
137
|
+
- lib/tasks/log_bench.rake
|
138
|
+
- logbench-preview.png
|
139
|
+
homepage: https://github.com/silva96/log_bench
|
140
|
+
licenses:
|
141
|
+
- MIT
|
142
|
+
metadata:
|
143
|
+
allowed_push_host: https://rubygems.org
|
144
|
+
homepage_uri: https://github.com/silva96/log_bench
|
145
|
+
source_code_uri: https://github.com/silva96/log_bench
|
146
|
+
changelog_uri: https://github.com/silva96/log_bench/blob/main/CHANGELOG.md
|
147
|
+
bug_tracker_uri: https://github.com/silva96/log_bench/issues
|
148
|
+
documentation_uri: https://github.com/silva96/log_bench/blob/main/README.md
|
149
|
+
post_install_message: "\n\U0001F389 LogBench installed successfully!\n\nNext steps:\n1.
|
150
|
+
Configure Rails (see README.md for setup instructions)\n2. Restart your Rails server\n3.
|
151
|
+
Make some requests to generate logs\n4. View logs: bundle exec log_bench log/development.log\n\nFor
|
152
|
+
help: bundle exec log_bench --help\nDocumentation: https://github.com/silva96/log_bench\n\n"
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: 3.1.0
|
161
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirements: []
|
167
|
+
rubygems_version: 3.6.2
|
168
|
+
specification_version: 4
|
169
|
+
summary: A terminal-based Rails log viewer with real-time monitoring and filtering
|
170
|
+
capabilities
|
171
|
+
test_files: []
|