logstruct 0.1.8 → 0.1.10
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 +4 -4
- data/CHANGELOG.md +16 -0
- data/lib/log_struct/enums/log_field.rb +1 -1
- data/lib/log_struct/integrations/action_mailer/metadata_collection.rb +0 -6
- data/lib/log_struct/integrations/active_job/log_subscriber.rb +2 -1
- data/lib/log_struct/integrations/active_job.rb +7 -2
- data/lib/log_struct/integrations/host_authorization.rb +0 -1
- data/lib/log_struct/integrations/lograge.rb +6 -1
- data/lib/log_struct/integrations/rack_error_handler/middleware.rb +39 -33
- data/lib/log_struct/integrations/request_context/middleware.rb +28 -0
- data/lib/log_struct/integrations/request_context.rb +27 -0
- data/lib/log_struct/integrations.rb +2 -0
- data/lib/log_struct/log/request.rb +0 -2
- data/lib/log_struct/log/security/blocked_host.rb +0 -2
- data/lib/log_struct/log/security/csrf_violation.rb +0 -2
- data/lib/log_struct/log/security/ip_spoof.rb +0 -2
- data/lib/log_struct/log/security.rb +2 -5
- data/lib/log_struct/semantic_logger/formatter.rb +9 -0
- data/lib/log_struct/semantic_logger/logger.rb +3 -1
- data/lib/log_struct/shared/add_request_fields.rb +0 -1
- data/lib/log_struct/shared/interfaces/request_fields.rb +0 -4
- data/lib/log_struct/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b138e5ba6e0739ee31d032606f4d7508463deeee00b64e3a870d34d4316e7567
|
|
4
|
+
data.tar.gz: f36bc4a9cb5ee2ab42b77a581efd1b28c7c23a75191429ac5b5926023d33a594
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c06589605729de5ac9ea44694e82712d2d175201adab6052b6eff1a2ae2cc8cc6b476ed7200d1fa6bf6a79db6eb280847b4ca34559a501bc327129db4574acfe
|
|
7
|
+
data.tar.gz: 992fc803c47c57367ca906179bf9b356618e42bf840ac6a3de4b7296d90be0db8d513177c57643e1564967624f444d0af00f2582844e4d68825a03f8e911ac37
|
data/CHANGELOG.md
CHANGED
|
@@ -5,8 +5,24 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
## [0.1.10] - 2026-01-23
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **Feature**: `request_id` now appears on all logs during a request, not just the request log
|
|
17
|
+
|
|
18
|
+
## [0.1.9] - 2026-01-23
|
|
19
|
+
|
|
8
20
|
### Changed
|
|
9
21
|
|
|
22
|
+
- **Fix**: ActiveJob integration handles Rails main event reporter subscribers
|
|
23
|
+
- **Fix**: Rack error handler avoids deprecated CSRF exception class on Rails main
|
|
24
|
+
- **CI**: Added Rails main daily integration run and updated Rails test matrix (7.1.6, 7.2.3, 8.0.4, 8.1.2)
|
|
25
|
+
|
|
10
26
|
## [0.1.8] - 2026-01-22
|
|
11
27
|
|
|
12
28
|
- **Fix**: Lograge custom options now appear in request logs
|
|
@@ -54,12 +54,6 @@ module LogStruct
|
|
|
54
54
|
end
|
|
55
55
|
log_data[:tags] = tags if tags.present?
|
|
56
56
|
|
|
57
|
-
# Get request_id from ActionDispatch if available
|
|
58
|
-
if ::ActionDispatch::Request.respond_to?(:current_request_id) &&
|
|
59
|
-
T.unsafe(::ActionDispatch::Request).current_request_id.present?
|
|
60
|
-
log_data[:request_id] = T.unsafe(::ActionDispatch::Request).current_request_id
|
|
61
|
-
end
|
|
62
|
-
|
|
63
57
|
# Get job_id from ActiveJob if available
|
|
64
58
|
if defined?(::ActiveJob::Logging) && ::ActiveJob::Logging.respond_to?(:job_id) &&
|
|
65
59
|
T.unsafe(::ActiveJob::Logging).job_id.present?
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# typed: strict
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require "active_support/log_subscriber"
|
|
4
5
|
require_relative "../../enums/source"
|
|
5
6
|
require_relative "../../enums/event"
|
|
6
7
|
require_relative "../../log/active_job"
|
|
@@ -10,7 +11,7 @@ module LogStruct
|
|
|
10
11
|
module Integrations
|
|
11
12
|
module ActiveJob
|
|
12
13
|
# Structured logging for ActiveJob
|
|
13
|
-
class LogSubscriber < ::
|
|
14
|
+
class LogSubscriber < ::ActiveSupport::LogSubscriber
|
|
14
15
|
extend T::Sig
|
|
15
16
|
|
|
16
17
|
sig { params(event: ::ActiveSupport::Notifications::Event).void }
|
|
@@ -25,8 +25,13 @@ module LogStruct
|
|
|
25
25
|
return nil unless config.integrations.enable_activejob
|
|
26
26
|
|
|
27
27
|
::ActiveSupport.on_load(:active_job) do
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
if ::ActiveJob::LogSubscriber.respond_to?(:detach_from)
|
|
29
|
+
# Detach the default text formatter
|
|
30
|
+
::ActiveJob::LogSubscriber.detach_from :active_job
|
|
31
|
+
elsif ::ActiveSupport.respond_to?(:event_reporter)
|
|
32
|
+
reporter = ::ActiveSupport.event_reporter
|
|
33
|
+
reporter.unsubscribe(::ActiveJob::LogSubscriber) if reporter.respond_to?(:unsubscribe)
|
|
34
|
+
end
|
|
30
35
|
|
|
31
36
|
# Attach our structured formatter
|
|
32
37
|
Integrations::ActiveJob::LogSubscriber.attach_to :active_job
|
|
@@ -63,7 +63,6 @@ module LogStruct
|
|
|
63
63
|
source_ip: request.ip,
|
|
64
64
|
user_agent: request.user_agent,
|
|
65
65
|
referer: request.referer,
|
|
66
|
-
request_id: request.request_id,
|
|
67
66
|
x_forwarded_for: request.x_forwarded_for,
|
|
68
67
|
allowed_hosts: allowed_hosts_array&.empty? ? nil : allowed_hosts_array,
|
|
69
68
|
allow_ip_hosts: allow_ip_hosts_value
|
|
@@ -101,6 +101,12 @@ module LogStruct
|
|
|
101
101
|
headers = event.payload[:headers]
|
|
102
102
|
return if headers.blank?
|
|
103
103
|
|
|
104
|
+
# Rails' ActionDispatch::RequestId middleware stores request_id in headers
|
|
105
|
+
# Only set if not already present in payload (payload takes precedence)
|
|
106
|
+
if options[:request_id].blank? && headers["action_dispatch.request_id"].present?
|
|
107
|
+
options[:request_id] = headers["action_dispatch.request_id"]
|
|
108
|
+
end
|
|
109
|
+
|
|
104
110
|
options[:user_agent] = headers["HTTP_USER_AGENT"]
|
|
105
111
|
options[:referer] = headers["HTTP_REFERER"]
|
|
106
112
|
options[:content_type] = headers["CONTENT_TYPE"]
|
|
@@ -144,7 +150,6 @@ module LogStruct
|
|
|
144
150
|
view: view,
|
|
145
151
|
database: db,
|
|
146
152
|
params: params,
|
|
147
|
-
request_id: normalized_data[:request_id]&.to_s,
|
|
148
153
|
source_ip: normalized_data[:source_ip]&.to_s,
|
|
149
154
|
user_agent: normalized_data[:user_agent]&.to_s,
|
|
150
155
|
referer: normalized_data[:referer]&.to_s,
|
|
@@ -71,7 +71,6 @@ module LogStruct
|
|
|
71
71
|
http_method: env["REQUEST_METHOD"],
|
|
72
72
|
user_agent: env["HTTP_USER_AGENT"],
|
|
73
73
|
referer: env["HTTP_REFERER"],
|
|
74
|
-
request_id: request.request_id,
|
|
75
74
|
message: ip_spoof_error.message,
|
|
76
75
|
client_ip: env["HTTP_CLIENT_IP"],
|
|
77
76
|
x_forwarded_for: env["HTTP_X_FORWARDED_FOR"],
|
|
@@ -81,38 +80,39 @@ module LogStruct
|
|
|
81
80
|
::Rails.logger.warn(security_log)
|
|
82
81
|
|
|
83
82
|
[FORBIDDEN_STATUS, IP_SPOOF_HEADERS.dup, [IP_SPOOF_HTML]]
|
|
84
|
-
rescue ::ActionController::InvalidAuthenticityToken => invalid_auth_token_error
|
|
85
|
-
# Create a security log for CSRF error
|
|
86
|
-
security_log = Log::Security::CSRFViolation.new(
|
|
87
|
-
path: request.path,
|
|
88
|
-
http_method: request.method,
|
|
89
|
-
source_ip: request.remote_ip,
|
|
90
|
-
user_agent: request.user_agent,
|
|
91
|
-
referer: request.referer,
|
|
92
|
-
request_id: request.request_id,
|
|
93
|
-
message: invalid_auth_token_error.message,
|
|
94
|
-
timestamp: Time.now
|
|
95
|
-
)
|
|
96
|
-
LogStruct.error(security_log)
|
|
97
|
-
|
|
98
|
-
# Report to error reporting service and/or re-raise
|
|
99
|
-
context = extract_request_context(env, request)
|
|
100
|
-
LogStruct.handle_exception(invalid_auth_token_error, source: Source::Security, context: context)
|
|
101
|
-
|
|
102
|
-
# If handle_exception raised an exception then Rails will deal with it (e.g. config.exceptions_app)
|
|
103
|
-
# If we are only logging or reporting these security errors, then return a default response
|
|
104
|
-
[FORBIDDEN_STATUS, CSRF_HEADERS.dup, [CSRF_HTML]]
|
|
105
83
|
rescue => error
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
84
|
+
if csrf_error?(error)
|
|
85
|
+
# Create a security log for CSRF error
|
|
86
|
+
security_log = Log::Security::CSRFViolation.new(
|
|
87
|
+
path: request.path,
|
|
88
|
+
http_method: request.method,
|
|
89
|
+
source_ip: request.remote_ip,
|
|
90
|
+
user_agent: request.user_agent,
|
|
91
|
+
referer: request.referer,
|
|
92
|
+
message: error.message,
|
|
93
|
+
timestamp: Time.now
|
|
94
|
+
)
|
|
95
|
+
LogStruct.error(security_log)
|
|
96
|
+
|
|
97
|
+
# Report to error reporting service and/or re-raise
|
|
98
|
+
context = extract_request_context(env, request)
|
|
99
|
+
LogStruct.handle_exception(error, source: Source::Security, context: context)
|
|
100
|
+
|
|
101
|
+
# If handle_exception raised an exception then Rails will deal with it (e.g. config.exceptions_app)
|
|
102
|
+
# If we are only logging or reporting these security errors, then return a default response
|
|
103
|
+
[FORBIDDEN_STATUS, CSRF_HEADERS.dup, [CSRF_HTML]]
|
|
104
|
+
else
|
|
105
|
+
# Extract request context for error reporting
|
|
106
|
+
context = extract_request_context(env, request)
|
|
107
|
+
|
|
108
|
+
# Create and log a structured exception with request context
|
|
109
|
+
exception_log = Log.from_exception(Source::Rails, error, context)
|
|
110
|
+
LogStruct.error(exception_log)
|
|
111
|
+
|
|
112
|
+
# Re-raise any standard errors to let Rails or error reporter handle it.
|
|
113
|
+
# Rails will also log the request details separately
|
|
114
|
+
raise error
|
|
115
|
+
end
|
|
116
116
|
end
|
|
117
117
|
end
|
|
118
118
|
|
|
@@ -135,7 +135,6 @@ module LogStruct
|
|
|
135
135
|
def extract_request_context(env, request = nil)
|
|
136
136
|
request ||= ::ActionDispatch::Request.new(env)
|
|
137
137
|
{
|
|
138
|
-
request_id: request.request_id,
|
|
139
138
|
path: request.path,
|
|
140
139
|
method: request.method,
|
|
141
140
|
user_agent: request.user_agent,
|
|
@@ -146,6 +145,13 @@ module LogStruct
|
|
|
146
145
|
{error_extracting_context: error.message}
|
|
147
146
|
end
|
|
148
147
|
|
|
148
|
+
sig { params(error: StandardError).returns(T::Boolean) }
|
|
149
|
+
def csrf_error?(error)
|
|
150
|
+
error_name = error.class.name
|
|
151
|
+
error_name == "ActionController::InvalidAuthenticityToken" ||
|
|
152
|
+
error_name == "ActionController::InvalidCrossOriginRequest"
|
|
153
|
+
end
|
|
154
|
+
|
|
149
155
|
sig { params(configured_proxies: T.untyped).returns(T.untyped) }
|
|
150
156
|
def normalized_trusted_proxies(configured_proxies)
|
|
151
157
|
if configured_proxies.nil? || (configured_proxies.respond_to?(:empty?) && configured_proxies.empty?)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module LogStruct
|
|
5
|
+
module Integrations
|
|
6
|
+
module RequestContext
|
|
7
|
+
# Middleware that captures request_id and stores it in SemanticLogger's
|
|
8
|
+
# named_tags so all logs during the request include the request_id.
|
|
9
|
+
class Middleware
|
|
10
|
+
extend T::Sig
|
|
11
|
+
|
|
12
|
+
sig { params(app: T.untyped).void }
|
|
13
|
+
def initialize(app)
|
|
14
|
+
@app = app
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
sig { params(env: T.untyped).returns(T.untyped) }
|
|
18
|
+
def call(env)
|
|
19
|
+
request = ::ActionDispatch::Request.new(env)
|
|
20
|
+
::SemanticLogger.push_named_tags(request_id: request.request_id)
|
|
21
|
+
@app.call(env)
|
|
22
|
+
ensure
|
|
23
|
+
::SemanticLogger.pop_named_tags
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative "request_context/middleware"
|
|
5
|
+
|
|
6
|
+
module LogStruct
|
|
7
|
+
module Integrations
|
|
8
|
+
# Request context integration that captures request_id for all logs
|
|
9
|
+
module RequestContext
|
|
10
|
+
extend T::Sig
|
|
11
|
+
extend IntegrationInterface
|
|
12
|
+
|
|
13
|
+
sig { override.params(config: LogStruct::Configuration).returns(T.nilable(T::Boolean)) }
|
|
14
|
+
def self.setup(config)
|
|
15
|
+
return nil unless config.enabled
|
|
16
|
+
|
|
17
|
+
# Insert after RequestId middleware so request_id is available
|
|
18
|
+
::Rails.application.middleware.insert_after(
|
|
19
|
+
::ActionDispatch::RequestId,
|
|
20
|
+
Integrations::RequestContext::Middleware
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require_relative "integrations/integration_interface"
|
|
5
|
+
require_relative "integrations/request_context"
|
|
5
6
|
require_relative "integrations/active_job"
|
|
6
7
|
require_relative "integrations/active_record"
|
|
7
8
|
require_relative "integrations/rack_error_handler"
|
|
@@ -77,6 +78,7 @@ module LogStruct
|
|
|
77
78
|
|
|
78
79
|
sig { params(config: LogStruct::Configuration).void }
|
|
79
80
|
def self.setup_middleware_integrations(config)
|
|
81
|
+
Integrations::RequestContext.setup(config)
|
|
80
82
|
Integrations::HostAuthorization.setup(config) if config.integrations.enable_host_authorization
|
|
81
83
|
Integrations::RackErrorHandler.setup(config) if config.integrations.enable_rack_error_handler
|
|
82
84
|
end
|
|
@@ -33,7 +33,6 @@ module LogStruct
|
|
|
33
33
|
const :source_ip, T.nilable(String), default: nil
|
|
34
34
|
const :user_agent, T.nilable(String), default: nil
|
|
35
35
|
const :referer, T.nilable(String), default: nil
|
|
36
|
-
const :request_id, T.nilable(String), default: nil
|
|
37
36
|
|
|
38
37
|
# Event-specific fields
|
|
39
38
|
const :format, T.nilable(Symbol), default: nil
|
|
@@ -69,7 +68,6 @@ module LogStruct
|
|
|
69
68
|
h[LogField::SourceIp] = source_ip unless source_ip.nil?
|
|
70
69
|
h[LogField::UserAgent] = user_agent unless user_agent.nil?
|
|
71
70
|
h[LogField::Referer] = referer unless referer.nil?
|
|
72
|
-
h[LogField::RequestId] = request_id unless request_id.nil?
|
|
73
71
|
h[LogField::Format] = format unless format.nil?
|
|
74
72
|
h[LogField::Controller] = controller unless controller.nil?
|
|
75
73
|
h[LogField::Action] = action unless action.nil?
|
|
@@ -34,7 +34,6 @@ module LogStruct
|
|
|
34
34
|
const :source_ip, T.nilable(String), default: nil
|
|
35
35
|
const :user_agent, T.nilable(String), default: nil
|
|
36
36
|
const :referer, T.nilable(String), default: nil
|
|
37
|
-
const :request_id, T.nilable(String), default: nil
|
|
38
37
|
|
|
39
38
|
# Event-specific fields
|
|
40
39
|
const :message, T.nilable(String), default: nil
|
|
@@ -65,7 +64,6 @@ module LogStruct
|
|
|
65
64
|
h[LogField::SourceIp] = source_ip unless source_ip.nil?
|
|
66
65
|
h[LogField::UserAgent] = user_agent unless user_agent.nil?
|
|
67
66
|
h[LogField::Referer] = referer unless referer.nil?
|
|
68
|
-
h[LogField::RequestId] = request_id unless request_id.nil?
|
|
69
67
|
h[LogField::Message] = message unless message.nil?
|
|
70
68
|
h[LogField::BlockedHost] = blocked_host unless blocked_host.nil?
|
|
71
69
|
h[LogField::BlockedHosts] = blocked_hosts unless blocked_hosts.nil?
|
|
@@ -34,7 +34,6 @@ module LogStruct
|
|
|
34
34
|
const :source_ip, T.nilable(String), default: nil
|
|
35
35
|
const :user_agent, T.nilable(String), default: nil
|
|
36
36
|
const :referer, T.nilable(String), default: nil
|
|
37
|
-
const :request_id, T.nilable(String), default: nil
|
|
38
37
|
|
|
39
38
|
# Event-specific fields
|
|
40
39
|
const :message, T.nilable(String), default: nil
|
|
@@ -60,7 +59,6 @@ module LogStruct
|
|
|
60
59
|
h[LogField::SourceIp] = source_ip unless source_ip.nil?
|
|
61
60
|
h[LogField::UserAgent] = user_agent unless user_agent.nil?
|
|
62
61
|
h[LogField::Referer] = referer unless referer.nil?
|
|
63
|
-
h[LogField::RequestId] = request_id unless request_id.nil?
|
|
64
62
|
h[LogField::Message] = message unless message.nil?
|
|
65
63
|
h
|
|
66
64
|
end
|
|
@@ -34,7 +34,6 @@ module LogStruct
|
|
|
34
34
|
const :source_ip, T.nilable(String), default: nil
|
|
35
35
|
const :user_agent, T.nilable(String), default: nil
|
|
36
36
|
const :referer, T.nilable(String), default: nil
|
|
37
|
-
const :request_id, T.nilable(String), default: nil
|
|
38
37
|
|
|
39
38
|
# Event-specific fields
|
|
40
39
|
const :message, T.nilable(String), default: nil
|
|
@@ -62,7 +61,6 @@ module LogStruct
|
|
|
62
61
|
h[LogField::SourceIp] = source_ip unless source_ip.nil?
|
|
63
62
|
h[LogField::UserAgent] = user_agent unless user_agent.nil?
|
|
64
63
|
h[LogField::Referer] = referer unless referer.nil?
|
|
65
|
-
h[LogField::RequestId] = request_id unless request_id.nil?
|
|
66
64
|
h[LogField::Message] = message unless message.nil?
|
|
67
65
|
h[LogField::ClientIp] = client_ip unless client_ip.nil?
|
|
68
66
|
h[LogField::XForwardedFor] = x_forwarded_for unless x_forwarded_for.nil?
|
|
@@ -20,7 +20,6 @@ module LogStruct
|
|
|
20
20
|
const :source_ip, T.nilable(String), default: nil
|
|
21
21
|
const :user_agent, T.nilable(String), default: nil
|
|
22
22
|
const :referer, T.nilable(String), default: nil
|
|
23
|
-
const :request_id, T.nilable(String), default: nil
|
|
24
23
|
|
|
25
24
|
Kwargs = T.type_alias do
|
|
26
25
|
{
|
|
@@ -28,8 +27,7 @@ module LogStruct
|
|
|
28
27
|
http_method: T.nilable(String),
|
|
29
28
|
source_ip: T.nilable(String),
|
|
30
29
|
user_agent: T.nilable(String),
|
|
31
|
-
referer: T.nilable(String)
|
|
32
|
-
request_id: T.nilable(String)
|
|
30
|
+
referer: T.nilable(String)
|
|
33
31
|
}
|
|
34
32
|
end
|
|
35
33
|
|
|
@@ -40,8 +38,7 @@ module LogStruct
|
|
|
40
38
|
http_method: http_method,
|
|
41
39
|
source_ip: source_ip,
|
|
42
40
|
user_agent: user_agent,
|
|
43
|
-
referer: referer
|
|
44
|
-
request_id: request_id
|
|
41
|
+
referer: referer
|
|
45
42
|
}
|
|
46
43
|
end
|
|
47
44
|
end
|
|
@@ -79,6 +79,15 @@ module LogStruct
|
|
|
79
79
|
)
|
|
80
80
|
@logstruct_formatter.call(log.level, log.time, log.name, plain_log)
|
|
81
81
|
end
|
|
82
|
+
|
|
83
|
+
# Add request_id from named_tags if present
|
|
84
|
+
request_id = log.named_tags[:request_id]
|
|
85
|
+
if request_id
|
|
86
|
+
data = JSON.parse(json)
|
|
87
|
+
data["req_id"] = request_id
|
|
88
|
+
json = data.to_json
|
|
89
|
+
end
|
|
90
|
+
|
|
82
91
|
# SemanticLogger appenders typically add their own newline. Avoid double newlines by stripping ours.
|
|
83
92
|
json.end_with?("\n") ? json.chomp : json
|
|
84
93
|
end
|
|
@@ -148,7 +148,9 @@ module LogStruct
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
# Proxy object to provide ActiveJob-compatible formatter interface
|
|
151
|
-
|
|
151
|
+
# Also implements the standard Logger formatter interface (call method)
|
|
152
|
+
# for compatibility with Ruby's Logger (especially logger gem 1.7.0+)
|
|
153
|
+
class FormatterProxy < ::Logger::Formatter
|
|
152
154
|
extend T::Sig
|
|
153
155
|
|
|
154
156
|
sig { returns(T::Array[T.any(String, Symbol)]) }
|
|
@@ -20,7 +20,6 @@ module LogStruct
|
|
|
20
20
|
hash[LogField::SourceIp.serialize] = source_ip if source_ip
|
|
21
21
|
hash[LogField::UserAgent.serialize] = user_agent if user_agent
|
|
22
22
|
hash[LogField::Referer.serialize] = referer if referer
|
|
23
|
-
hash[LogField::RequestId.serialize] = request_id if request_id
|
|
24
23
|
end
|
|
25
24
|
end
|
|
26
25
|
end
|
data/lib/log_struct/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logstruct
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- DocSpring
|
|
@@ -281,6 +281,8 @@ files:
|
|
|
281
281
|
- lib/log_struct/integrations/rack.rb
|
|
282
282
|
- lib/log_struct/integrations/rack_error_handler.rb
|
|
283
283
|
- lib/log_struct/integrations/rack_error_handler/middleware.rb
|
|
284
|
+
- lib/log_struct/integrations/request_context.rb
|
|
285
|
+
- lib/log_struct/integrations/request_context/middleware.rb
|
|
284
286
|
- lib/log_struct/integrations/shrine.rb
|
|
285
287
|
- lib/log_struct/integrations/sidekiq.rb
|
|
286
288
|
- lib/log_struct/integrations/sidekiq/logger.rb
|