rails-pretty-logger 0.2.9 → 0.3.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 +4 -4
- data/README.md +215 -35
- data/app/assets/javascripts/rails/pretty/logger/application.js +16 -23
- data/app/assets/stylesheets/rails/pretty/logger/application.css +1 -15
- data/app/assets/stylesheets/rails/pretty/logger/dashboards.css +463 -141
- data/app/assets/stylesheets/rails/pretty/logger/list.css +1 -94
- data/app/controllers/rails/pretty/logger/application_controller.rb +31 -0
- data/app/controllers/rails/pretty/logger/dashboards_controller.rb +9 -4
- data/app/controllers/rails/pretty/logger/hourly_logs_controller.rb +36 -4
- data/app/helpers/rails/pretty/logger/application_helper.rb +32 -0
- data/app/helpers/rails/pretty/logger/dashboards_helper.rb +114 -14
- data/app/views/layouts/rails/pretty/logger/application.html.erb +9 -8
- data/app/views/partials/_error_pagination.html.erb +12 -10
- data/app/views/partials/_log_entries.html.erb +5 -0
- data/app/views/partials/_log_filters.html.erb +14 -0
- data/app/views/partials/_pretyyloggernavbar.html.erb +14 -9
- data/app/views/rails/pretty/logger/dashboards/index.html.erb +37 -20
- data/app/views/rails/pretty/logger/dashboards/logs.html.erb +33 -14
- data/app/views/rails/pretty/logger/hourly_logs/index.html.erb +49 -25
- data/app/views/rails/pretty/logger/hourly_logs/logs.html.erb +35 -14
- data/config/locales/rails_pretty_logger.en.yml +35 -0
- data/config/locales/rails_pretty_logger.tr.yml +35 -0
- data/lib/generators/rails_pretty_logger/install/install_generator.rb +29 -0
- data/lib/generators/rails_pretty_logger/install/templates/rails_pretty_logger.rb +20 -0
- data/lib/rails/pretty/logger/active_support_logger.rb +3 -7
- data/lib/rails/pretty/logger/config/logger_config.rb +0 -16
- data/lib/rails/pretty/logger/configuration.rb +18 -0
- data/lib/rails/pretty/logger/console_logger.rb +2 -2
- data/lib/rails/pretty/logger/engine.rb +22 -4
- data/lib/rails/pretty/logger/rails_logger.rb +62 -41
- data/lib/rails/pretty/logger/version.rb +1 -1
- data/lib/rails/pretty/logger.rb +547 -31
- data/lib/tasks/rails/pretty/logger_tasks.rake +36 -23
- metadata +79 -38
- data/Rakefile +0 -22
- data/app/assets/javascripts/rails/pretty/logger/dashboards.js +0 -2
- data/app/assets/javascripts/rails/pretty/logger/list.min.js +0 -2
- data/app/models/rails/pretty/logger/application_record.rb +0 -9
- data/app/assets/config/{rails_pretty_logger_manifest.js → manifest.js} +1 -1
|
@@ -1,33 +1,52 @@
|
|
|
1
|
-
<%= render "partials/pretyyloggernavbar", path_name:
|
|
1
|
+
<%= render "partials/pretyyloggernavbar", path_name: t("rails_pretty_logger.navigation.hourly_logs") %>
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<% unless rails_pretty_logger_tail_mode? %>
|
|
4
|
+
<%= render "partials/error_pagination", log: @log, log_data: @log_data , locals: {path: "logs_dashboards_path"} %>
|
|
5
|
+
<% end %>
|
|
6
|
+
|
|
7
|
+
<div class="form-group log-controls">
|
|
8
|
+
<div class="log-toolbar">
|
|
9
|
+
<% if rails_pretty_logger_tail_mode? %>
|
|
10
|
+
<%= link_to(t("rails_pretty_logger.logs.filtered_view"), logs_dashboards_path(rails_pretty_logger_log_filter_params(include_mode: false).merge(date_range: { start: @log.start_date, end: @log.end_date, divider: set_divider(params) }))) %>
|
|
11
|
+
<% else %>
|
|
12
|
+
<%= link_to(t("rails_pretty_logger.logs.tail_last_lines", count: Rails::Pretty::Logger::PrettyLogger.tail_lines), logs_dashboards_path(rails_pretty_logger_log_filter_params.merge(mode: "tail"))) %>
|
|
13
|
+
<% if rails_pretty_logger_request_grouping? %>
|
|
14
|
+
<%= link_to(t("rails_pretty_logger.logs.plain_lines"), logs_dashboards_path(rails_pretty_logger_log_filter_params(include_group: false).merge(date_range: { start: @log.start_date, end: @log.end_date, divider: set_divider(params) }))) %>
|
|
15
|
+
<% else %>
|
|
16
|
+
<%= link_to(t("rails_pretty_logger.logs.group_requests"), logs_dashboards_path(rails_pretty_logger_log_filter_params.merge(group: "request", date_range: { start: @log.start_date, end: @log.end_date, divider: set_divider(params) }))) %>
|
|
17
|
+
<% end %>
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<%= render "partials/log_filters", path: "logs_dashboards_path" %>
|
|
4
22
|
|
|
5
|
-
<div class="form-group">
|
|
6
23
|
<%= form_for :date_range, url: logs_dashboards_path(log_file: params[:log_file]), method: :post do |f| %>
|
|
24
|
+
<%= hidden_field_tag :query, params[:query] if params[:query].present? %>
|
|
25
|
+
<%= hidden_field_tag :severity, params[:severity] if params[:severity].present? %>
|
|
26
|
+
<%= hidden_field_tag :group, params[:group] if params[:group].present? %>
|
|
7
27
|
<p>
|
|
8
|
-
<%= label(:start,
|
|
28
|
+
<%= label(:start, :title, t("rails_pretty_logger.filters.start_date")) %>
|
|
9
29
|
<%= f.date_field(:start, value: @log.start_date, max: Date.today) %>
|
|
10
|
-
<%= label(:end, :title, "
|
|
30
|
+
<%= label(:end, :title, t("rails_pretty_logger.filters.end_date")) %>
|
|
11
31
|
<%= f.date_field(:end, value: @log.end_date, max: Date.today) %>
|
|
12
|
-
<%= label(:divider, :title, "
|
|
32
|
+
<%= label(:divider, :title, t("rails_pretty_logger.filters.logs_per_page")) %>
|
|
13
33
|
<%= f.number_field(:divider, value: set_divider(params)) %>
|
|
14
|
-
<%= f.submit "
|
|
34
|
+
<%= f.submit t("rails_pretty_logger.actions.submit") %>
|
|
15
35
|
</p>
|
|
16
36
|
<%- end%>
|
|
17
37
|
|
|
18
|
-
<% if @log_data[:logs_count] > 0 %>
|
|
38
|
+
<% if @log_data[:logs_count] > 0 && !rails_pretty_logger_read_only? %>
|
|
19
39
|
<p>
|
|
20
|
-
<%=
|
|
40
|
+
<%= button_to(t("rails_pretty_logger.actions.clear_logs"),
|
|
21
41
|
clear_logs_dashboards_path(log_file: params[:log_file]),
|
|
22
|
-
html_options = {class: "clear_logs",
|
|
23
42
|
method: :post,
|
|
24
|
-
|
|
43
|
+
class: "clear_logs",
|
|
44
|
+
form: { class: "clear_logs_form",
|
|
45
|
+
data: { turbo_confirm: t("rails_pretty_logger.confirmations.clear_all") }}) %>
|
|
25
46
|
</p>
|
|
26
47
|
<% end %>
|
|
27
48
|
</div>
|
|
28
49
|
|
|
29
50
|
<hr>
|
|
30
51
|
|
|
31
|
-
|
|
32
|
-
<%= check_highlight(line) %> <br>
|
|
33
|
-
<% end %>
|
|
52
|
+
<%= render "partials/log_entries", log_data: @log_data %>
|
|
@@ -1,39 +1,63 @@
|
|
|
1
|
-
<%
|
|
2
|
-
<div>
|
|
3
|
-
<h1 class="message"
|
|
1
|
+
<% unless @hourly_logs_present %>
|
|
2
|
+
<div class="empty-state">
|
|
3
|
+
<h1 class="message"><%= t("rails_pretty_logger.states.no_logs") %></h1>
|
|
4
4
|
</div>
|
|
5
5
|
|
|
6
6
|
<% else %>
|
|
7
7
|
|
|
8
8
|
<div class="hourly-list">
|
|
9
|
-
|
|
10
9
|
<div id="hourly">
|
|
11
|
-
|
|
12
10
|
<div class="logger_navbar">
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
</
|
|
16
|
-
|
|
11
|
+
<div class="logger_navbar__heading">
|
|
12
|
+
<h1><%= t("rails_pretty_logger.navigation.hourly_logs") %></h1>
|
|
13
|
+
</div>
|
|
17
14
|
|
|
15
|
+
<nav class="logger_navbar__actions">
|
|
16
|
+
<%= link_to(t("rails_pretty_logger.navigation.main_logs"), dashboards_path, class: "dashboard_button") %>
|
|
17
|
+
</nav>
|
|
18
18
|
</div>
|
|
19
|
-
<input class="search" placeholder="Search" />
|
|
20
|
-
<button class="sort" data-sort="name">
|
|
21
|
-
Sort
|
|
22
|
-
</button>
|
|
23
|
-
<ul class="pagination"></ul>
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
<%= form_with url: hourly_logs_path, method: :get, scope: nil, class: "hourly_filters filter-panel" do |form| %>
|
|
21
|
+
<%= form.label :search, t("rails_pretty_logger.filters.search") %>
|
|
22
|
+
<%= form.search_field :search, value: params[:search], placeholder: t("rails_pretty_logger.filters.search"), class: "search" %>
|
|
23
|
+
<%= form.hidden_field :sort, value: params[:sort] %>
|
|
24
|
+
<%= form.submit t("rails_pretty_logger.filters.search") %>
|
|
25
|
+
<%= link_to(t("rails_pretty_logger.actions.sort", direction: params[:sort] == "desc" ? "asc" : "desc"),
|
|
26
|
+
hourly_logs_path(search: params[:search], sort: params[:sort] == "desc" ? "asc" : "desc"),
|
|
27
|
+
class: "sort") %>
|
|
28
|
+
<% end %>
|
|
29
|
+
|
|
30
|
+
<% if @log_file_list.empty? %>
|
|
31
|
+
<div class="empty-state empty-state--inline">
|
|
32
|
+
<h1 class="message"><%= t("rails_pretty_logger.states.no_logs") %></h1>
|
|
33
|
+
</div>
|
|
34
|
+
<% end %>
|
|
35
|
+
|
|
36
|
+
<ul class="list log-file-list">
|
|
37
|
+
<% @log_file_list.each do |value| %>
|
|
38
|
+
<li class="log-file-row">
|
|
39
|
+
<div class="log-file-row__main">
|
|
40
|
+
<%= link_to(modify_name(value.fetch(:file_name)),
|
|
41
|
+
logs_hourly_logs_path(log_file: value.fetch(:file_name), date_range: { start: time_now, end: time_now }),
|
|
42
|
+
html_options = {class: "name log-file-row__name",
|
|
43
|
+
data: { confirm: t("rails_pretty_logger.confirmations.open_file", size: value.fetch(:file_size)) }}) %>
|
|
44
|
+
<span class="log-file-row__meta"><%= t("rails_pretty_logger.logs.file_size", size: value.fetch(:file_size)) %></span>
|
|
45
|
+
</div>
|
|
46
|
+
</li>
|
|
47
|
+
<% end %>
|
|
36
48
|
</ul>
|
|
49
|
+
|
|
50
|
+
<% if @total_pages > 1 %>
|
|
51
|
+
<ul class="pagination">
|
|
52
|
+
<% 1.upto(@total_pages) do |page| %>
|
|
53
|
+
<li>
|
|
54
|
+
<%= link_to page,
|
|
55
|
+
hourly_logs_path(search: params[:search], sort: params[:sort], page: page),
|
|
56
|
+
class: ("active" if page == @page) %>
|
|
57
|
+
</li>
|
|
58
|
+
<% end %>
|
|
59
|
+
</ul>
|
|
60
|
+
<% end %>
|
|
37
61
|
</div>
|
|
38
62
|
</div>
|
|
39
63
|
<% end %>
|
|
@@ -1,35 +1,56 @@
|
|
|
1
1
|
<div class="logger_navbar">
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<div class="logger_navbar__heading">
|
|
3
|
+
<h1><%= t("rails_pretty_logger.navigation.hourly_logs") %></h1>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<nav class="logger_navbar__actions">
|
|
7
|
+
<%= link_to(t("rails_pretty_logger.navigation.main_logs"), dashboards_path, class: "dashboard_button") %>
|
|
8
|
+
<%= link_to(t("rails_pretty_logger.navigation.hourly_logs"), hourly_logs_path, class: "dashboard_button") %>
|
|
9
|
+
</nav>
|
|
6
10
|
</div>
|
|
7
|
-
|
|
11
|
+
|
|
8
12
|
<% if @log_data[:logs_count] > 0 %>
|
|
9
13
|
|
|
14
|
+
<% unless rails_pretty_logger_tail_mode? %>
|
|
10
15
|
<%= render "partials/error_pagination", log: @log, log_data: @log_data, locals: {path: "logs_hourly_logs_path"} %>
|
|
16
|
+
<% end %>
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
<div class="form-group log-controls">
|
|
19
|
+
<div class="log-toolbar">
|
|
20
|
+
<% if rails_pretty_logger_tail_mode? %>
|
|
21
|
+
<%= link_to(t("rails_pretty_logger.logs.filtered_view"), logs_hourly_logs_path(rails_pretty_logger_log_filter_params(include_mode: false).merge(date_range: { start: @log.start_date, end: @log.end_date, divider: set_divider(params) }))) %>
|
|
22
|
+
<% else %>
|
|
23
|
+
<%= link_to(t("rails_pretty_logger.logs.tail_last_lines", count: Rails::Pretty::Logger::PrettyLogger.tail_lines), logs_hourly_logs_path(rails_pretty_logger_log_filter_params.merge(mode: "tail"))) %>
|
|
24
|
+
<% if rails_pretty_logger_request_grouping? %>
|
|
25
|
+
<%= link_to(t("rails_pretty_logger.logs.plain_lines"), logs_hourly_logs_path(rails_pretty_logger_log_filter_params(include_group: false).merge(date_range: { start: @log.start_date, end: @log.end_date, divider: set_divider(params) }))) %>
|
|
26
|
+
<% else %>
|
|
27
|
+
<%= link_to(t("rails_pretty_logger.logs.group_requests"), logs_hourly_logs_path(rails_pretty_logger_log_filter_params.merge(group: "request", date_range: { start: @log.start_date, end: @log.end_date, divider: set_divider(params) }))) %>
|
|
28
|
+
<% end %>
|
|
29
|
+
<% end %>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<%= render "partials/log_filters", path: "logs_hourly_logs_path" %>
|
|
33
|
+
|
|
34
|
+
<% if @log_data[:logs_count] > 0 && !rails_pretty_logger_read_only? %>
|
|
13
35
|
<p>
|
|
14
|
-
<%=
|
|
36
|
+
<%= button_to(t("rails_pretty_logger.actions.clear_logs"),
|
|
15
37
|
clear_logs_hourly_logs_path(log_file: params[:log_file]),
|
|
16
|
-
html_options = {class: "clear_logs",
|
|
17
38
|
method: :post,
|
|
18
|
-
|
|
39
|
+
class: "clear_logs",
|
|
40
|
+
form: { class: "clear_logs_form",
|
|
41
|
+
data: { turbo_confirm: t("rails_pretty_logger.confirmations.clear_all") }}) %>
|
|
19
42
|
</p>
|
|
20
43
|
<% end %>
|
|
21
44
|
</div>
|
|
22
45
|
|
|
23
46
|
|
|
24
|
-
|
|
47
|
+
<hr>
|
|
25
48
|
|
|
26
|
-
|
|
27
|
-
<%= check_highlight(line) %> <br>
|
|
28
|
-
<% end %>
|
|
49
|
+
<%= render "partials/log_entries", log_data: @log_data %>
|
|
29
50
|
|
|
30
51
|
<% else %>
|
|
31
52
|
|
|
32
53
|
<div>
|
|
33
|
-
<h1 class="message"
|
|
54
|
+
<h1 class="message"><%= t("rails_pretty_logger.states.no_logs") %></h1>
|
|
34
55
|
</div>
|
|
35
56
|
<% end %>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
en:
|
|
2
|
+
rails_pretty_logger:
|
|
3
|
+
actions:
|
|
4
|
+
clear: "Clear"
|
|
5
|
+
clear_logs: "Clear logs"
|
|
6
|
+
sort: "Sort %{direction}"
|
|
7
|
+
submit: "Submit"
|
|
8
|
+
confirmations:
|
|
9
|
+
clear_all: "Are you sure to clear all logs?"
|
|
10
|
+
clear_file: "Are you sure to clear all logs from %{file}?"
|
|
11
|
+
open_file: "Log file size is %{size} MB. Are you sure to open this file?"
|
|
12
|
+
filters:
|
|
13
|
+
clear_filters: "Clear filters"
|
|
14
|
+
end_date: "End Date:"
|
|
15
|
+
filter: "Filter"
|
|
16
|
+
logs_per_page: "Logs per page:"
|
|
17
|
+
search: "Search"
|
|
18
|
+
search_log_content: "Search log content"
|
|
19
|
+
severity: "Severity"
|
|
20
|
+
start_date: "Start Date:"
|
|
21
|
+
logs:
|
|
22
|
+
file_size: "%{size} MB"
|
|
23
|
+
filtered_view: "Filtered view"
|
|
24
|
+
group_requests: "Group requests"
|
|
25
|
+
plain_lines: "Plain lines"
|
|
26
|
+
tail_last_lines: "Tail last %{count} lines"
|
|
27
|
+
ungrouped_lines: "Ungrouped lines"
|
|
28
|
+
navigation:
|
|
29
|
+
hourly_logs: "Hourly logs"
|
|
30
|
+
log_files: "Log files"
|
|
31
|
+
main_logs: "Main logs"
|
|
32
|
+
pagination: "Pagination"
|
|
33
|
+
states:
|
|
34
|
+
no_logs: "There is no log file to show"
|
|
35
|
+
stdout_logging: "RAILS_LOG_TO_STDOUT is present. No logs are being kept."
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
tr:
|
|
2
|
+
rails_pretty_logger:
|
|
3
|
+
actions:
|
|
4
|
+
clear: "Temizle"
|
|
5
|
+
clear_logs: "Logları temizle"
|
|
6
|
+
sort: "%{direction} sırala"
|
|
7
|
+
submit: "Gönder"
|
|
8
|
+
confirmations:
|
|
9
|
+
clear_all: "Tüm logları temizlemek istediğine emin misin?"
|
|
10
|
+
clear_file: "%{file} dosyasındaki tüm logları temizlemek istediğine emin misin?"
|
|
11
|
+
open_file: "Log dosyası %{size} MB. Bu dosyayı açmak istediğine emin misin?"
|
|
12
|
+
filters:
|
|
13
|
+
clear_filters: "Filtreleri temizle"
|
|
14
|
+
end_date: "Bitiş tarihi:"
|
|
15
|
+
filter: "Filtrele"
|
|
16
|
+
logs_per_page: "Sayfa başına log:"
|
|
17
|
+
search: "Ara"
|
|
18
|
+
search_log_content: "Log içeriğinde ara"
|
|
19
|
+
severity: "Seviye"
|
|
20
|
+
start_date: "Başlangıç tarihi:"
|
|
21
|
+
logs:
|
|
22
|
+
file_size: "%{size} MB"
|
|
23
|
+
filtered_view: "Filtrelenmiş görünüm"
|
|
24
|
+
group_requests: "İstekleri grupla"
|
|
25
|
+
plain_lines: "Düz satırlar"
|
|
26
|
+
tail_last_lines: "Son %{count} satır"
|
|
27
|
+
ungrouped_lines: "Gruplanmamış satırlar"
|
|
28
|
+
navigation:
|
|
29
|
+
hourly_logs: "Saatlik loglar"
|
|
30
|
+
log_files: "Log dosyaları"
|
|
31
|
+
main_logs: "Ana loglar"
|
|
32
|
+
pagination: "Sayfalama"
|
|
33
|
+
states:
|
|
34
|
+
no_logs: "Gösterilecek log dosyası yok"
|
|
35
|
+
stdout_logging: "RAILS_LOG_TO_STDOUT mevcut. Log dosyası tutulmuyor."
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
3
|
+
module RailsPrettyLogger
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
|
6
|
+
JAVASCRIPT_MANIFEST_LINK = "//= link rails/pretty/logger/application.js".freeze
|
|
7
|
+
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
def copy_initializer
|
|
11
|
+
template "rails_pretty_logger.rb", "config/initializers/rails_pretty_logger.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def mount_engine
|
|
15
|
+
route %(mount Rails::Pretty::Logger::Engine => "/rails-pretty-logger")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def link_javascript_asset
|
|
19
|
+
manifest = "app/assets/config/manifest.js"
|
|
20
|
+
manifest_path = File.join(destination_root, manifest)
|
|
21
|
+
return unless File.exist?(manifest_path)
|
|
22
|
+
return if File.read(manifest_path).include?(JAVASCRIPT_MANIFEST_LINK)
|
|
23
|
+
|
|
24
|
+
separator = File.read(manifest_path).end_with?("\n") ? "" : "\n"
|
|
25
|
+
append_to_file manifest, "#{separator}#{JAVASCRIPT_MANIFEST_LINK}\n"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Rails::Pretty::Logger.configure do |config|
|
|
2
|
+
# The hook runs inside the Rails Pretty Logger engine controller.
|
|
3
|
+
# Example for apps that expose authenticate_user!:
|
|
4
|
+
# config.authenticate_with = -> { authenticate_user! }
|
|
5
|
+
config.authenticate_with = nil
|
|
6
|
+
|
|
7
|
+
# Production dashboards should usually be read-only unless clearing logs is explicitly desired.
|
|
8
|
+
config.read_only = Rails.env.production?
|
|
9
|
+
|
|
10
|
+
# Set to nil to allow any log file size.
|
|
11
|
+
config.max_file_size = 50.megabytes
|
|
12
|
+
|
|
13
|
+
# Number of lines shown by the tail view.
|
|
14
|
+
config.tail_lines = 500
|
|
15
|
+
|
|
16
|
+
# Optional parser for custom log formats. Return nil for lines the parser does not handle.
|
|
17
|
+
# Supported keys include :timestamp, :severity, :request_method, :request_path,
|
|
18
|
+
# :request_ip, :response_status, and :duration.
|
|
19
|
+
# config.log_line_parser = ->(line) { nil }
|
|
20
|
+
end
|
|
@@ -5,11 +5,7 @@ module Rails::Pretty::Logger
|
|
|
5
5
|
|
|
6
6
|
class ActiveSupportLogger < RailsLogger
|
|
7
7
|
include ActiveSupport::LoggerThreadSafeLevel
|
|
8
|
-
|
|
9
|
-
include LoggerSilence
|
|
10
|
-
else
|
|
11
|
-
include ActiveSupport::LoggerSilence
|
|
12
|
-
end
|
|
8
|
+
include ActiveSupport::LoggerSilence
|
|
13
9
|
|
|
14
10
|
# Returns true if the logger destination matches one of the sources
|
|
15
11
|
#
|
|
@@ -80,8 +76,8 @@ module Rails::Pretty::Logger
|
|
|
80
76
|
end
|
|
81
77
|
end
|
|
82
78
|
|
|
83
|
-
def initialize(*args)
|
|
84
|
-
super
|
|
79
|
+
def initialize(*args, **kwargs)
|
|
80
|
+
super(*args, **kwargs)
|
|
85
81
|
@formatter = SimpleFormatter.new
|
|
86
82
|
after_initialize if respond_to? :after_initialize
|
|
87
83
|
end
|
|
@@ -1,17 +1 @@
|
|
|
1
1
|
require "rails/pretty/logger/console_logger"
|
|
2
|
-
require "rails/pretty/logger/active_support_logger"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
module Rails
|
|
6
|
-
module Pretty
|
|
7
|
-
module Logger
|
|
8
|
-
module Config
|
|
9
|
-
|
|
10
|
-
class LoggerConfig < Rails::Application
|
|
11
|
-
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Rails::Pretty::Logger
|
|
2
|
+
class Configuration
|
|
3
|
+
attr_accessor :authenticate_with, :log_line_parser, :max_file_size, :tail_lines
|
|
4
|
+
attr_writer :read_only
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@authenticate_with = nil
|
|
8
|
+
@log_line_parser = nil
|
|
9
|
+
@read_only = Rails.env.production?
|
|
10
|
+
@max_file_size = nil
|
|
11
|
+
@tail_lines = 500
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def read_only?
|
|
15
|
+
@read_only == true
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -3,11 +3,29 @@ module Rails
|
|
|
3
3
|
module Logger
|
|
4
4
|
class Engine < ::Rails::Engine
|
|
5
5
|
isolate_namespace Rails::Pretty::Logger
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
|
|
7
|
+
initializer "rails_pretty_logger.assets" do |app|
|
|
8
|
+
assets_config = app.config.assets if app.config.respond_to?(:assets)
|
|
9
|
+
|
|
10
|
+
if assets_config.respond_to?(:paths) && assets_config.respond_to?(:precompile)
|
|
11
|
+
%w[stylesheets javascripts].each do |asset_path|
|
|
12
|
+
path = root.join("app/assets", asset_path).to_s
|
|
13
|
+
assets_config.paths << path unless assets_config.paths.include?(path)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
%w[
|
|
17
|
+
rails/pretty/logger/application.js
|
|
18
|
+
rails/pretty/logger/application.css
|
|
19
|
+
rails/pretty/logger/dashboards.css
|
|
20
|
+
rails/pretty/logger/list.css
|
|
21
|
+
].each do |asset|
|
|
22
|
+
assets_config.precompile << asset unless assets_config.precompile.include?(asset)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
8
25
|
end
|
|
9
|
-
|
|
10
|
-
|
|
26
|
+
|
|
27
|
+
rake_tasks do
|
|
28
|
+
load root.join("lib/tasks/rails/pretty/logger_tasks.rake")
|
|
11
29
|
end
|
|
12
30
|
end
|
|
13
31
|
end
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
|
|
2
|
+
require "fileutils"
|
|
3
|
+
require "logger"
|
|
4
|
+
|
|
2
5
|
module Rails::Pretty::Logger
|
|
3
6
|
|
|
4
7
|
class RailsLogger < ::Logger
|
|
@@ -7,14 +10,10 @@ module Rails::Pretty::Logger
|
|
|
7
10
|
progname: nil, formatter: nil, datetime_format: nil,
|
|
8
11
|
shift_period_suffix: '%Y%m%d')
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
self.progname = progname
|
|
12
|
-
@default_formatter = Formatter.new
|
|
13
|
-
self.datetime_format = datetime_format
|
|
14
|
-
self.formatter = formatter
|
|
13
|
+
super(nil, level: level, progname: progname, formatter: formatter, datetime_format: datetime_format)
|
|
15
14
|
@logdev = nil
|
|
16
15
|
if logdev
|
|
17
|
-
log_name = "log
|
|
16
|
+
log_name = Rails.root.join("log", "#{logdev}.log").to_s
|
|
18
17
|
@logdev = LoggerDevice.new(log_name, :shift_age => shift_age,
|
|
19
18
|
:shift_size => shift_size,
|
|
20
19
|
:shift_period_suffix => shift_period_suffix, file_count: file_count )
|
|
@@ -95,48 +94,70 @@ module Rails::Pretty::Logger
|
|
|
95
94
|
end
|
|
96
95
|
|
|
97
96
|
def shift_log_period(period_end)
|
|
98
|
-
|
|
97
|
+
with_rotation_lock do
|
|
98
|
+
suffix = period_end.strftime(@shift_period_suffix)
|
|
99
|
+
|
|
100
|
+
suffix_year = period_end.strftime('%Y')
|
|
101
|
+
suffix_month = period_end.strftime('%m')
|
|
102
|
+
suffix_day = period_end.strftime('%d')
|
|
103
|
+
|
|
104
|
+
if @shift_age == 'hourly'
|
|
105
|
+
suffix = period_end.strftime('%Y%m%d_%H%M')
|
|
106
|
+
end
|
|
99
107
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
age_file = available_log_path("#{@filename}.#{suffix}")
|
|
109
|
+
|
|
110
|
+
@dev.close rescue nil
|
|
111
|
+
|
|
112
|
+
File.rename("#{@filename}", age_file)
|
|
113
|
+
new_path = File.join(Rails.root, 'log', 'hourly', suffix_year, suffix_month, suffix_day)
|
|
114
|
+
FileUtils.mkdir_p new_path
|
|
115
|
+
destination = available_log_path(File.join(new_path, File.basename(age_file)))
|
|
116
|
+
FileUtils.mv age_file, destination
|
|
117
|
+
delete_old_hourly_files
|
|
118
|
+
@dev = create_logfile(@filename)
|
|
119
|
+
true
|
|
120
|
+
end
|
|
121
|
+
end
|
|
103
122
|
|
|
104
|
-
|
|
105
|
-
|
|
123
|
+
def with_rotation_lock
|
|
124
|
+
FileUtils.mkdir_p(File.dirname(rotation_lock_path))
|
|
125
|
+
File.open(rotation_lock_path, File::RDWR | File::CREAT, 0644) do |lock|
|
|
126
|
+
lock.flock(File::LOCK_EX)
|
|
127
|
+
yield
|
|
106
128
|
end
|
|
129
|
+
end
|
|
107
130
|
|
|
108
|
-
|
|
131
|
+
def rotation_lock_path
|
|
132
|
+
Rails.root.join("tmp", "rails_pretty_logger", "#{File.basename(@filename)}.rotate.lock").to_s
|
|
133
|
+
end
|
|
109
134
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
age_file = "#{@filename}.#{suffix}.#{idx}"
|
|
117
|
-
break unless FileTest.exist?(age_file)
|
|
118
|
-
end
|
|
135
|
+
def available_log_path(path)
|
|
136
|
+
candidate = path
|
|
137
|
+
index = 0
|
|
138
|
+
while File.exist?(candidate)
|
|
139
|
+
index += 1
|
|
140
|
+
candidate = "#{path}.#{index}"
|
|
119
141
|
end
|
|
142
|
+
candidate
|
|
143
|
+
end
|
|
120
144
|
|
|
121
|
-
|
|
122
|
-
log_files =
|
|
123
|
-
while
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
file_path = log_files[file_index]
|
|
127
|
-
delete_old_file(file_path)
|
|
128
|
-
log_files = Dir[ File.join(Rails.root, 'log', 'hourly') + "/#{suffix_year}/**/*"].reject {|fn| File.directory?(fn) }
|
|
145
|
+
def delete_old_hourly_files
|
|
146
|
+
log_files = hourly_log_files
|
|
147
|
+
while log_files.length > @file_count
|
|
148
|
+
delete_old_file(log_files.min_by { |log_file| hourly_log_sort_key(log_file) })
|
|
149
|
+
log_files = hourly_log_files
|
|
129
150
|
end
|
|
151
|
+
end
|
|
130
152
|
|
|
131
|
-
|
|
153
|
+
def hourly_log_files
|
|
154
|
+
log_prefix = "#{File.basename(@filename)}."
|
|
155
|
+
Dir[File.join(Rails.root, 'log', 'hourly', '**', '*')]
|
|
156
|
+
.select { |file| File.file?(file) && File.basename(file).start_with?(log_prefix) }
|
|
157
|
+
end
|
|
132
158
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
new_path = File.join(Rails.root, 'log', 'hourly', suffix_year, suffix_month, suffix_day)
|
|
136
|
-
FileUtils.mkdir_p new_path
|
|
137
|
-
FileUtils.mv old_log_path, new_path, :force => true
|
|
138
|
-
@dev = create_logfile(@filename)
|
|
139
|
-
return true
|
|
159
|
+
def hourly_log_sort_key(file)
|
|
160
|
+
File.basename(file)[/\.([0-9]{8}_[0-9]{4})(?:\.[0-9]+)?\z/, 1] || File.mtime(file).utc.strftime("%Y%m%d_%H%M")
|
|
140
161
|
end
|
|
141
162
|
|
|
142
163
|
def delete_old_file(file_path)
|
|
@@ -144,9 +165,9 @@ module Rails::Pretty::Logger
|
|
|
144
165
|
month_dir = File.expand_path("..",day_dir)
|
|
145
166
|
year_dir = File.expand_path("../..",day_dir)
|
|
146
167
|
File.delete(file_path) if File.exist?(file_path)
|
|
147
|
-
Dir.rmdir(day_dir) if Dir.empty?(day_dir)
|
|
148
|
-
Dir.rmdir(month_dir) if month_dir.empty?
|
|
149
|
-
Dir.rmdir(year_dir) if year_dir.empty?
|
|
168
|
+
Dir.rmdir(day_dir) if Dir.exist?(day_dir) && Dir.empty?(day_dir)
|
|
169
|
+
Dir.rmdir(month_dir) if Dir.exist?(month_dir) && Dir.empty?(month_dir)
|
|
170
|
+
Dir.rmdir(year_dir) if Dir.exist?(year_dir) && Dir.empty?(year_dir)
|
|
150
171
|
end
|
|
151
172
|
end
|
|
152
173
|
|