request_headers_logger 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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