logstruct 0.1.9 → 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 +6 -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/host_authorization.rb +0 -1
- data/lib/log_struct/integrations/lograge.rb +6 -1
- data/lib/log_struct/integrations/rack_error_handler/middleware.rb +0 -3
- 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
|
@@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Changed
|
|
11
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
|
+
|
|
12
18
|
## [0.1.9] - 2026-01-23
|
|
13
19
|
|
|
14
20
|
### Changed
|
|
@@ -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?
|
|
@@ -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"],
|
|
@@ -90,7 +89,6 @@ module LogStruct
|
|
|
90
89
|
source_ip: request.remote_ip,
|
|
91
90
|
user_agent: request.user_agent,
|
|
92
91
|
referer: request.referer,
|
|
93
|
-
request_id: request.request_id,
|
|
94
92
|
message: error.message,
|
|
95
93
|
timestamp: Time.now
|
|
96
94
|
)
|
|
@@ -137,7 +135,6 @@ module LogStruct
|
|
|
137
135
|
def extract_request_context(env, request = nil)
|
|
138
136
|
request ||= ::ActionDispatch::Request.new(env)
|
|
139
137
|
{
|
|
140
|
-
request_id: request.request_id,
|
|
141
138
|
path: request.path,
|
|
142
139
|
method: request.method,
|
|
143
140
|
user_agent: request.user_agent,
|
|
@@ -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
|