request_headers_logger 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
  SHA1:
3
- metadata.gz: 1a3ef4bf0a8787742b143de9fd75e856c99284dd
4
- data.tar.gz: 8159bb657b7de2a5036a113d0dc05b65d4a1ac34
3
+ metadata.gz: 426a124479eca311531e5bfea76dd501c1d18d91
4
+ data.tar.gz: 5f0588b3dd89067b276b144a826360511a8bab6d
5
5
  SHA512:
6
- metadata.gz: b8bff686ae38f14bf3c5e4db57466c63385b307cd6a4633b61653b2b470f7fc89f27fbb843d50c28c507d2b0c319365af5ce988f08da479f57eea1d3d1a09ddb
7
- data.tar.gz: f08ca98445f59ad39f3e0c88ad10b18f2cb4982049b177ce0fbf704ce4de2b3e6493f8314ce863dbaf881528d49a639ecce67e32590ab6e612f9e8ba849bfea7
6
+ metadata.gz: fc35c05ebc50865e5475852bdcdf8d987a90470cb4b3fda32582429b77d0de04e3d7f6c581662b9a64cf32a89856aef90e46fa308f0ae571cbdf670ad783420b
7
+ data.tar.gz: 9f683fc2afee57432db86b18fe506e174fb8966467c080c479f57c8dc827d1689357e11f8ecbb2f76c3d6fe894b8318b1346a5abdb90b806a5052a6b9ec85f4e
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- request_headers_logger (0.0.1)
5
- activesupport (> 4.0)
4
+ request_headers_logger (0.0.2)
6
5
  request_headers_middleware (~> 0.0.4)
7
6
 
8
7
  GEM
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RequestHeadersLogger
4
+ class Configuration
5
+ class InvalidKey < StandardError
6
+ def initialize(key)
7
+ super("Configuration option '#{key.inspect}' is not a valid key")
8
+ end
9
+ end
10
+
11
+ CONFIG_KEYS = [
12
+ :log_format, # [logger_format] default or json
13
+ :loggers, # [Loggers] List of all loggers used.
14
+ :tag_format, # [tag_format]
15
+ ].freeze
16
+
17
+ LOG_FORMATS = %w[text json].freeze
18
+ TAG_FORMATS = %w[val key_val].freeze
19
+
20
+ def initialize
21
+ @configs = {
22
+ log_format: LOG_FORMATS.first,
23
+ loggers: [],
24
+ tag_format: TAG_FORMATS.first
25
+ }
26
+ end
27
+
28
+ def []=(key, value)
29
+ raise InvalidKey, key unless CONFIG_KEYS.include?(key)
30
+
31
+ @configs[key] = value
32
+ end
33
+
34
+ def [](key)
35
+ @configs[key]
36
+ end
37
+
38
+ def log_format
39
+ LOG_FORMATS.include?(@configs[:log_format]) ? @configs[:log_format] : LOG_FORMATS.first
40
+ end
41
+
42
+ def tag_format
43
+ TAG_FORMATS.include?(@configs[:tag_format]) ? @configs[:tag_format] : TAG_FORMATS.first
44
+ end
45
+ end
46
+ end
@@ -13,21 +13,21 @@ module RequestHeadersLogger
13
13
 
14
14
  lifecycle.before(:perform) do |worker, job|
15
15
  RequestHeadersMiddleware.store = job.payload_object.instance_variable_get(:@store)
16
-
17
- RequestHeadersLogger.tag_logger Delayed::Worker.logger
18
- RequestHeadersLogger.tag_logger ::Rails.logger unless dj_use_rails_logger
16
+ set_dj_loggers
19
17
  end
20
18
 
21
19
  lifecycle.after(:perform) do |worker, job|
22
- RequestHeadersLogger.untag_logger Delayed::Worker.logger
23
- RequestHeadersLogger.untag_logger ::Rails.logger unless dj_use_rails_logger
24
-
25
20
  RequestHeadersMiddleware.store = {}
26
21
  end
27
22
  end
28
23
 
29
- def self.dj_use_rails_logger
30
- ::Rails.logger == Delayed::Worker.logger
24
+ def self.set_dj_loggers
25
+ RequestHeadersLogger.configure do |config|
26
+ loggers = [Delayed::Worker.logger]
27
+ loggers << ::Rails.logger
28
+
29
+ config[:loggers] = loggers
30
+ end
31
31
  end
32
32
  end
33
33
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RequestHeadersLogger
4
+ class JsonFormatter
5
+ def call(severity, timestamp, progname, msg)
6
+ json = { level: severity, timestamp: timestamp.to_s, message: msg.strip }
7
+ json = json.merge(progname: progname.to_s) unless progname.nil?
8
+
9
+ json.merge(RequestHeadersLogger.tags || {}).to_json + "\n"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'message_queue_plugin' if defined?(MessageQueue)
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'message_queue'
4
+
5
+ module RequestHeadersLogger
6
+ class MQRequestHeadersPlugin < MessageQueue::Plugin
7
+ class << self
8
+ def symbolize(obj = {})
9
+ if obj.is_a? Hash
10
+ return obj.reduce({}) do |memo, (k, v)|
11
+ memo.tap { |m| m[k.to_sym] = symbolize(v) }
12
+ end
13
+ end
14
+ obj
15
+ end
16
+ end
17
+
18
+ callbacks do |lifecycle|
19
+ lifecycle.before(:publish) do |_message, options|
20
+ options[:headers] ||= {}
21
+ options[:headers][:store] = RequestHeadersMiddleware.store
22
+ end
23
+
24
+ lifecycle.before(:consume) do |delivery_info, properties, payload|
25
+ store = symbolize(properties.headers).dig(:store) || {}
26
+ RequestHeadersMiddleware.store = store
27
+
28
+ set_dj_loggers
29
+ end
30
+
31
+ lifecycle.after(:consume) do |delivery_info, properties, payload|
32
+ RequestHeadersMiddleware.store = {}
33
+ end
34
+ end
35
+
36
+ def self.set_dj_loggers
37
+ RequestHeadersLogger.configure do |config|
38
+ config[:loggers] = [MessageQueue.logger]
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ MessageQueue.configure do |config|
45
+ config[:plugins] << RequestHeadersLogger::MQRequestHeadersPlugin
46
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RequestHeadersLogger
4
+ class TextFormatter < ::Logger::Formatter
5
+ def call(severity, timestamp, progname, msg)
6
+ super(severity, timestamp, progname, "#{tags_text}#{msg}")
7
+ end
8
+
9
+ def tags_text
10
+ RequestHeadersLogger.tags.collect { |key, val| tag_value(key, val) }.join if RequestHeadersLogger.tags.any?
11
+ end
12
+
13
+ def tag_value(key, value)
14
+ tag = value.to_s
15
+ tag = "#{key}: #{tag}" if RequestHeadersLogger.tag_format.eql? 'key_val'
16
+
17
+ "[#{tag}] "
18
+ end
19
+ end
20
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RequestHeadersLogger
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
@@ -1,37 +1,55 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support'
4
3
  require 'request_headers_middleware'
4
+ require 'request_headers_logger/configuration'
5
+ require 'request_headers_logger/json_formatter'
6
+ require 'request_headers_logger/text_formatter'
5
7
  require 'request_headers_logger/delayed_job/delayed_job'
8
+ require 'request_headers_logger/message_queue/message_queue'
6
9
 
7
10
  module RequestHeadersLogger # :nodoc:
8
11
  extend self
9
12
 
10
13
  attr_accessor :whitelist
11
- @whitelist = ['x-request-id'.to_sym]
14
+ @whitelist = ['x-request-id'.to_sym]
15
+ @configuration = Configuration.new
16
+
17
+ def configure
18
+ yield @configuration
19
+
20
+ prepare_loggers
21
+ end
12
22
 
13
23
  def tags
14
24
  filter(RequestHeadersMiddleware.store)
15
25
  end
16
26
 
17
- def tag_logger(logger)
18
- logger = tagged_logger(logger) unless logger.respond_to? :push_tags
19
- tags.each do |_tag, value|
20
- logger.push_tags(value) unless value.nil?
21
- end
27
+ def log_format
28
+ @configuration.log_format
22
29
  end
23
30
 
24
- def untag_logger(logger)
25
- logger = tagged_logger(logger) unless logger.respond_to? :pop_tags
26
- tags.each do |_tag, value|
27
- logger.pop_tags unless value.nil?
28
- end
31
+ def tag_format
32
+ @configuration.tag_format
33
+ end
34
+
35
+ def loggers
36
+ @configuration[:loggers]
29
37
  end
30
38
 
31
39
  private
32
40
 
33
- def tagged_logger(logger)
34
- ActiveSupport::TaggedLogging.new(logger)
41
+ def prepare_loggers
42
+ loggers.each do |logger|
43
+ logger_formatter logger
44
+ end
45
+ end
46
+
47
+ def logger_formatter(logger)
48
+ logger.tap { |obj| obj.formatter = formatter_class.new }
49
+ end
50
+
51
+ def formatter_class
52
+ RequestHeadersLogger.const_get("#{log_format.capitalize}Formatter")
35
53
  end
36
54
 
37
55
  def filter(store)
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.email = ['wshihadh@gmail.com']
12
12
  gem.description = 'RequestHeaderLogger Allows you to tag logs with RequestHeader flags.'
13
13
  gem.summary = 'RequestHeaderLogger Allows you to tag logs with RequestHeader flags.'
14
- gem.homepage = 'https://github.com/wshihadeh/request_headers_logger'
14
+ gem.homepage = 'https://github.com/fidor/request_headers_logger'
15
15
  gem.licenses = ['MIT']
16
16
 
17
17
  gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
@@ -19,7 +19,6 @@ Gem::Specification.new do |gem|
19
19
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
20
  gem.require_paths = ['lib']
21
21
 
22
- gem.add_dependency 'activesupport', '> 4.0'
23
22
  gem.add_dependency 'request_headers_middleware', '~> 0.0.4'
24
23
 
25
24
  gem.add_development_dependency 'delayed_job', '~> 4.1', '>= 4.1.4'
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe RequestHeadersLogger::Configuration do
6
+ let(:config) { RequestHeadersLogger::Configuration.new }
7
+
8
+ describe '.log_format' do
9
+ it 'return text as default' do
10
+ expect(config.log_format).to eq('text')
11
+ end
12
+
13
+ it 'return text when log_format is not supported' do
14
+ config[:log_format] = 'syslog'
15
+ expect(config.log_format).to eq('text')
16
+ end
17
+
18
+ it 'return log_format value when it is supported' do
19
+ config[:log_format] = 'json'
20
+ expect(config.log_format).to eq('json')
21
+ end
22
+ end
23
+
24
+ describe '.tag_format' do
25
+ it 'return val as default' do
26
+ expect(config.tag_format).to eq('val')
27
+ end
28
+
29
+ it 'return val when log_format is not supported' do
30
+ config[:tag_format] = 'unknwn'
31
+ expect(config.tag_format).to eq('val')
32
+ end
33
+
34
+ it 'return tag_format value when it is supported' do
35
+ config[:tag_format] = 'key_val'
36
+ expect(config.tag_format).to eq('key_val')
37
+ end
38
+ end
39
+
40
+ describe '[]' do
41
+ it 'return text as default for log_format' do
42
+ expect(config[:log_format]).to eq('text')
43
+ end
44
+
45
+ it 'return empty array as default for loggers' do
46
+ expect(config[:loggers]).to eq([])
47
+ end
48
+ end
49
+
50
+ describe '[]=' do
51
+ it 'assign valid config keys' do
52
+ logger = Logger.new(STDOUT)
53
+
54
+ config[:log_format] = 'json'
55
+ config[:loggers] << logger
56
+
57
+ expect(config[:log_format]).to eq('json')
58
+ expect(config[:loggers].first).to eq(logger)
59
+ end
60
+
61
+ it 'raise an error for invalid configs ' do
62
+ expect { config[:undefined] = 'undefined' }.to raise_error(RequestHeadersLogger::Configuration::InvalidKey)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'json'
6
+
7
+ RSpec.describe RequestHeadersLogger::JsonFormatter do
8
+ let(:buffer) { StringIO.new }
9
+ let(:logger) do
10
+ logger = Logger.new(buffer)
11
+ logger.progname = 'dummy'
12
+ logger.formatter = RequestHeadersLogger::JsonFormatter.new
13
+ logger
14
+ end
15
+
16
+ it 'output logs in a json format' do
17
+ logger.info('json log message')
18
+ json = JSON.parse(buffer.string)
19
+
20
+ expect(json.class).to eq Hash
21
+ expect(json.size).to eq 4
22
+ expect(json.keys).to eq %w[level timestamp message progname]
23
+ expect(json['level']).to eq 'INFO'
24
+ expect(json['message']).to eq 'json log message'
25
+ expect(json['progname']).to eq 'dummy'
26
+ end
27
+
28
+ it 'include tags in the json' do
29
+ RequestHeadersMiddleware.store = { 'X-Request-Id': 'ef382618', 'tag': 'SSS' }
30
+
31
+ logger.info('json log message')
32
+ json = JSON.parse(buffer.string)
33
+
34
+ expect(json.class).to eq Hash
35
+ expect(json.size).to eq 5
36
+ expect(json.keys).to eq %w[level timestamp message progname X-Request-Id]
37
+ expect(json['level']).to eq 'INFO'
38
+ expect(json['message']).to eq 'json log message'
39
+ expect(json['progname']).to eq 'dummy'
40
+ expect(json['X-Request-Id']).to eq 'ef382618'
41
+
42
+ RequestHeadersMiddleware.store = {}
43
+ end
44
+ end
@@ -1,27 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'active_support'
5
4
 
6
5
  RSpec.describe RequestHeadersLogger do
7
- let(:logger) { ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) }
6
+ let(:logger) { Logger.new(STDOUT) }
8
7
 
9
8
  describe '.tags' do
10
- before(:each) do
9
+ before do
11
10
  @store = { 'X-Request-Id': 'ef382618-e46d-42f5-aca6-ae9e1db8fee0',
12
11
  'X-Request-Id2': 'e46def38-2618-42f5-ae9e-1db8fee0aca6',
13
12
  'X-Request-Id3': '618e46de-f382-42f5-aca6-8fee0ae9e1db' }
13
+ RequestHeadersMiddleware.store = @store
14
14
  end
15
15
 
16
- it 'return only x-request-id by default' do
17
- RequestHeadersMiddleware.store = @store
16
+ after do
17
+ RequestHeadersMiddleware.store = {}
18
+ end
18
19
 
20
+ it 'return only x-request-id by default' do
19
21
  expect(RequestHeadersLogger.tags.count).to eq(1)
20
22
  expect(RequestHeadersLogger.tags).to eq('X-Request-Id': 'ef382618-e46d-42f5-aca6-ae9e1db8fee0')
21
23
  end
22
24
 
23
25
  it 'return empty hash when whitelist is empty' do
24
- RequestHeadersMiddleware.store = @store
25
26
  RequestHeadersLogger.whitelist = []
26
27
 
27
28
  expect(RequestHeadersLogger.tags.count).to eq(0)
@@ -29,7 +30,6 @@ RSpec.describe RequestHeadersLogger do
29
30
  end
30
31
 
31
32
  it 'return only the white listed flags' do
32
- RequestHeadersMiddleware.store = @store
33
33
  RequestHeadersLogger.whitelist = ['x-request-id'.to_sym, 'x-request-id2'.to_sym]
34
34
 
35
35
  expect(RequestHeadersLogger.tags.count).to eq(2)
@@ -37,29 +37,4 @@ RSpec.describe RequestHeadersLogger do
37
37
  expect(RequestHeadersLogger.tags[:'X-Request-Id2']).to eq('e46def38-2618-42f5-ae9e-1db8fee0aca6')
38
38
  end
39
39
  end
40
-
41
- describe '.tag_logger' do
42
- it 'tag the logger' do
43
- store = { 'X-Request-Id': 'ef382618-e46d-42f5-aca6-ae9e1db8fee0' }
44
- RequestHeadersMiddleware.store = store
45
- RequestHeadersLogger.tag_logger logger
46
- tags = logger.formatter.current_tags
47
-
48
- expect(tags.count).to eq(1)
49
- expect(tags.first).to eq(store[:'X-Request-Id'])
50
- end
51
- end
52
-
53
- describe '.untag_logger' do
54
- it 'untag the logger' do
55
- store = { 'X-Request-Id': 'ef382618-e46d-42f5-aca6-ae9e1db8fee0' }
56
- RequestHeadersMiddleware.store = store
57
- RequestHeadersLogger.tag_logger logger
58
- RequestHeadersLogger.untag_logger logger
59
- tags = logger.formatter.current_tags
60
-
61
- expect(tags.count).to eq(0)
62
- expect(tags).to eq([])
63
- end
64
- end
65
40
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe RequestHeadersLogger::TextFormatter do
6
+ let(:buffer) { StringIO.new }
7
+ let(:logger) do
8
+ logger = Logger.new(buffer)
9
+ logger.progname = 'dummy'
10
+ logger.formatter = RequestHeadersLogger::TextFormatter.new
11
+ logger
12
+ end
13
+
14
+ it 'output logs in a text format' do
15
+ logger.info('text log message')
16
+
17
+ expect(buffer.string).to match(/I, \[[0-9\-T:\.# ]*\] INFO -- dummy: text log message$/)
18
+ end
19
+
20
+ context 'store has some tags' do
21
+ before do
22
+ RequestHeadersMiddleware.store = { 'X-Request-Id': 'ef382618', 'tag': 'SSS' }
23
+ end
24
+
25
+ after do
26
+ RequestHeadersMiddleware.store = {}
27
+ RequestHeadersLogger.configure { |c| c[:tag_format] = 'val' }
28
+ end
29
+
30
+ it 'output tags with key_val formmat' do
31
+ RequestHeadersLogger.configure { |c| c[:tag_format] = 'key_val' }
32
+ logger.info('text log message')
33
+ output = buffer.string
34
+
35
+ expect(output).to match(/I, \[[0-9\-T:\.# ]*\] INFO -- dummy: \[X-Request-Id: ef382618\] text log message$/)
36
+ end
37
+
38
+ it 'include tags in the log line' do
39
+ logger.info('text log message')
40
+
41
+ expect(buffer.string).to match(/I, \[[0-9\-T:\.# ]*\] INFO -- dummy: \[ef382618\] text log message$/)
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: request_headers_logger
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
  - Al-waleed Shihadeh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-19 00:00:00.000000000 Z
11
+ date: 2018-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">"
18
- - !ruby/object:Gem::Version
19
- version: '4.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">"
25
- - !ruby/object:Gem::Version
26
- version: '4.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: request_headers_middleware
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -165,16 +151,24 @@ files:
165
151
  - Rakefile
166
152
  - bin/travis
167
153
  - lib/request_headers_logger.rb
154
+ - lib/request_headers_logger/configuration.rb
168
155
  - lib/request_headers_logger/delayed_job/delayed_job.rb
169
156
  - lib/request_headers_logger/delayed_job/performable_method.rb
170
157
  - lib/request_headers_logger/delayed_job/request_header_delayed_plugin.rb
158
+ - lib/request_headers_logger/json_formatter.rb
159
+ - lib/request_headers_logger/message_queue/message_queue.rb
160
+ - lib/request_headers_logger/message_queue/message_queue_plugin.rb
161
+ - lib/request_headers_logger/text_formatter.rb
171
162
  - lib/request_headers_logger/version.rb
172
163
  - request_headers_logger.gemspec
164
+ - spec/configuration_spec.rb
173
165
  - spec/delayed_job/performable_method_spec.rb
166
+ - spec/json_formatter_spec.rb
174
167
  - spec/request_headers_logger_spec.rb
175
168
  - spec/spec_helper.rb
176
169
  - spec/support/mock_dj_user.rb
177
- homepage: https://github.com/wshihadeh/request_headers_logger
170
+ - spec/text_formatter_spec.rb
171
+ homepage: https://github.com/fidor/request_headers_logger
178
172
  licenses:
179
173
  - MIT
180
174
  metadata: {}
@@ -199,7 +193,10 @@ signing_key:
199
193
  specification_version: 4
200
194
  summary: RequestHeaderLogger Allows you to tag logs with RequestHeader flags.
201
195
  test_files:
196
+ - spec/configuration_spec.rb
202
197
  - spec/delayed_job/performable_method_spec.rb
198
+ - spec/json_formatter_spec.rb
203
199
  - spec/request_headers_logger_spec.rb
204
200
  - spec/spec_helper.rb
205
201
  - spec/support/mock_dj_user.rb
202
+ - spec/text_formatter_spec.rb