loga 2.4.0 → 2.5.4

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: 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