heavylog 0.0.1 → 0.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47ec6ffc41672ed7c9adc52d297a917fb29b2b97c0a5f241b82a0dfa2805cfed
4
- data.tar.gz: e1163732c1c138707a90ef2cb7254a93f6891358468247768236ef2411c79663
3
+ metadata.gz: f65df3243c6174d917b13395981eac25a835eff5a9a646ccb35b598a669f1141
4
+ data.tar.gz: b06dc2293064ae86a433fc29a7947dd03b403cfa248d8b8e57280c146cca51b3
5
5
  SHA512:
6
- metadata.gz: 732bda484d52d363aa20b25f4c19b636c47393e568161309af5e2f72925dd933ea4c6f3999ce0924ebcd1010dee09ca5e108dbd696f6f8402ead135b4470f844
7
- data.tar.gz: 42ad2287596556ef8664b7208ab382241fe60701f0aa85912dcdc7047c596c9fc5d2ec64c38a71617498a77696895665fedb1773e1d281fa9079ec11ebf65325
6
+ metadata.gz: 4fa777d8823ffb829c9b447e37efeae2034dedab05f3b7104057ce183ecf5d92acac833a01565825b1c28303c7e2360c62c938e01ceabbd6a7cb3780dbd92b95
7
+ data.tar.gz: 1e2da843ff2352d326b311da106644c0a765233217a2798f2b929717369556ea57fb43602b2e463b9e3f5feea9861e18e5ac675542df47c53500d42acc529ff5
data/Gemfile.lock ADDED
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ heavylog (0.0.2)
5
+ actionpack (>= 5)
6
+ activesupport (>= 5)
7
+ railties (>= 5)
8
+ request_store (~> 1.4)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ actionpack (5.1.6)
14
+ actionview (= 5.1.6)
15
+ activesupport (= 5.1.6)
16
+ rack (~> 2.0)
17
+ rack-test (>= 0.6.3)
18
+ rails-dom-testing (~> 2.0)
19
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
20
+ actionview (5.1.6)
21
+ activesupport (= 5.1.6)
22
+ builder (~> 3.1)
23
+ erubi (~> 1.4)
24
+ rails-dom-testing (~> 2.0)
25
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
26
+ activesupport (5.1.6)
27
+ concurrent-ruby (~> 1.0, >= 1.0.2)
28
+ i18n (>= 0.7, < 2)
29
+ minitest (~> 5.1)
30
+ tzinfo (~> 1.1)
31
+ builder (3.2.3)
32
+ concurrent-ruby (1.0.5)
33
+ crass (1.0.3)
34
+ diff-lcs (1.3)
35
+ erubi (1.7.1)
36
+ i18n (1.0.0)
37
+ concurrent-ruby (~> 1.0)
38
+ loofah (2.2.2)
39
+ crass (~> 1.0.2)
40
+ nokogiri (>= 1.5.9)
41
+ method_source (0.9.0)
42
+ mini_portile2 (2.3.0)
43
+ minitest (5.11.3)
44
+ nokogiri (1.8.2)
45
+ mini_portile2 (~> 2.3.0)
46
+ rack (2.0.4)
47
+ rack-test (1.0.0)
48
+ rack (>= 1.0, < 3)
49
+ rails-dom-testing (2.0.3)
50
+ activesupport (>= 4.2.0)
51
+ nokogiri (>= 1.6)
52
+ rails-html-sanitizer (1.0.4)
53
+ loofah (~> 2.2, >= 2.2.2)
54
+ railties (5.1.6)
55
+ actionpack (= 5.1.6)
56
+ activesupport (= 5.1.6)
57
+ method_source
58
+ rake (>= 0.8.7)
59
+ thor (>= 0.18.1, < 2.0)
60
+ rake (10.5.0)
61
+ request_store (1.4.1)
62
+ rack (>= 1.4)
63
+ rspec (3.7.0)
64
+ rspec-core (~> 3.7.0)
65
+ rspec-expectations (~> 3.7.0)
66
+ rspec-mocks (~> 3.7.0)
67
+ rspec-core (3.7.1)
68
+ rspec-support (~> 3.7.0)
69
+ rspec-expectations (3.7.0)
70
+ diff-lcs (>= 1.2.0, < 2.0)
71
+ rspec-support (~> 3.7.0)
72
+ rspec-mocks (3.7.0)
73
+ diff-lcs (>= 1.2.0, < 2.0)
74
+ rspec-support (~> 3.7.0)
75
+ rspec-support (3.7.1)
76
+ thor (0.20.0)
77
+ thread_safe (0.3.6)
78
+ tzinfo (1.2.5)
79
+ thread_safe (~> 0.1)
80
+
81
+ PLATFORMS
82
+ ruby
83
+
84
+ DEPENDENCIES
85
+ bundler (~> 1.16)
86
+ heavylog!
87
+ rake (~> 10.0)
88
+ rspec (~> 3.0)
89
+
90
+ BUNDLED WITH
91
+ 1.16.0
data/heavylog.gemspec CHANGED
@@ -24,4 +24,9 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "bundler", "~> 1.16"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
27
+
28
+ spec.add_runtime_dependency 'activesupport', '>= 5'
29
+ spec.add_runtime_dependency 'actionpack', '>= 5'
30
+ spec.add_runtime_dependency 'railties', '>= 5'
31
+ spec.add_runtime_dependency 'request_store', '~> 1.4'
27
32
  end
@@ -0,0 +1,11 @@
1
+ require 'json'
2
+
3
+ module Heavylog
4
+ module Formatters
5
+ class Json
6
+ def call(data)
7
+ ::JSON.dump(data)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Heavylog
2
+ module Formatters
3
+ class Raw
4
+ def call(data)
5
+ data
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,104 @@
1
+ require 'json'
2
+ require 'action_pack'
3
+ require 'active_support/core_ext/class/attribute'
4
+ require 'active_support/log_subscriber'
5
+ require 'request_store'
6
+
7
+ module Heavylog
8
+ class LogSubscriber < ActiveSupport::LogSubscriber
9
+ def process_action(event)
10
+ payload = event.payload
11
+ data = extract_request(event, payload)
12
+ RequestStore.store[:heavylog_request_data] = data
13
+ end
14
+
15
+ def redirect_to(event)
16
+ RequestStore.store[:heavylog_location] = event.payload[:location]
17
+ end
18
+
19
+ def unpermitted_parameters(event)
20
+ RequestStore.store[:heavylog_unpermitted_params] ||= []
21
+ RequestStore.store[:heavylog_unpermitted_params].concat(event.payload[:keys])
22
+ end
23
+
24
+ private
25
+
26
+ def extract_request(event, payload)
27
+ payload = event.payload
28
+ data = initial_data(payload)
29
+ data.merge!(extract_status(payload))
30
+ data.merge!(extract_runtimes(event, payload))
31
+ data.merge!(extract_location)
32
+ data.merge!(extract_unpermitted_params)
33
+ data.merge!(custom_options(event))
34
+ end
35
+
36
+ def initial_data(payload)
37
+ {
38
+ method: payload[:method],
39
+ path: extract_path(payload),
40
+ format: extract_format(payload),
41
+ controller: payload[:controller],
42
+ action: payload[:action]
43
+ }
44
+ end
45
+
46
+ def extract_path(payload)
47
+ path = payload[:path]
48
+ strip_query_string(path)
49
+ end
50
+
51
+ def strip_query_string(path)
52
+ index = path.index('?')
53
+ index ? path[0, index] : path
54
+ end
55
+
56
+ def extract_format(payload)
57
+ payload[:format]
58
+ end
59
+
60
+ def extract_status(payload)
61
+ if (status = payload[:status])
62
+ { status: status.to_i }
63
+ elsif (error = payload[:exception])
64
+ exception, message = error
65
+ { status: get_error_status_code(exception), error: "#{exception}: #{message}" }
66
+ else
67
+ { status: 0 }
68
+ end
69
+ end
70
+
71
+ def get_error_status_code(exception)
72
+ status = ActionDispatch::ExceptionWrapper.rescue_responses[exception]
73
+ Rack::Utils.status_code(status)
74
+ end
75
+
76
+ def custom_options(event)
77
+ event.payload[:custom_payload] || {}
78
+ end
79
+
80
+ def extract_runtimes(event, payload)
81
+ data = { duration: event.duration.to_f.round(2) }
82
+ [:view_runtime, :db_runtime].each do |key|
83
+ data[key] = payload[key].to_f.round(2) if payload.key?(key)
84
+ end
85
+ data
86
+ end
87
+
88
+ def extract_location
89
+ location = RequestStore.store[:heavylog_location]
90
+ return {} unless location
91
+
92
+ RequestStore.store[:heavylog_location] = nil
93
+ { location: strip_query_string(location) }
94
+ end
95
+
96
+ def extract_unpermitted_params
97
+ unpermitted_params = RequestStore.store[:heavylog_unpermitted_params]
98
+ return {} unless unpermitted_params
99
+
100
+ RequestStore.store[:heavylog_unpermitted_params] = nil
101
+ { unpermitted_params: unpermitted_params }
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ require 'rack/body_proxy'
3
+
4
+ module Heavylog
5
+ class Middleware
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ request = ActionDispatch::Request.new(env)
12
+ RequestStore.store[:heavylog_request_id] = request.uuid
13
+
14
+ @app.call(env)
15
+ ensure
16
+ Heavylog.finish
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require 'active_support/ordered_options'
3
+
4
+ module Heavylog
5
+ class OrderedOptions < ActiveSupport::OrderedOptions
6
+ def custom_payload(&block)
7
+ self.custom_payload_method = block
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module Heavylog
3
+ class Railtie < Rails::Railtie
4
+ config.heavylog = Heavylog::OrderedOptions.new
5
+ config.heavylog.enabled = false
6
+ config.heavylog.path = 'log/heavylog.log'
7
+
8
+ initializer "heavylog.insert_middleware" do |app|
9
+ app.config.middleware.insert_before Rails::Rack::Logger, Heavylog::Middleware
10
+ end
11
+
12
+ config.after_initialize do |app|
13
+ Heavylog.setup(app) if app.config.heavylog.enabled
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Heavylog
4
+ module RequestLogger
5
+ def add(severity, message = nil, progname = nil, &block)
6
+ super
7
+ Heavylog.log(severity, message, progname, &block)
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module Heavylog
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/heavylog.rb CHANGED
@@ -1,5 +1,98 @@
1
- require "heavylog/version"
1
+ # frozen_string_literal: true
2
+ require 'heavylog/version'
3
+ require 'heavylog/formatters/raw'
4
+ require 'heavylog/formatters/json'
5
+ require 'heavylog/log_subscriber'
6
+ require 'heavylog/middleware'
7
+ require 'heavylog/ordered_options'
8
+ require 'heavylog/request_logger'
2
9
 
3
10
  module Heavylog
4
- # Your code goes here...
11
+ module_function
12
+
13
+ mattr_accessor :logger, :application, :formatter, :log_level
14
+
15
+ def setup(app)
16
+ self.application = app
17
+ patch_loggers
18
+ attach_to_action_controller
19
+ setup_custom_payload
20
+ set_options
21
+ end
22
+
23
+ def patch_loggers
24
+ Rails.logger.extend(RequestLogger)
25
+ end
26
+
27
+ def set_options
28
+ f = File.open(config.path, 'a')
29
+ f.binmode
30
+ f.sync = true
31
+
32
+ Heavylog.logger = ActiveSupport::Logger.new(f)
33
+ Heavylog.formatter = config.formatter || Heavylog::Formatters::Raw.new
34
+ Heavylog.log_level = config.log_level || :info
35
+ end
36
+
37
+ def attach_to_action_controller
38
+ Heavylog::LogSubscriber.attach_to :action_controller
39
+ end
40
+
41
+ def setup_custom_payload
42
+ return unless config.custom_payload_method.respond_to?(:call)
43
+
44
+ klasses = Array(config.base_controller_class)
45
+ klasses.map! { |klass| klass.try(:constantize) }
46
+ klasses.push(ActionController::Base) if klasses.empty?
47
+ klasses.each { |klass| extend_base_controller_class(klass) }
48
+ end
49
+
50
+ def extend_base_controller_class(klass)
51
+ append_payload_method = klass.instance_method(:append_info_to_payload)
52
+ custom_payload_method = config.custom_payload_method
53
+
54
+ klass.send(:define_method, :append_info_to_payload) do |payload|
55
+ append_payload_method.bind(self).call(payload)
56
+ payload[:custom_payload] = custom_payload_method.call(self)
57
+ end
58
+ end
59
+
60
+ def log(severity, message = nil, progname = nil, &block)
61
+ return if !config.enabled
62
+
63
+ uuid = RequestStore.store[:heavylog_request_id]
64
+ return if !uuid
65
+
66
+ if message.nil?
67
+ if block_given?
68
+ message = yield
69
+ else
70
+ message = progname
71
+ end
72
+ end
73
+
74
+ RequestStore.store[:heavylog_buffer] ||= StringIO.new
75
+ RequestStore.store[:heavylog_buffer].puts(message)
76
+ end
77
+
78
+ def finish
79
+ return if !config.enabled
80
+
81
+ buffer = RequestStore.store[:heavylog_buffer]
82
+ return if !buffer
83
+
84
+ request = {
85
+ request_id: RequestStore.store[:heavylog_request_id],
86
+ messages: buffer.string.dup
87
+ }.merge(RequestStore.store[:heavylog_request_data] || {})
88
+
89
+ formatted = Heavylog.formatter.call(request)
90
+ Heavylog.logger.send(Heavylog.log_level, formatted)
91
+ end
92
+
93
+ def config
94
+ application.config.heavylog
95
+ end
5
96
  end
97
+
98
+ require 'heavylog/railtie' if defined?(Rails)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heavylog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristjan Rang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-31 00:00:00.000000000 Z
11
+ date: 2018-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,62 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: actionpack
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '5'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: railties
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '5'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: request_store
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.4'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.4'
55
111
  description: Format all Rails logging per request
56
112
  email:
57
113
  - mail@rang.ee
@@ -63,6 +119,7 @@ files:
63
119
  - ".rspec"
64
120
  - ".travis.yml"
65
121
  - Gemfile
122
+ - Gemfile.lock
66
123
  - LICENSE.txt
67
124
  - README.md
68
125
  - Rakefile
@@ -70,6 +127,13 @@ files:
70
127
  - bin/setup
71
128
  - heavylog.gemspec
72
129
  - lib/heavylog.rb
130
+ - lib/heavylog/formatters/json.rb
131
+ - lib/heavylog/formatters/raw.rb
132
+ - lib/heavylog/log_subscriber.rb
133
+ - lib/heavylog/middleware.rb
134
+ - lib/heavylog/ordered_options.rb
135
+ - lib/heavylog/railtie.rb
136
+ - lib/heavylog/request_logger.rb
73
137
  - lib/heavylog/version.rb
74
138
  homepage: https://github.com/krisrang/heavylog
75
139
  licenses: