hot_catch 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -17
- data/lib/generators/hot_catch/install_generator.rb +1 -29
- data/lib/generators/hot_catch/uninstall_generator.rb +0 -6
- data/lib/hot_catch.rb +9 -10
- data/lib/hot_catch/custom_log_subscribers.rb +1 -1
- data/lib/hot_catch/hot_catch_logger.rb +8 -29
- data/lib/hot_catch/version.rb +1 -1
- metadata +2 -3
- data/lib/hot_catch/hot_catch_log.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d30ed8cb373a76a5c27b352bb56a5f0694bf4f7e
|
4
|
+
data.tar.gz: 7938dab531e6cde13405ea25831f5097f1a6a75a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d70f6af9e7b6133465bcb85c9acb36639ca44f9c8522bb5fb598fc69e8a25c3f24fddf006cdf4ee064c4dde5a6e8efe51f3d604ba07cedb050d84ba4a2ec7da
|
7
|
+
data.tar.gz: 6f430732e4f7432361d6c09d0ecc94d873730a3442f49bb6c312a8fcca9b377e9e6d70f876e023dee1ba2524d564251751983fed363b8dbf6ec6a71f2517049c
|
data/README.md
CHANGED
@@ -1,18 +1,5 @@
|
|
1
1
|
# HotCatch
|
2
|
-
Данный гем позволяет
|
3
|
-
запросы на главный сервер.
|
4
|
-
|
5
|
-
## Использование
|
6
|
-
Логи можно посмотреть в консоли:
|
7
|
-
```ruby
|
8
|
-
> HotCatchLog.all
|
9
|
-
> HotCatchLog.first.log_data
|
10
|
-
```
|
11
|
-
В данной реализации логи разделены по статусам запросов (поле `status HotCatchLog`).
|
12
|
-
Кроме того одинаковые ошибки собираются в одну, при этом увеличивается счётчик в моделе `HotCatchLog` поле `count_log`.
|
13
|
-
|
14
|
-
Ответы от сервера, куда отправляются логи, доступен в файле `log/hot_catch_log_response_errors`.
|
15
|
-
Если всё порядке - этого файла нет или он пуст.
|
2
|
+
Данный гем позволяет посылать лог-данные на главный сервер.
|
16
3
|
|
17
4
|
## Установка
|
18
5
|
1. Добавить гем в `Gemfile`
|
@@ -22,11 +9,14 @@ gem 'hot_catch'
|
|
22
9
|
2. `$ bundle install`
|
23
10
|
3. Запустить генератор установки: `$ rails generate hot_catch:install`
|
24
11
|
Для удаления: `$ rails generate hot_catch:uninstall`
|
25
|
-
4.
|
26
|
-
5. Изменить в `config/hot_catch_config.json` url - адрес сервера для отправки лог файлов.
|
12
|
+
4. Изменить в `config/hot_catch_config.json` url - адрес сервера для отправки лог файлов.
|
27
13
|
Автоматически запросы посылаются на адрес *url/main_hot_catch_logs*, но нужно указать только *url*.
|
28
14
|
|
29
|
-
Это всё! Теперь
|
15
|
+
Это всё! Теперь логи автоматически посылаются на сервер.
|
16
|
+
|
17
|
+
## Примечание
|
18
|
+
Ответы от сервера, куда отправляются логи, доступен в файле `log/hot_catch_log_response_errors`.
|
19
|
+
Если всё порядке - этого файла нет или он пуст.
|
30
20
|
|
31
21
|
## License
|
32
22
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -7,35 +7,7 @@ module HotCatch
|
|
7
7
|
# Включение всех файлов из указанной папки относительно __FILE__ (то есть текущего файла)
|
8
8
|
source_root File.expand_path('../../../hot_catch', __FILE__)
|
9
9
|
# include Rails::Generators::Migration
|
10
|
-
|
11
|
-
def add_model_hot_catch
|
12
|
-
create_file "db/migrate/20170729154223_create_hot_catch_log.rb" do
|
13
|
-
<<RUBY
|
14
|
-
class CreateHotCatchLog < ActiveRecord::Migration[5.0]
|
15
|
-
def change
|
16
|
-
create_table :hot_catch_logs do |t|
|
17
|
-
t.string :log_data, null: false
|
18
|
-
t.integer :count_log, default: 1, null: false
|
19
|
-
t.string :status, null: false
|
20
|
-
|
21
|
-
t.timestamps
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
RUBY
|
26
|
-
end
|
27
|
-
|
28
|
-
create_file "app/models/application_record.rb" do
|
29
|
-
"class ApplicationRecord < ActiveRecord::Base
|
30
|
-
self.abstract_class = true
|
31
|
-
end"
|
32
|
-
end unless File.exist? "app/models/application_record.rb"
|
33
|
-
|
34
|
-
|
35
|
-
copy_file "hot_catch_log.rb", "app/models/hot_catch_log.rb"
|
36
|
-
end
|
37
|
-
|
38
|
-
|
10
|
+
|
39
11
|
def add_rack_logger
|
40
12
|
copy_file "hot_catch_logger.rb", "config/hot_catch_logger.rb"
|
41
13
|
end
|
@@ -6,11 +6,6 @@ module HotCatch
|
|
6
6
|
class UninstallGenerator < Rails::Generators::Base
|
7
7
|
# include Rails::Generators::Migration
|
8
8
|
|
9
|
-
def remove_model_hot_catch
|
10
|
-
remove_file "db/migrate/20170729154223_create_hot_catch_log.rb"
|
11
|
-
remove_file "app/models/hot_catch_log.rb"
|
12
|
-
end
|
13
|
-
|
14
9
|
def remove_rack_logger
|
15
10
|
remove_file "config/hot_catch_logger.rb"
|
16
11
|
end
|
@@ -25,7 +20,6 @@ module HotCatch
|
|
25
20
|
|
26
21
|
def remove_log_files
|
27
22
|
remove_file "tmp/hot_catch_buf_file"
|
28
|
-
remove_file "tmp/hot_catch_buf_file2"
|
29
23
|
end
|
30
24
|
|
31
25
|
def remove_hot_catch_config
|
data/lib/hot_catch.rb
CHANGED
@@ -12,11 +12,8 @@ module HotCatch
|
|
12
12
|
# ====================================
|
13
13
|
# body_log = {main_hot_catch_log: {
|
14
14
|
# "log_data":"some message",
|
15
|
-
# "name_app":"
|
16
|
-
# "
|
17
|
-
# "id_log_origin_app":1,
|
18
|
-
# "from_log":"Rails",
|
19
|
-
# "status":"SERVER_ERROR"}
|
15
|
+
# "name_app":"my_app",
|
16
|
+
# "from_log":"Rails"}
|
20
17
|
# }
|
21
18
|
# ====================================
|
22
19
|
# 4. sender_logs.send_log(body_log)
|
@@ -30,14 +27,12 @@ module HotCatch
|
|
30
27
|
@url += "/main_hot_catch_logs"
|
31
28
|
end
|
32
29
|
|
33
|
-
def rails_g_log(log_data,
|
30
|
+
def rails_g_log(log_data, status)
|
34
31
|
send_log(
|
35
32
|
{main_hot_catch_log:
|
36
33
|
{
|
37
34
|
"log_data":log_data,
|
38
35
|
"name_app":Rails.application.class.parent_name,
|
39
|
-
"count_log":count_log,
|
40
|
-
"id_log_origin_app":id_log,
|
41
36
|
"from_log":"Rails",
|
42
37
|
"status":status
|
43
38
|
}
|
@@ -47,10 +42,14 @@ module HotCatch
|
|
47
42
|
|
48
43
|
def send_log(body_log)
|
49
44
|
response = call(@url, body_log)
|
50
|
-
#
|
45
|
+
# если на зпрос пришёл ответ, то пришло уведомление об ошибке, которое логируется
|
51
46
|
unless response.empty?
|
52
47
|
str = "\n" + (?-*20) + "\n#{Time.now}\nlogs:\n#{body_log.to_s}\nresponse\n:#{response}\n" + (?-*20) + "\n"
|
53
|
-
File.open("log/hot_catch_log_response_errors", 'a'){ |file| file.write str
|
48
|
+
File.open("log/hot_catch_log_response_errors", 'a'){ |file| file.write str.encode('UTF-8', {
|
49
|
+
:invalid => :replace,
|
50
|
+
:undef => :replace,
|
51
|
+
:replace => '?'
|
52
|
+
}) }
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
@@ -24,7 +24,7 @@ class CustomActiveRecordLogSubscriber < ActiveRecord::LogSubscriber
|
|
24
24
|
# name = colorize_payload_name(name, payload[:name])
|
25
25
|
# sql = color(sql, sql_color(sql), true)
|
26
26
|
|
27
|
-
debug " #{name} #{sql}#{binds}" unless payload[:sql].to_s =~ /hot_catch_logs|COMMIT|BEGIN/i
|
27
|
+
debug " #{name} #{sql}#{binds}" unless payload[:sql].to_s =~ /hot_catch_logs|COMMIT|BEGIN|Rendering|Rendered/i
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -5,9 +5,6 @@ require 'action_dispatch/http/request'
|
|
5
5
|
require 'rack/body_proxy'
|
6
6
|
# require 'rack/utils'
|
7
7
|
|
8
|
-
require_relative '../app/models/application_record.rb'
|
9
|
-
require_relative '../app/models/hot_catch_log.rb'
|
10
|
-
|
11
8
|
module Rails
|
12
9
|
module Rack
|
13
10
|
# Sets log tags, logs the request, calls the app, and flushes the logs.
|
@@ -36,10 +33,6 @@ module Rails
|
|
36
33
|
def call_app(request, env)
|
37
34
|
instrumenter = ActiveSupport::Notifications.instrumenter
|
38
35
|
instrumenter.start 'request.action_dispatch', request: request
|
39
|
-
|
40
|
-
# Флаг начала запроса
|
41
|
-
logger << "\nBEGIN\n"
|
42
|
-
|
43
36
|
logger.info { started_request_message(request) }
|
44
37
|
resp = @app.call(env)
|
45
38
|
resp[2] = ::Rack::BodyProxy.new(resp[2]) { finish(request) }
|
@@ -76,31 +69,17 @@ module Rails
|
|
76
69
|
private
|
77
70
|
|
78
71
|
def finish(request)
|
79
|
-
# Если быстро обновлять страницу, то конец лога не успевает записаться.
|
80
|
-
# Для этого записываем последний лог в новый файл и с новым запросом считываем
|
81
|
-
# его и записанный конец лога из изначального лог-файла.
|
82
|
-
|
83
72
|
# Считали данные из основного лог-файла
|
84
|
-
|
85
|
-
File.open('tmp/hot_catch_buf_file'){ |file|
|
73
|
+
log = ""
|
74
|
+
File.open('tmp/hot_catch_buf_file'){ |file| log = file.read}
|
86
75
|
File.open('tmp/hot_catch_buf_file', 'w'){ |file| file.print "" }
|
87
|
-
logs = logs.split("BEGIN").delete_if{|x| !x.present? }
|
88
|
-
|
89
|
-
# Считали данные из дополнительного лог-файла и записали начало последнего лога
|
90
|
-
add_log = ""
|
91
|
-
File.open('tmp/hot_catch_buf_file2'){ |file| add_log = file.read} if File.exist?('tmp/hot_catch_buf_file2')
|
92
|
-
File.open('tmp/hot_catch_buf_file2', 'w'){ |file| file.print logs[-1] }
|
93
|
-
logs.delete_at(-1)
|
94
|
-
|
95
|
-
# Собираем начало лога и конец
|
96
|
-
add_log = add_log + (logs[0]).to_s
|
97
|
-
HotCatchLog.process_data_log(add_log) unless add_log.strip =~ /assets/
|
98
|
-
|
99
|
-
logs.delete_at(0)
|
100
|
-
# Обрабатываем остальные логи, если есть
|
101
|
-
logs.each {|log| HotCatchLog.process_data_log(log) unless log.strip =~ /assets/}
|
102
|
-
|
103
76
|
|
77
|
+
# получаем статус из лога
|
78
|
+
status = log.match(/!!!(\d{3})!!!/)
|
79
|
+
status = status[1] if status
|
80
|
+
log.gsub!(/!!!(\d{3})!!!\s/, "")
|
81
|
+
# отправляем логи
|
82
|
+
Rails.application.config.sender_logs.rails_g_log(log, status) unless log.strip =~ /assets/
|
104
83
|
|
105
84
|
instrumenter = ActiveSupport::Notifications.instrumenter
|
106
85
|
instrumenter.finish 'request.action_dispatch', request: request
|
data/lib/hot_catch/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hot_catch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Davhot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Description of Testgem.
|
14
14
|
email:
|
@@ -24,7 +24,6 @@ files:
|
|
24
24
|
- lib/generators/hot_catch/uninstall_generator.rb
|
25
25
|
- lib/hot_catch.rb
|
26
26
|
- lib/hot_catch/custom_log_subscribers.rb
|
27
|
-
- lib/hot_catch/hot_catch_log.rb
|
28
27
|
- lib/hot_catch/hot_catch_logger.rb
|
29
28
|
- lib/hot_catch/version.rb
|
30
29
|
- lib/tasks/hot_catch_tasks.rake
|
@@ -1,70 +0,0 @@
|
|
1
|
-
class HotCatchLog < ApplicationRecord
|
2
|
-
|
3
|
-
validates :log_data, :status, presence: true
|
4
|
-
validates :count_log, presence: true, numericality: {only_integer: true, greater_than: 0}
|
5
|
-
|
6
|
-
STATUSES = ["STATUS", "SUCCESS", "REDIRECTION", "CLIENT_ERROR", "SERVER_ERROR", "WARNING"]
|
7
|
-
|
8
|
-
# Проверка лога на уникальность
|
9
|
-
def self.process_data_log(str)
|
10
|
-
str, status = get_status(str)
|
11
|
-
|
12
|
-
# Если статус не найден, то возможна ошибка в контроллере
|
13
|
-
status = STATUSES[3] if !status && str =~ /ActionController/
|
14
|
-
|
15
|
-
str2 = strip_str(str)
|
16
|
-
opt = true
|
17
|
-
|
18
|
-
HotCatchLog.where(status: status).each do |cur_log|
|
19
|
-
if strip_str(cur_log.log_data) == str2
|
20
|
-
cur_log.count_log += 1
|
21
|
-
cur_log.save
|
22
|
-
|
23
|
-
# Отправка лога на сервер
|
24
|
-
Rails.application.config.sender_logs.rails_g_log(cur_log.log_data,
|
25
|
-
cur_log.count_log, cur_log.id, cur_log.status)
|
26
|
-
|
27
|
-
opt = false
|
28
|
-
return
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
if opt && str.strip.present? && status.present?
|
33
|
-
l = HotCatchLog.create(log_data: format_log(str), status: status)
|
34
|
-
|
35
|
-
# Отправка лога на сервер
|
36
|
-
# args: log_data, count_log, id_log, status
|
37
|
-
Rails.application.config.sender_logs.rails_g_log(l.log_data, l.count_log,
|
38
|
-
l.id, l.status)
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
# Метод для сравнения логов
|
46
|
-
def self.strip_str(str)
|
47
|
-
str = str.dup
|
48
|
-
str.gsub!(/\d+(\.\d+)?ms/, "") # За сколько выполнилось действие
|
49
|
-
str.gsub!(/\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s\+\d{4}/, "") # дата
|
50
|
-
str.gsub!(/#<.*:0x[\d|\w]+>/, "") # Объект (например #<StaticPagesController:0x007f37791686d8>)
|
51
|
-
format_log(str)
|
52
|
-
end
|
53
|
-
|
54
|
-
# Помимо сравнения логов, нужен для форматирования лога и записи в бд
|
55
|
-
def self.format_log(str)
|
56
|
-
str = str.split("\n").select{|x| x.present?}.join("\n") # убирает повторяющиеся переводы строки
|
57
|
-
str.strip! # лишние символы пропусков в начале и конце
|
58
|
-
str
|
59
|
-
end
|
60
|
-
|
61
|
-
# Возвращает статус и лог без статуса
|
62
|
-
def self.get_status(str)
|
63
|
-
status = str.match(/!!!(\d{3})!!!/)
|
64
|
-
status = status[1] if status
|
65
|
-
str = str.gsub(/!!!(\d{3})!!!\s/, "")
|
66
|
-
status = STATUSES[status[0].to_i - 1] if status.present?
|
67
|
-
[str, status]
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|