loga 2.4.0 → 2.5.4

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
  SHA256:
3
- metadata.gz: 8b069a9b029cfb82d0a179ebb76738b71506eb717c49e0053c135204225f7d4f
4
- data.tar.gz: e62a39b1e52025dc1bcd7a8c69b1d8e260f73e954de16f7c9fbfb42529154363
3
+ metadata.gz: b0e5af261daf89f7f7e4b80be296a8f19307a33f187a501e23eb5295fbedd8f2
4
+ data.tar.gz: ed0d0281f4d40078051363434600bdd9a8f843ba70a85fde3b110d56a58e2ca3
5
5
  SHA512:
6
- metadata.gz: 9aae956e2b49cc519590cca3be9d32d6d268871b4d8bc97fb568b66003d3fd7913f04debf445b6cee2ced3a04d1d3af610eb256c48411b3f92fc76b3120c8d51
7
- data.tar.gz: 16f42b6af8af4479ae5dfec57f47c27db4b41d9e4b7e58491e289cb5d487316d115fe47723bbf8690c30d692da59bb134a29f2b9eb964b9ff7477a3a5b2fd1f0
6
+ metadata.gz: 64128d6a8442ce7006629f3056c94487e9316f7c07cd284b3f96f3bb01fd5daccd3a7e4372dfb746376e8e91e2ccb52e015e381bd1c2fdc1774b86e5a5a78f43
7
+ data.tar.gz: bf0393ec37a4f9f8a023d031b5823ad94151fc98b9f1d2ce1ee2bea8b580c88db3013b35b73c68636dfb482dbabd1019771b0b0542ec11c8b2ab0baad290a022
data/.circleci/config.yml CHANGED
@@ -74,6 +74,10 @@ jobs:
74
74
  docker:
75
75
  - image: circleci/ruby:2.6
76
76
  <<: *test_build
77
+ ruby-2.7:
78
+ docker:
79
+ - image: circleci/ruby:2.7
80
+ <<: *test_build
77
81
  rubocop:
78
82
  <<: *basic_build
79
83
  steps:
@@ -135,6 +139,12 @@ workflows:
135
139
  only: /.*/
136
140
  requires:
137
141
  - build
142
+ - ruby-2.7:
143
+ filters:
144
+ tags:
145
+ only: /.*/
146
+ requires:
147
+ - build
138
148
  - upload-coverage:
139
149
  filters:
140
150
  tags:
@@ -144,6 +154,7 @@ workflows:
144
154
  - ruby-2.4
145
155
  - ruby-2.5
146
156
  - ruby-2.6
157
+ - ruby-2.7
147
158
  - push-to-rubygems:
148
159
  filters:
149
160
  tags:
@@ -156,3 +167,4 @@ workflows:
156
167
  - ruby-2.4
157
168
  - ruby-2.5
158
169
  - ruby-2.6
170
+ - ruby-2.7
data/Appraisals CHANGED
@@ -8,20 +8,32 @@ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.4.0')
8
8
  end
9
9
  end
10
10
 
11
- appraise 'rails42' do
12
- gem 'rails', '~> 4.2.0'
11
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
12
+ appraise 'rails42' do
13
+ gem 'rails', '~> 4.2.0'
14
+ end
15
+
16
+ appraise 'rails50' do
17
+ gem 'rails', '~> 5.0.0'
18
+ end
19
+
20
+ appraise 'rails52' do
21
+ gem 'rails', '~> 5.2.0'
22
+ end
13
23
  end
14
24
 
15
25
  appraise 'sinatra14' do
16
26
  gem 'sinatra', '~> 1.4.0'
17
27
  end
18
28
 
19
- appraise 'rails50' do
20
- gem 'rails', '~> 5.0.0'
21
- end
29
+ if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('2.5.0')
30
+ appraise 'rails60' do
31
+ gem 'rails', '~> 6.0.0'
32
+ end
22
33
 
23
- appraise 'rails52' do
24
- gem 'rails', '~> 5.2.0'
34
+ appraise 'sidekiq6' do
35
+ gem 'sidekiq', '~> 6.0'
36
+ end
25
37
  end
26
38
 
27
39
  appraise 'sidekiq51' do
data/CHANGELOG.md CHANGED
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [2.5.4] - 2021-03-24
8
+ ### Fixed
9
+ - Remove state from Rack middleware, to prevent race conditions where one request would overwrite the state of another
10
+
11
+ ## [2.5.3] - 2020-10-27
12
+ ### Fixed
13
+ - Support for sidekiq 6 - previous versions were causing sidekiq to crash with `Internal exception!`
14
+
15
+ ## [2.5.2] - 2020-10-21
16
+ ### Fixed
17
+ - Support for sidekiq 6
18
+
19
+ ## [2.5.1] - 2020-01-02
20
+ ### Fixed
21
+ - Fixed a long standing bug that would mask exceptions raised by the host application when serving requests. The original exception would be replaced with a `TypeError` one due to a HTTP status code not being available within `Loga::Rack::Logger`.
22
+
23
+ ## [2.5.0] - 2019-11-12
24
+ ### Added
25
+ - Add support for rails 6
26
+
7
27
  ## [2.4.0] - 2019-09-03
8
28
  ### Fixed
9
29
  - `duration` in the `sidekiq` integration is now calculated correctly
data/Gemfile CHANGED
@@ -4,5 +4,5 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :test do
7
- gem 'simplecov'
7
+ gem 'simplecov', '~> 0.17.0'
8
8
  end
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Build Status](https://circleci.com/gh/FundingCircle/loga/tree/master.svg?style=shield&circle-token=9b81c3cf8468a8c3dc760f4c0398cf8914cb27d4)](https://circleci.com/gh/FundingCircle/loga/tree/master)
5
5
  [![Code Quality](https://codeclimate.com/repos/5563694f6956805723005d2f/badges/8eecb9144730614fb39e/gpa.svg)](https://codeclimate.com/repos/5563694f6956805723005d2f/feed)
6
6
  [![Test Coverage](https://codeclimate.com/repos/5563694f6956805723005d2f/badges/8eecb9144730614fb39e/coverage.svg)](https://codeclimate.com/repos/5563694f6956805723005d2f/coverage)
7
- [![Dependency Status](https://gemnasium.com/badges/github.com/FundingCircle/loga.svg)](https://gemnasium.com/github.com/FundingCircle/loga)
7
+ [![Dependency Status](https://img.shields.io/librariesio/release/rubygems/loga)](https://libraries.io/rubygems/loga)
8
8
 
9
9
  ## Description
10
10
 
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 6.0.0"
6
+
7
+ group :test do
8
+ gem "simplecov", "~> 0.17.0"
9
+ end
10
+
11
+ gemspec path: "../"
@@ -5,7 +5,7 @@ source "https://rubygems.org"
5
5
  gem "sidekiq", "~> 5.1.0"
6
6
 
7
7
  group :test do
8
- gem "simplecov"
8
+ gem "simplecov", "~> 0.17.0"
9
9
  end
10
10
 
11
11
  gemspec path: "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "sidekiq", "~> 6.0"
6
+
7
+ group :test do
8
+ gem "simplecov", "~> 0.17.0"
9
+ end
10
+
11
+ gemspec path: "../"
@@ -5,7 +5,7 @@ source "https://rubygems.org"
5
5
  gem "sinatra", "~> 1.4.0"
6
6
 
7
7
  group :test do
8
- gem "simplecov"
8
+ gem "simplecov", "~> 0.17.0"
9
9
  end
10
10
 
11
11
  gemspec path: "../"
@@ -3,7 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  group :test do
6
- gem "simplecov"
6
+ gem "simplecov", "~> 0.17.0"
7
7
  end
8
8
 
9
9
  gemspec path: "../"
@@ -79,6 +79,7 @@ module Loga
79
79
  { format: ENV['LOGA_FORMAT'].presence }.reject { |_, v| v.nil? }
80
80
  end
81
81
 
82
+ # Note: sidekiq 6 will extend the logger -> https://github.com/mperham/sidekiq/blob/v6.1.2/lib/sidekiq.rb#L210
82
83
  def initialize_logger
83
84
  device.sync = sync
84
85
  logger = Logger.new(device)
@@ -47,7 +47,8 @@ module Loga
47
47
  end
48
48
 
49
49
  event.timestamp ||= time
50
- event.data ||= {}
50
+ # Overwrite sidekiq_context data anything manually specified
51
+ event.data = sidekiq_context.merge!(event.data || {})
51
52
  event.data.tap do |hash|
52
53
  hash.merge! compute_exception(event.exception)
53
54
  hash.merge! compute_type(event.type)
@@ -101,6 +102,20 @@ module Loga
101
102
  tags: current_tags.join(' '),
102
103
  }
103
104
  end
105
+
106
+ def sidekiq_context
107
+ return {} unless defined?(::Sidekiq::Context)
108
+
109
+ c = ::Sidekiq::Context.current
110
+
111
+ # The context usually holds :class and :jid. :elapsed is added when the job ends
112
+ data = c.dup
113
+ if data.key?(:elapsed)
114
+ data[:duration] = data[:elapsed].to_f
115
+ data.delete(:elapsed)
116
+ end
117
+ data
118
+ end
104
119
  end
105
120
  end
106
121
  end
@@ -7,62 +7,57 @@ module Loga
7
7
  @app = app
8
8
  end
9
9
 
10
- def call(env)
10
+ def call(env, started_at = Time.now)
11
11
  request = Loga::Rack::Request.new(env)
12
12
  env['loga.request.original_path'] = request.path
13
13
 
14
14
  if logger.respond_to?(:tagged)
15
- logger.tagged(compute_tags(request)) { call_app(request, env) }
15
+ logger.tagged(compute_tags(request)) { call_app(request, env, started_at) }
16
16
  else
17
- call_app(request, env)
17
+ call_app(request, env, started_at)
18
18
  end
19
19
  end
20
20
 
21
21
  private
22
22
 
23
- attr_reader :data, :env, :request, :started_at
24
-
25
- def call_app(request, env)
26
- @data = {}
27
- @env = env
28
- @request = request
29
- @started_at = Time.now
30
-
31
- @app.call(env).tap { |status, _headers, _body| data['status'] = status.to_i }
23
+ def call_app(request, env, started_at)
24
+ status, _headers, _body = @app.call(env)
32
25
  ensure
33
- set_data
34
- send_message
35
- end
26
+ data = generate_data(request, status, started_at)
36
27
 
37
- # rubocop:disable Metrics/LineLength
38
- def set_data
39
- data['method'] = request.request_method
40
- data['path'] = request.original_path
41
- data['params'] = request.filtered_parameters
42
- data['request_id'] = request.uuid
43
- data['request_ip'] = request.ip
44
- data['user_agent'] = request.user_agent
45
- data['controller'] = request.controller_action_name if request.controller_action_name
46
- data['duration'] = duration_in_ms(started_at, Time.now)
47
- end
48
- # rubocop:enable Metrics/LineLength
28
+ exception = compute_exception(env)
49
29
 
50
- def send_message
51
30
  event = Loga::Event.new(
52
31
  data: { request: data },
53
- exception: compute_exception,
54
- message: compute_message,
32
+ exception: exception,
33
+ message: compute_message(request, data),
55
34
  timestamp: started_at,
56
35
  type: 'request',
57
36
  )
58
- logger.public_send(compute_level, event)
37
+
38
+ exception ? logger.error(event) : logger.info(event)
39
+ end
40
+
41
+ def generate_data(request, status, started_at)
42
+ controller = request.controller_action_name
43
+ status ||= 500
44
+ {
45
+ 'method' => request.request_method,
46
+ 'path' => request.original_path,
47
+ 'params' => request.filtered_parameters,
48
+ 'request_id' => request.uuid,
49
+ 'request_ip' => request.ip,
50
+ 'user_agent' => request.user_agent,
51
+ 'duration' => duration_in_ms(started_at, Time.now),
52
+ 'status' => status.to_i,
53
+ }.tap { |d| d['controller'] = controller if controller }
59
54
  end
60
55
 
61
56
  def logger
62
57
  Loga.logger
63
58
  end
64
59
 
65
- def compute_message
60
+ def compute_message(request, data)
66
61
  '%<method>s %<filtered_full_path>s %<status>d in %<duration>dms' % {
67
62
  method: request.request_method,
68
63
  filtered_full_path: request.filtered_full_path,
@@ -71,19 +66,14 @@ module Loga
71
66
  }
72
67
  end
73
68
 
74
- def compute_level
75
- compute_exception ? :error : :info
76
- end
69
+ def compute_exception(env)
70
+ exception =
71
+ env['loga.exception'] || env['action_dispatch.exception'] ||
72
+ env['sinatra.error'] || env['rack.exception']
77
73
 
78
- def compute_exception
79
74
  filter_exceptions.include?(exception.class.to_s) ? nil : exception
80
75
  end
81
76
 
82
- def exception
83
- env['loga.exception'] || env['action_dispatch.exception'] ||
84
- env['sinatra.error'] || env['rack.exception']
85
- end
86
-
87
77
  def filter_exceptions
88
78
  Loga.configuration.filter_exceptions
89
79
  end
data/lib/loga/railtie.rb CHANGED
@@ -125,7 +125,7 @@ module Loga
125
125
  def silence_rails_rack_logger
126
126
  case Rails::VERSION::MAJOR
127
127
  when 3 then require 'loga/ext/rails/rack/logger3.rb'
128
- when 4..5 then require 'loga/ext/rails/rack/logger.rb'
128
+ when 4..6 then require 'loga/ext/rails/rack/logger.rb'
129
129
  else
130
130
  raise Loga::ConfigurationError,
131
131
  "Rails #{Rails::VERSION::MAJOR} is unsupported"
data/lib/loga/sidekiq.rb CHANGED
@@ -1,16 +1,24 @@
1
- require 'loga/sidekiq/job_logger'
2
-
3
1
  module Loga
4
2
  module Sidekiq
5
3
  def self.configure_logging
6
4
  return unless defined?(::Sidekiq)
7
5
  return if Gem::Version.new(::Sidekiq::VERSION) < Gem::Version.new('5.0')
8
6
 
9
- ::Sidekiq.configure_server do |config|
10
- config.options[:job_logger] = Loga::Sidekiq::JobLogger
7
+ if Gem::Version.new(::Sidekiq::VERSION) < Gem::Version.new('6.0')
8
+ require 'loga/sidekiq5/job_logger'
9
+
10
+ ::Sidekiq.configure_server do |config|
11
+ config.options[:job_logger] = Loga::Sidekiq5::JobLogger
12
+ end
13
+ elsif Gem::Version.new(::Sidekiq::VERSION) < Gem::Version.new('7.0')
14
+ require 'loga/sidekiq6/job_logger'
15
+
16
+ ::Sidekiq.configure_server do |config|
17
+ config.options[:job_logger] = Loga::Sidekiq6::JobLogger
18
+ end
11
19
  end
12
20
 
13
- ::Sidekiq::Logging.logger = Loga.configuration.logger
21
+ ::Sidekiq.logger = Loga.configuration.logger
14
22
  end
15
23
  end
16
24
  end
@@ -1,9 +1,7 @@
1
1
  module Loga
2
- module Sidekiq
2
+ module Sidekiq5
3
3
  # The approach of using a custom job logger in sidekiq was introduced
4
4
  # in v5.0: https://github.com/mperham/sidekiq/pull/3235
5
- # This job logger does not support logging for Sidekiq versions
6
- # that are before 5.0
7
5
  class JobLogger
8
6
  include Loga::Utilities
9
7
 
@@ -0,0 +1,50 @@
1
+ require 'sidekiq/job_logger'
2
+
3
+ module Loga
4
+ module Sidekiq6
5
+ class JobLogger < ::Sidekiq::JobLogger
6
+ EVENT_TYPE = 'sidekiq'.freeze
7
+
8
+ def call(item, _queue)
9
+ start = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
10
+
11
+ yield
12
+
13
+ with_elapsed_time_context(start) do
14
+ loga_log(
15
+ message: "#{item['class']} with jid: '#{item['jid']}' done", item: item,
16
+ )
17
+ end
18
+ rescue Exception => e # rubocop:disable Lint/RescueException
19
+ with_elapsed_time_context(start) do
20
+ loga_log(
21
+ message: "#{item['class']} with jid: '#{item['jid']}' fail", item: item,
22
+ exception: e
23
+ )
24
+ end
25
+
26
+ raise
27
+ end
28
+
29
+ private
30
+
31
+ def loga_log(message:, item:, exception: nil)
32
+ data = {
33
+ 'created_at' => item['created_at'],
34
+ 'enqueued_at' => item['enqueued_at'],
35
+ 'jid' => item['jid'],
36
+ 'queue' => item['queue'],
37
+ 'retry' => item['retry'],
38
+ 'params' => item['args'],
39
+ 'class' => item['class'],
40
+ }
41
+ if exception
42
+ data['exception'] = exception
43
+ @logger.warn(Event.new(type: EVENT_TYPE, message: message, data: data))
44
+ else
45
+ @logger.info(Event.new(type: EVENT_TYPE, message: message, data: data))
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end