custom_log_space 0.1.0 → 0.1.2
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 +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +8 -1
- data/README.md +33 -2
- data/lib/custom_log_space/base_subscriber.rb +11 -100
- data/lib/custom_log_space/log_formatter.rb +20 -0
- data/lib/custom_log_space/log_writer.rb +107 -0
- data/lib/custom_log_space/thread_manager.rb +39 -0
- data/lib/custom_log_space/version.rb +1 -1
- data/lib/custom_log_space/view_subscriber.rb +1 -0
- metadata +5 -3
- data/sig/change_rails_log_path.rbs +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d0e3ad542c322fac2dae3da5cb1777a9ca18f6e60725e7886bf1bc21df9dce9
|
4
|
+
data.tar.gz: 6b97fca2a8072335da8a712fc9884a7b7665a211d811dd51eb2e829126e8e6b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7a9bb6be97c059b281c76d58dda57f495125b05aa2cb406d5a1d348ed06b28299a77f4b8e24ce4c98b832745c932caef0fcfb5858a268e9013594e0414004eb
|
7
|
+
data.tar.gz: 3311eff79f825be74b425a762ce1cd130c3ba4e20859cf08d46b21d2e5990edc51c1240a50233491c283317b75282e227a9e195ce87a55dc87fbcad245accc2a
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
## [0.1.
|
3
|
+
## [0.1.2] - 2023-09-15
|
4
|
+
### Changed
|
5
|
+
Modified the file path structure for logs. New structure: log/custom_log_space/#{controller_name}/#{action_name}/#{date}/#{time}.log.
|
6
|
+
|
7
|
+
## [0.1.1] - 2023-09-13
|
8
|
+
### Added
|
9
|
+
- Added `cleanup_old_directories` method to manage and delete old directories, ensuring only the two most recent date-directories remain.
|
4
10
|
|
11
|
+
## [0.1.0] - 2023-09-12
|
5
12
|
- Initial release
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
The CustomLogSpace gem allows Rails developers to direct Rails logs to files, organized by each controller and action. This organization simplifies debugging and analysis.
|
4
4
|
|
5
|
+
Thanks to this gem, developers are freed from the hassle of constantly starting the rails server to check logs every time an action in a controller is executed.
|
6
|
+
|
5
7
|
## Installation
|
6
8
|
|
7
9
|
To begin, add the gem to your application's Gemfile:
|
@@ -25,10 +27,39 @@ $ gem install custom_log_space
|
|
25
27
|
```
|
26
28
|
|
27
29
|
## Usage
|
28
|
-
Logs are saved in the `log/custom_log_space
|
30
|
+
Logs are saved in the `log/custom_log_space/#{controller_name}/#{action_name}/#{date}/#{time}.log`.
|
31
|
+
|
32
|
+
```
|
33
|
+
user log % tree
|
34
|
+
.
|
35
|
+
├── custom_log_space
|
36
|
+
│ └── articles_controller
|
37
|
+
│ ├── index
|
38
|
+
│ │ ├── 2023-09-14
|
39
|
+
│ │ │ ├── 08:45.log
|
40
|
+
│ │ │ └── 08:46.log
|
41
|
+
│ │ └── 2023-09-15
|
42
|
+
│ │ ├── 02:10.log
|
43
|
+
│ │ ├── 08:10.log
|
44
|
+
│ │ └── 08:11.log
|
45
|
+
│ ├── new
|
46
|
+
│ │ └── 2023-09-14
|
47
|
+
│ │ └── 08:45.log
|
48
|
+
│ └── show
|
49
|
+
│ └── 2023-09-15
|
50
|
+
│ └── 02:10.log
|
51
|
+
└── development.log
|
52
|
+
```
|
29
53
|
|
30
|
-
|
54
|
+
## Retention Policy
|
31
55
|
|
56
|
+
To prevent excessive disk usage, logs within the `date` directory are retained for only 3 days. Any logs older than this retention period will be automatically deleted, starting with the oldest. Ensure that you archive or backup logs if you need them for longer periods.
|
57
|
+
|
58
|
+
## Ignoring Logs in Git
|
59
|
+
If needed, add `/log/custom_log_space/*` to your `.gitignore` to ensure the logs aren't committed to your repository.
|
60
|
+
```
|
61
|
+
/log/custom_log_space/*
|
62
|
+
```
|
32
63
|
|
33
64
|
## Supported environments
|
34
65
|
- Rails 7
|
@@ -1,114 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "custom_log_space/log_formatter"
|
4
|
+
require "custom_log_space/thread_manager"
|
5
|
+
require "custom_log_space/log_writer"
|
6
|
+
|
3
7
|
module CustomLogSpace
|
4
8
|
# CustomLogSpace::Subscriber is a class for handling custom logging in Rails applications.
|
5
9
|
# It provides methods for processing different types of log events and organizing log messages.
|
10
|
+
# https://github.com/rails/rails/blob/7-0-stable/activesupport/lib/active_support/log_subscriber.rb
|
6
11
|
class BaseSubscriber < ActiveSupport::LogSubscriber
|
12
|
+
include CustomLogSpace::LogWriter
|
13
|
+
include CustomLogSpace::LogFormatter
|
14
|
+
|
7
15
|
def start_processing(event)
|
8
|
-
|
16
|
+
ThreadManager.setup(event.payload)
|
9
17
|
end
|
10
18
|
|
11
19
|
def process_action(event)
|
12
|
-
|
13
|
-
status = payload[:status]
|
14
|
-
duration = event.duration.round(2)
|
15
|
-
view_runtime = payload[:view_runtime]&.round(2)
|
16
|
-
db_runtime = payload[:db_runtime]&.round(2)
|
17
|
-
allocations = event.allocations
|
18
|
-
|
19
|
-
message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{duration}ms " \
|
20
|
-
"(Views: #{view_runtime}ms | ActiveRecord: #{db_runtime}ms | Allocations: #{allocations})"
|
21
|
-
|
20
|
+
message = format_message(event)
|
22
21
|
log_message(message)
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def setup_thread_variables(payload)
|
29
|
-
Thread.current[:current_controller] = payload[:controller]
|
30
|
-
Thread.current[:current_action] = payload[:action]
|
31
|
-
Thread.current[:path] = payload[:path]
|
32
|
-
Thread.current[:params] = payload[:params].except(:controller, :action)
|
33
|
-
Thread.current[:header_written] = false
|
34
|
-
end
|
35
|
-
|
36
|
-
def clear_thread_variables
|
37
|
-
Thread.current[:current_controller] = nil
|
38
|
-
Thread.current[:current_action] = nil
|
39
|
-
Thread.current[:path] = nil
|
40
|
-
Thread.current[:params] = nil
|
41
|
-
Thread.current[:header_written] = nil
|
42
|
-
end
|
43
|
-
|
44
|
-
def log_message(message)
|
45
|
-
current_controller = Thread.current[:current_controller]
|
46
|
-
current_action = Thread.current[:current_action]
|
47
|
-
|
48
|
-
return unless current_controller && current_action
|
49
|
-
|
50
|
-
FileUtils.mkdir_p(controller_log_directory) unless Dir.exist?(controller_log_directory)
|
51
|
-
write_to_custom_log(message)
|
52
|
-
end
|
53
|
-
|
54
|
-
def custom_log_directory
|
55
|
-
today = Time.now.strftime("%Y%m%d")
|
56
|
-
time = Time.now.strftime("%H%M")
|
57
|
-
File.join(Rails.root, "log", "custom_log_space", today, time)
|
58
|
-
end
|
59
|
-
|
60
|
-
def controller_log_directory
|
61
|
-
controller_name = Thread.current[:current_controller].underscore
|
62
|
-
File.join(custom_log_directory, controller_name)
|
63
|
-
end
|
64
|
-
|
65
|
-
def custom_log_file_path
|
66
|
-
action_name = Thread.current[:current_action]
|
67
|
-
log_file_name = "#{action_name}.log"
|
68
|
-
File.join(controller_log_directory, log_file_name)
|
69
|
-
end
|
70
|
-
|
71
|
-
def write_to_custom_log(message)
|
72
|
-
custom_log_path = custom_log_file_path
|
73
|
-
|
74
|
-
File.open(custom_log_path, "a") do |file|
|
75
|
-
write_header_information(file)
|
76
|
-
file.puts(message)
|
77
|
-
end
|
78
|
-
rescue SystemCallError, IOError => e
|
79
|
-
handle_file_error(e)
|
80
|
-
end
|
81
|
-
|
82
|
-
def handle_file_error(error)
|
83
|
-
error_prefix = error.is_a?(SystemCallError) ? "Error" : "IO Error"
|
84
|
-
puts "#{error_prefix}: #{error.message}"
|
85
|
-
end
|
86
|
-
|
87
|
-
def write_header_information(file)
|
88
|
-
return if Thread.current[:header_written]
|
89
|
-
|
90
|
-
current_controller = Thread.current[:current_controller]
|
91
|
-
current_action = Thread.current[:current_action]
|
92
|
-
|
93
|
-
file.puts("") # Add a blank line for better readability.
|
94
|
-
write_request_info(file)
|
95
|
-
write_processing_info(file, current_controller, current_action)
|
96
|
-
write_parameters_info(file)
|
97
|
-
Thread.current[:header_written] = true
|
98
|
-
end
|
99
|
-
|
100
|
-
def write_request_info(file)
|
101
|
-
formatted_time = Time.now.strftime("%Y-%m-%d %H:%M:%S %z")
|
102
|
-
file.puts "Started GET \"#{Thread.current[:path]}\" for ::1 at #{formatted_time}"
|
103
|
-
end
|
104
|
-
|
105
|
-
def write_processing_info(file, current_controller, current_action)
|
106
|
-
file.puts "Processing by #{current_controller}##{current_action} as HTML"
|
107
|
-
end
|
108
|
-
|
109
|
-
def write_parameters_info(file)
|
110
|
-
params = Thread.current[:params] || {}
|
111
|
-
file.puts "Parameters: #{params.inspect}" unless params.empty?
|
22
|
+
ThreadManager.clear
|
112
23
|
end
|
113
24
|
end
|
114
25
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CustomLogSpace
|
4
|
+
# The LogFormatter module is responsible for formatting log messages.
|
5
|
+
module LogFormatter
|
6
|
+
private
|
7
|
+
|
8
|
+
def format_message(event)
|
9
|
+
payload = event.payload
|
10
|
+
status = payload[:status]
|
11
|
+
duration = event.duration.round(2)
|
12
|
+
view_runtime = payload[:view_runtime]&.round(2)
|
13
|
+
db_runtime = payload[:db_runtime]&.round(2)
|
14
|
+
allocations = event.allocations
|
15
|
+
|
16
|
+
"Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{duration}ms " \
|
17
|
+
"(Views: #{view_runtime}ms | ActiveRecord: #{db_runtime}ms | Allocations: #{allocations})"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CustomLogSpace
|
4
|
+
# The LogWriter module provides methods for writing log messages to custom log files.
|
5
|
+
# It allows the creation of log directories, handling file errors, and appending messages to log files.
|
6
|
+
module LogWriter
|
7
|
+
private
|
8
|
+
|
9
|
+
def log_message(message)
|
10
|
+
current_controller = Thread.current[:current_controller]
|
11
|
+
current_action = Thread.current[:current_action]
|
12
|
+
|
13
|
+
return unless current_controller && current_action
|
14
|
+
|
15
|
+
write_to_custom_log(message) do |file|
|
16
|
+
write_header_information(file)
|
17
|
+
end
|
18
|
+
|
19
|
+
cleanup_old_directories
|
20
|
+
end
|
21
|
+
|
22
|
+
def cleanup_old_directories
|
23
|
+
return unless Dir.exist?(action_directory)
|
24
|
+
|
25
|
+
# If there are more than 3 date-directories, remove the oldest ones
|
26
|
+
remove_oldest_directory while all_directories.size > 3
|
27
|
+
end
|
28
|
+
|
29
|
+
def all_directories
|
30
|
+
@all_directories ||= Dir.entries(action_directory).select do |entry|
|
31
|
+
File.directory?(File.join(action_directory, entry)) && entry !~ /^\./
|
32
|
+
end.sort
|
33
|
+
end
|
34
|
+
|
35
|
+
def remove_oldest_directory
|
36
|
+
directory_to_remove = all_directories.shift
|
37
|
+
path_to_remove = File.join(action_directory, directory_to_remove)
|
38
|
+
FileUtils.rm_rf(path_to_remove)
|
39
|
+
end
|
40
|
+
|
41
|
+
def action_directory
|
42
|
+
@action_directory ||= begin
|
43
|
+
controller_name = Thread.current[:current_controller].underscore
|
44
|
+
action_name = Thread.current[:current_action]
|
45
|
+
File.join(Rails.root, "log", "custom_log_space", controller_name, action_name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def write_to_custom_log(message)
|
50
|
+
directory_path = log_directory_based_on_format
|
51
|
+
FileUtils.mkdir_p(directory_path) unless Dir.exist?(directory_path)
|
52
|
+
custom_log_path = custom_log_file_path(directory_path)
|
53
|
+
|
54
|
+
File.open(custom_log_path, "a") do |file|
|
55
|
+
yield(file) # Header or other info can be passed and written here
|
56
|
+
file.puts(message)
|
57
|
+
end
|
58
|
+
rescue SystemCallError, IOError => e
|
59
|
+
handle_file_error(e)
|
60
|
+
end
|
61
|
+
|
62
|
+
def handle_file_error(error)
|
63
|
+
error_prefix = error.is_a?(SystemCallError) ? "Error" : "IO Error"
|
64
|
+
puts "#{error_prefix}: #{error.message}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def write_header_information(file)
|
68
|
+
return if Thread.current[:header_written]
|
69
|
+
|
70
|
+
current_controller = Thread.current[:current_controller]
|
71
|
+
current_action = Thread.current[:current_action]
|
72
|
+
|
73
|
+
file.puts("") # Add a blank line for better readability.
|
74
|
+
write_request_info(file)
|
75
|
+
write_processing_info(file, current_controller, current_action)
|
76
|
+
write_parameters_info(file)
|
77
|
+
Thread.current[:header_written] = true
|
78
|
+
end
|
79
|
+
|
80
|
+
def write_request_info(file)
|
81
|
+
formatted_time = Time.now.strftime("%Y-%m-%d %H:%M:%S %z")
|
82
|
+
file.puts "Started GET \"#{Thread.current[:path]}\" for ::1 at #{formatted_time}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def write_processing_info(file, current_controller, current_action)
|
86
|
+
file.puts "Processing by #{current_controller}##{current_action} as HTML"
|
87
|
+
end
|
88
|
+
|
89
|
+
def write_parameters_info(file)
|
90
|
+
params = Thread.current[:params] || {}
|
91
|
+
file.puts "Parameters: #{params.inspect}" unless params.empty?
|
92
|
+
end
|
93
|
+
|
94
|
+
def custom_log_file_path(directory_path)
|
95
|
+
time = Time.now.strftime("%H:%M")
|
96
|
+
"#{directory_path}/#{time}.log"
|
97
|
+
end
|
98
|
+
|
99
|
+
def log_directory_based_on_format
|
100
|
+
controller_name = Thread.current[:current_controller].underscore
|
101
|
+
action_name = Thread.current[:current_action]
|
102
|
+
date = Time.now.strftime("%Y-%m-%d")
|
103
|
+
|
104
|
+
File.join(Rails.root, "log", "custom_log_space", controller_name, action_name, date)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CustomLogSpace
|
4
|
+
# The ThreadManager class provides methods for managing thread-local variables related to logging in a Rails application.
|
5
|
+
# It is responsible for setting up and clearing thread-local variables such as controller, action, path, params, and header_written.
|
6
|
+
class ThreadManager
|
7
|
+
# https://railsguides.jp/v6.1/active_support_instrumentation.html#start-processing-action-controller
|
8
|
+
# Sets up thread-local variables based on the provided payload.
|
9
|
+
#
|
10
|
+
# @param payload [Hash] The payload containing information about the current request.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# payload = {
|
15
|
+
# controller: 'HomeController',
|
16
|
+
# action: 'index',
|
17
|
+
# path: '/home',
|
18
|
+
# params: { id: 1, page: 2 }
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# CustomLogSpace::ThreadManager.setup(payload)
|
22
|
+
#
|
23
|
+
def self.setup(payload)
|
24
|
+
Thread.current[:current_controller] = payload[:controller]
|
25
|
+
Thread.current[:current_action] = payload[:action]
|
26
|
+
Thread.current[:path] = payload[:path]
|
27
|
+
Thread.current[:params] = payload[:params].except(:controller, :action)
|
28
|
+
Thread.current[:header_written] = false
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.clear
|
32
|
+
Thread.current[:current_controller] = nil
|
33
|
+
Thread.current[:current_action] = nil
|
34
|
+
Thread.current[:path] = nil
|
35
|
+
Thread.current[:params] = nil
|
36
|
+
Thread.current[:header_written] = nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
# ViewSubscriber logs view rendering events for CustomLogSpace.
|
4
4
|
# It tracks events like template rendering, partial rendering, and collection rendering.
|
5
|
+
# https://github.com/rails/rails/blob/7-0-stable/actionview/lib/action_view/log_subscriber.rb
|
5
6
|
class ViewSubscriber < CustomLogSpace::BaseSubscriber
|
6
7
|
def render_template(event)
|
7
8
|
identifier = event.payload[:identifier]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: custom_log_space
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nishikawa1031
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -48,10 +48,12 @@ files:
|
|
48
48
|
- custom_log_space.gemspec
|
49
49
|
- lib/custom_log_space.rb
|
50
50
|
- lib/custom_log_space/base_subscriber.rb
|
51
|
+
- lib/custom_log_space/log_formatter.rb
|
52
|
+
- lib/custom_log_space/log_writer.rb
|
51
53
|
- lib/custom_log_space/sql_subscriber.rb
|
54
|
+
- lib/custom_log_space/thread_manager.rb
|
52
55
|
- lib/custom_log_space/version.rb
|
53
56
|
- lib/custom_log_space/view_subscriber.rb
|
54
|
-
- sig/change_rails_log_path.rbs
|
55
57
|
- sig/custom_log_space.rbs
|
56
58
|
homepage: https://github.com/nishikawa1031/custom_log_space.git
|
57
59
|
licenses:
|