researchable_loggable 1.3.0 → 1.4.0

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: d31e14c3436ecf2f814d53dcd9eba0a1a5a8686cdf9d293473c46c8dab7fea85
4
- data.tar.gz: 3ae484c57e691a6e9e2f95fd57cf50b83a21376cdceb58d7e99d3847e3b7f78f
3
+ metadata.gz: 4b80bc8fef9e875582f653226ef7bcc8f2bf01c44b7befba142694842800026f
4
+ data.tar.gz: 55cd5ef8ca78c68dd4e25ebc1cd7e68627f1871d4a2d0f646267a41ab8cab623
5
5
  SHA512:
6
- metadata.gz: 2154157435a80a51f35f7adcd027f19350fde893d32be03a88bdbfc71929a1e7b96eff437e1c011fff7f6f85f6eac6811445b7dd86edfaed6d5bd5d55700625c
7
- data.tar.gz: f21065f092442df36a47a3b7a52869d8c1cf3e74aad4ae9906f8b51e16786f7e7c5b25b548539ea930c899ef520a52ab13d77c5445d2eb30a3fc112639c4bff3
6
+ metadata.gz: 5f7821133b81bd0e363fea979048ef084e602860f83a558ed1d923b93f17950855dbc041ddc1eb314eeedfae03fdb8ed88319d4ea589439d4f8d5754c6ac86da
7
+ data.tar.gz: 1482b7dd44efb2a1177aabccd50f0f3ffb888e0af4448fc4ce27871ee93daf1648e745572f501a4770e42e7b571cd66c9088e7523d17534133362a2735a04dc9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # [1.4.0](https://gitlab.com/researchable/general/gems/loggable/compare/v1.3.1...v1.4.0) (2024-11-29)
2
+
3
+
4
+ ### Features
5
+
6
+ * add trace and span id ([6e486e0](https://gitlab.com/researchable/general/gems/loggable/commit/6e486e03f7bef1ecf739195d80472f3cf3c2b7f6))
7
+ * replace ecs logging format to logfmt ([19eb571](https://gitlab.com/researchable/general/gems/loggable/commit/19eb571719ed294fed4f94094c091c76470cae53))
8
+
9
+ ## [1.3.1](https://gitlab.com/researchable/general/gems/loggable/compare/v1.3.0...v1.3.1) (2024-11-26)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * accessing method of undefined in lograge custom_option ([fb44b01](https://gitlab.com/researchable/general/gems/loggable/commit/fb44b01c305f4321a560f8824419abc5d1512874))
15
+
1
16
  # [1.3.0](https://gitlab.com/researchable/general/gems/loggable/compare/v1.2.0...v1.3.0) (2024-11-11)
2
17
 
3
18
 
data/Gemfile CHANGED
@@ -11,7 +11,6 @@ gem 'rspec', '~> 3.0'
11
11
 
12
12
  gem 'ruboguide', '~> 1.0'
13
13
 
14
- gem 'ecs-logging', '~> 1.0'
15
14
  gem 'lograge'
16
15
  gem 'logstash-event'
17
16
 
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- researchable_loggable (1.2.0)
5
- ecs-logging (~> 1.0)
4
+ researchable_loggable (1.3.1)
6
5
  lograge
7
6
  logstash-event
8
7
  opentelemetry-exporter-otlp (~> 0.28)
@@ -36,7 +35,6 @@ GEM
36
35
  concurrent-ruby (1.2.0)
37
36
  crass (1.0.6)
38
37
  diff-lcs (1.5.0)
39
- ecs-logging (1.0.0)
40
38
  erubi (1.12.0)
41
39
  google-protobuf (4.27.4-x86_64-linux)
42
40
  bigdecimal
@@ -335,7 +333,6 @@ PLATFORMS
335
333
  x86_64-linux
336
334
 
337
335
  DEPENDENCIES
338
- ecs-logging (~> 1.0)
339
336
  lograge
340
337
  logstash-event
341
338
  opentelemetry-exporter-otlp (~> 0.28)
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+ require 'time'
5
+ require 'active_support/logger_silence'
6
+
7
+ module Loggable
8
+ module Logfmt
9
+ # A structured logger that formats log messages in a key-value style using Logfmt formatting
10
+ # This has been adapted from https://github.com/cyberdelia/logfmt-ruby/
11
+ class Logger < ::Logger
12
+ def initialize(*args, **kwargs)
13
+ super
14
+ @formatter ||= KeyValueFormatter.new
15
+ end
16
+
17
+ # Include the LoggerSilence module to fix the incompatibility with ActiveSupport::LoggerSilence whe
18
+ # Rails.application.config.assets.quiet option is set to true, but do not include the module for the
19
+ # test environment as it causes issues with ActiveSupport::LoggerThreadSafeLevel::IsolatedExecutionState.
20
+ def self.include_logger_silence
21
+ include ActiveSupport::LoggerSilence
22
+ end
23
+
24
+ # Custom formatter class that renders logs as in a key-value style using Logfmt formatting
25
+ class KeyValueFormatter < ::Logger::Formatter
26
+ def call(severity, timestamp, progname, msg)
27
+ %(time=#{datetime(timestamp)} severity=#{severity.ljust(5)}#{progname(progname)} #{message(msg)}\n)
28
+ end
29
+
30
+ private
31
+
32
+ def datetime(time)
33
+ time.utc.iso8601(3)
34
+ end
35
+
36
+ def message(msg)
37
+ return unless msg
38
+
39
+ if msg.respond_to?(:to_hash)
40
+ pairs = msg.to_hash.map { |k, v| format_pair(k, v) }
41
+ pairs.compact.join(' ')
42
+ else
43
+ format_pair('message', msg)
44
+ end
45
+ end
46
+
47
+ def format_pair(key, value)
48
+ return nil if value.nil?
49
+
50
+ # Return a bare key when the value is a `TrueClass`
51
+ return key if value == true
52
+
53
+ "#{key}=#{format_value(value)}"
54
+ end
55
+
56
+ def progname(progname)
57
+ return nil unless progname
58
+
59
+ # Format this pair like any other to ensure quoting, escaping, etc…,
60
+ # But we also need a leading space so we can interpolate the resulting
61
+ # key/value pair into our log line.
62
+ " #{format_pair(' progname', progname)}"
63
+ end
64
+
65
+ def format_value(value)
66
+ if value.is_a?(Float)
67
+ format('%.3f', value)
68
+ elsif value.is_a?(Time)
69
+ datetime(value)
70
+ elsif value.respond_to?(:to_ary)
71
+ format_value(
72
+ "[#{Array(value).map { |v| format_value(v) }.join(', ')}]"
73
+ )
74
+ else
75
+ # Interpolating due to a weird/subtle behaviour possible in #to_s.
76
+ # Namely, it's possible it doesn't actually return a String:
77
+ # https://github.com/ruby/spec/blob/3affe1e54fcd11918a242ad5d4a7ba895ee30c4c/language/string_spec.rb#L130-L141
78
+ value = "#{value}" # rubocop:disable Style/RedundantInterpolation
79
+ value = value.dump if value.match?(/[[:space:]]|[[:cntrl:]]/) # wrap in quotes and escape control characters
80
+ value
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ecs_logging/logger'
3
+ require 'lograge'
4
4
  require 'rails'
5
+ require 'opentelemetry/sdk'
5
6
 
6
7
  module Loggable
7
8
  # Railtie to configure logging before rails starts
@@ -12,13 +13,14 @@ module Loggable
12
13
  config.loggable.current_user_method = :current_user
13
14
 
14
15
  # Initializer runs before initialize_logger (found in Bootstrap) so from the very beginning we are logging using
15
- # the ecs format, even during the initialization process
16
+ # the logfmt format, even during the initialization process
16
17
  # rubocop:disable Metrics/BlockLength
17
18
  initializer :loggable_web, before: :initialize_logger do
18
19
  Rails.application.configure do
19
20
  production_like = Rails.env.production? || config.loggable.production_like
20
21
  if production_like
21
- Rails.logger = ::EcsLogging::Logger.new($stdout)
22
+ Loggable::Logfmt::Logger.include_logger_silence if Rails.application.config.assets.quiet
23
+ Rails.logger = Loggable::Logfmt::Logger.new($stdout)
22
24
  Rails.logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase || 'INFO')
23
25
 
24
26
  Loggable::OpenTelemetryConfig.configure(Rails.application.class.module_parent_name.underscore.dasherize)
@@ -32,20 +34,26 @@ module Loggable
32
34
  if controller.respond_to?(config.loggable.current_user_method)
33
35
  user_id = controller.send(config.loggable.current_user_method).try(:id)
34
36
  end
37
+
35
38
  {
36
- ecs: {
37
- 'source.ip': controller.request.ip,
38
- 'user.id': user_id,
39
- 'http.code': response_code
40
- },
41
- status: response_code
39
+ 'source.ip': controller.request.ip,
40
+ 'user.id': user_id,
41
+ status: response_code,
42
+ span_id: OpenTelemetry::Trace.current_span.context.hex_span_id,
43
+ trace_id: OpenTelemetry::Trace.current_span.context.hex_trace_id
42
44
  }
43
45
  end
44
46
  config.lograge.custom_options = lambda do |event|
47
+ return if event.payload[:params].blank?
48
+
45
49
  exceptions = %w[controller action format id]
46
- { params: event.payload[:params].except(*exceptions) }
50
+ params = event.payload[:params].except(*exceptions)
51
+ # append a suffix to each param
52
+ params.each_with_object({}) do |(key, value), result|
53
+ result["params.#{key}"] = value
54
+ end
47
55
  end
48
- config.lograge.formatter = Loggable::Lograge::Formatter.new if production_like
56
+ config.lograge.formatter = ::Lograge::Formatters::Raw.new
49
57
  end
50
58
  end
51
59
  # rubocop:enable Metrics/BlockLength
@@ -54,7 +62,7 @@ module Loggable
54
62
  Rails.application.configure do
55
63
  if defined?(Delayed::Worker)
56
64
  if Rails.env.production? || config.loggable.production_like
57
- Delayed::Worker.logger = ::EcsLogging::Logger.new($stdout)
65
+ Delayed::Worker.logger = Loggable::Logfmt::Logger.new($stdout)
58
66
  Delayed::Worker.logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase || 'INFO')
59
67
  Loggable::OpenTelemetryConfig.configure("#{Rails.application.class.module_parent_name.underscore.dasherize}
60
68
  -worker")
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Loggable
4
- VERSION = '1.3.0'
4
+ VERSION = '1.4.0'
5
5
  end
@@ -3,8 +3,7 @@
3
3
  require_relative 'loggable/version'
4
4
  require_relative 'loggable/railtie' if defined?(Rails::Railtie)
5
5
  require_relative 'loggable/opentelemetry_config'
6
- require_relative 'loggable/ecs_logging/formatter_monkey_patch'
7
- require_relative 'loggable/lograge/formatter'
6
+ require_relative 'loggable/logfmt/logger'
8
7
 
9
8
  module ResearchableLoggable
10
9
  class Error < StandardError
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: researchable_loggable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Researchable
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-11 00:00:00.000000000 Z
11
+ date: 2024-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: ecs-logging
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: lograge
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -114,20 +100,19 @@ files:
114
100
  - LICENSE.txt
115
101
  - README.md
116
102
  - Rakefile
117
- - lib/loggable/ecs_logging/formatter_monkey_patch.rb
118
- - lib/loggable/lograge/formatter.rb
103
+ - lib/loggable/logfmt/logger.rb
119
104
  - lib/loggable/opentelemetry_config.rb
120
105
  - lib/loggable/railtie.rb
121
106
  - lib/loggable/version.rb
122
107
  - lib/researchable_loggable.rb
123
108
  - sig/loggable.rbs
124
- homepage: https://gitlab.com/researchable/general/gems/loggable/-/blob/v1.3.0/README.md
109
+ homepage: https://gitlab.com/researchable/general/gems/loggable/-/blob/v1.4.0/README.md
125
110
  licenses:
126
111
  - MIT
127
112
  metadata:
128
- homepage_uri: https://gitlab.com/researchable/general/gems/loggable/-/blob/v1.3.0/README.md
113
+ homepage_uri: https://gitlab.com/researchable/general/gems/loggable/-/blob/v1.4.0/README.md
129
114
  source_code_uri: https://gitlab.com/researchable/general/gems/loggable
130
- changelog_uri: https://gitlab.com/researchable/general/gems/loggable/-/blob/v1.3.0/CHANGELOG.md
115
+ changelog_uri: https://gitlab.com/researchable/general/gems/loggable/-/blob/v1.4.0/CHANGELOG.md
131
116
  post_install_message:
132
117
  rdoc_options: []
133
118
  require_paths:
@@ -143,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
128
  - !ruby/object:Gem::Version
144
129
  version: '0'
145
130
  requirements: []
146
- rubygems_version: 3.5.11
131
+ rubygems_version: 3.5.22
147
132
  signing_key:
148
133
  specification_version: 4
149
134
  summary: Researchable's gem to standardize logging on all Rails applications.
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ecs_logging/formatter'
4
-
5
- module Loggable
6
- module EcsLogging
7
- # A monkey patch to the ::EcsLogging::Formatter to customize how messages from lograge are rendered
8
- module FormatterMonkeyPatch
9
- def call(severity, time, progname, msg, **extras)
10
- base = {
11
- '@timestamp': time.utc.iso8601(3),
12
- 'log.level': severity,
13
- message: msg,
14
- 'ecs.version': '1.4.0'
15
- }
16
-
17
- base['log.logger'] = progname if progname
18
-
19
- base.merge!(msg.except(:lograge)) if msg.is_a?(Hash) && msg.key?(:lograge)
20
- base.merge!(extras) if extras
21
-
22
- "#{JSON.fast_generate(base)}\n"
23
- end
24
-
25
- class << self
26
- def apply_patch
27
- const = find_const
28
- mtd = find_method(const)
29
-
30
- # byebug
31
- const.prepend(self) if const && mtd && mtd.arity == -5
32
- end
33
-
34
- private
35
-
36
- def find_const
37
- Kernel.const_get('::EcsLogging::Formatter')
38
- rescue NameError
39
- puts '[WARN] ::EcsLogging::Formatter not found. Patch could not be applied.' # rubocop:disable Rails/Output
40
- end
41
-
42
- def find_method(const)
43
- return unless const
44
-
45
- method_name = :call
46
- const.instance_method(method_name)
47
- rescue NameError
48
- puts "[WARN] '#{method_name}' method not found in '#{const}'. Patch could not be applied." # rubocop:disable Rails/Output
49
- end
50
- end
51
- end
52
- end
53
- end
54
-
55
- Loggable::EcsLogging::FormatterMonkeyPatch.apply_patch
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'lograge'
4
- require 'active_support/core_ext/array'
5
-
6
- module Loggable
7
- module Lograge
8
- # Custom formatter class that renders logs as ruby objects with just the ecs fields generated by the logger, the
9
- # message, and a lograge flag so the ECS logger knows to process this further before rendering
10
- class Formatter < ::Lograge::Formatters::KeyValue
11
- def call(data)
12
- (data[:ecs] || {}).merge(message: super(data), lograge: true)
13
- end
14
-
15
- protected
16
-
17
- def fields_to_display(data)
18
- data.keys.excluding(%i[ecs])
19
- end
20
- end
21
- end
22
- end