activesupport-json_logging 1.1.0 → 1.2.0
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 +7 -0
- data/README.md +97 -2
- data/lib/json_logging/formatter_with_tags.rb +38 -8
- data/lib/json_logging/json_logger_extension.rb +29 -9
- data/lib/json_logging/version.rb +1 -1
- metadata +43 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c99bef73cc6bf2627075656ee38a3e3b756ac61ef54f2edcc628814b317ac7bf
|
|
4
|
+
data.tar.gz: c4a0e1ecfd0ae8862db0167cc5507b8da4572e6a58ed4035ec7aa606c3154442
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3abb724226828b28519f25dc8edb138c3b4d7dc1a07bf2946b952e46bee4bef5d71149a44df4a52cb12e41f892ca4d2f7147bfdeb9dbd7ad0ca3c4ee3873dddc
|
|
7
|
+
data.tar.gz: 25b2c9f5ae0c8107e4f5c7385ff96fbb379cbfba851234be9800909978b14d1d81b5fab961a5d72bd1d4ede78c5d1d16eb5ab1534e6ed54d2074e1c21456395c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.2.0 (2025-11-07)
|
|
4
|
+
|
|
5
|
+
- Add support for service-specific tagged loggers: create loggers with permanent tags using `logger.tagged("service")` without a block
|
|
6
|
+
- Improve BroadcastLogger compatibility: service-specific loggers work seamlessly with `ActiveSupport::BroadcastLogger`
|
|
7
|
+
- Fix LocalTagStorage implementation to match Rails' TaggedLogging behavior: use `tag_stack` attribute accessor pattern for proper tag isolation
|
|
8
|
+
- Add comprehensive examples in README for service-specific loggers and BroadcastLogger integration
|
|
9
|
+
|
|
3
10
|
## 1.1.0 (2025-11-04)
|
|
4
11
|
|
|
5
12
|
- Move tags to root level of JSON payload instead of nested in context (breaking change: tags now at `payload["tags"]` instead of `payload["context"]["tags"]`)
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# activesupport-json_logging
|
|
2
2
|
|
|
3
|
-
[](https://badge.fury.io/rb/activesupport-json_logging) [](https://badge.fury.io/rb/activesupport-json_logging) [](https://github.com/amkisko/activesupport-json_logging.rb/actions/workflows/test.yml) [](https://codecov.io/gh/amkisko/activesupport-json_logging.rb)
|
|
4
4
|
|
|
5
5
|
Structured JSON logging for Rails and ActiveSupport with a safe, single-line formatter.
|
|
6
6
|
No dependencies beyond Rails and Activesupport.
|
|
@@ -8,6 +8,10 @@ Supports Rails versions from 6 to 8.
|
|
|
8
8
|
|
|
9
9
|
Sponsored by [Kisko Labs](https://www.kiskolabs.com).
|
|
10
10
|
|
|
11
|
+
<a href="https://www.kiskolabs.com">
|
|
12
|
+
<img src="kisko.svg" width="200" alt="Sponsored by Kisko Labs" />
|
|
13
|
+
</a>
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
## Installation
|
|
13
17
|
|
|
@@ -40,6 +44,8 @@ end
|
|
|
40
44
|
- `JsonLogging.with_context` to attach contextual fields per-thread
|
|
41
45
|
- Smart message parsing (handles hashes, JSON strings, plain strings, and Exception objects)
|
|
42
46
|
- Native `tagged` method support - use it just like Rails' tagged logger
|
|
47
|
+
- Service-specific tagged loggers - create loggers with permanent tags using `logger.tagged("service")` without a block
|
|
48
|
+
- Full compatibility with `ActiveSupport::BroadcastLogger` (Rails 7.1+)
|
|
43
49
|
- Automatic Rails integration via Railtie (auto-requires the gem in Rails apps)
|
|
44
50
|
|
|
45
51
|
## Basic usage
|
|
@@ -63,6 +69,17 @@ logger.tagged("BCX").info("Stuff")
|
|
|
63
69
|
logger.tagged("BCX", "Jason").info("Stuff")
|
|
64
70
|
logger.tagged("BCX").tagged("Jason").info("Stuff")
|
|
65
71
|
|
|
72
|
+
# Create a service-specific logger with permanent tags
|
|
73
|
+
# All logs from this logger will include the "dotenv" tag
|
|
74
|
+
dotenv_logger = logger.tagged("dotenv")
|
|
75
|
+
dotenv_logger.info("Loading environment variables") # Includes "dotenv" tag
|
|
76
|
+
dotenv_logger.warn("Missing .env file") # Includes "dotenv" tag
|
|
77
|
+
|
|
78
|
+
# You can also create service loggers directly
|
|
79
|
+
base_logger = JsonLogging.logger($stdout)
|
|
80
|
+
service_logger = base_logger.tagged("my-service")
|
|
81
|
+
service_logger.info("Service started") # All logs tagged with "my-service"
|
|
82
|
+
|
|
66
83
|
# Add context
|
|
67
84
|
JsonLogging.with_context(user_id: 123) do
|
|
68
85
|
logger.warn({event: "slow_query", duration_ms: 250})
|
|
@@ -85,6 +102,84 @@ This gem does **not** automatically configure your Rails app. You set it up manu
|
|
|
85
102
|
- In Rails 7.1+, Rails automatically wraps your logger in `ActiveSupport::BroadcastLogger` to enable writing to multiple destinations (e.g., STDOUT and file simultaneously). This works seamlessly with our logger - your JSON logger will be wrapped and all method calls will delegate correctly. No special handling needed.
|
|
86
103
|
- In Rails 7.1+, tag storage uses `ActiveSupport::IsolatedExecutionState` for improved thread/Fiber safety.
|
|
87
104
|
|
|
105
|
+
### Service-specific loggers with tags
|
|
106
|
+
|
|
107
|
+
You can create loggers with permanent tags for specific services or components. This is useful when you want all logs from a particular service to be tagged consistently:
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
# Create a logger for DotEnv service with "dotenv" tag
|
|
111
|
+
base_logger = JsonLogging.logger($stdout)
|
|
112
|
+
dotenv_logger = base_logger.tagged("dotenv")
|
|
113
|
+
|
|
114
|
+
# All logs from this logger will include the "dotenv" tag
|
|
115
|
+
dotenv_logger.info("Loading .env file")
|
|
116
|
+
dotenv_logger.warn("Missing .env.local file")
|
|
117
|
+
dotenv_logger.error("Invalid environment variable format")
|
|
118
|
+
|
|
119
|
+
# Example: Configure Dotenv::Rails to use tagged logger
|
|
120
|
+
if defined?(Dotenv::Rails)
|
|
121
|
+
Dotenv::Rails.logger = base_logger.tagged("dotenv")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Example: Create multiple service loggers
|
|
125
|
+
redis_logger = base_logger.tagged("redis")
|
|
126
|
+
sidekiq_logger = base_logger.tagged("sidekiq")
|
|
127
|
+
api_logger = base_logger.tagged("api")
|
|
128
|
+
|
|
129
|
+
# Each service logger maintains its tag across all log calls
|
|
130
|
+
redis_logger.info("Connected to Redis") # Tagged with "redis"
|
|
131
|
+
sidekiq_logger.info("Job enqueued") # Tagged with "sidekiq"
|
|
132
|
+
api_logger.info("Request received") # Tagged with "api"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### BroadcastLogger integration
|
|
136
|
+
|
|
137
|
+
`ActiveSupport::BroadcastLogger` (Rails 7.1+) allows writing logs to multiple destinations simultaneously. `JsonLogging` works seamlessly with `BroadcastLogger`:
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
# Create JSON loggers for different destinations
|
|
141
|
+
stdout_logger = JsonLogging.logger($stdout)
|
|
142
|
+
file_logger = JsonLogging.logger(Rails.root.join("log", "production.log"))
|
|
143
|
+
|
|
144
|
+
# Wrap in BroadcastLogger to write to both destinations
|
|
145
|
+
broadcast_logger = ActiveSupport::BroadcastLogger.new(stdout_logger)
|
|
146
|
+
broadcast_logger.broadcast_to(file_logger)
|
|
147
|
+
|
|
148
|
+
# All logging methods work through BroadcastLogger
|
|
149
|
+
broadcast_logger.info("This goes to both STDOUT and file")
|
|
150
|
+
broadcast_logger.warn({event: "warning", message: "Something happened"})
|
|
151
|
+
|
|
152
|
+
# Tagged logging works through BroadcastLogger
|
|
153
|
+
broadcast_logger.tagged("REQUEST", request_id) do
|
|
154
|
+
broadcast_logger.info("Processing request") # Tagged logs go to both destinations
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Service-specific loggers work with BroadcastLogger
|
|
158
|
+
# Note: Create service logger from underlying logger, then wrap in BroadcastLogger
|
|
159
|
+
# (BroadcastLogger.tagged without block returns array due to delegation)
|
|
160
|
+
base_logger = JsonLogging.logger($stdout)
|
|
161
|
+
dotenv_logger = base_logger.tagged("dotenv")
|
|
162
|
+
dotenv_broadcast = ActiveSupport::BroadcastLogger.new(dotenv_logger)
|
|
163
|
+
dotenv_broadcast.broadcast_to(file_logger.tagged("dotenv")) # Tag second destination too
|
|
164
|
+
dotenv_broadcast.info("Environment loaded") # Tagged and broadcast to all destinations
|
|
165
|
+
|
|
166
|
+
# Rails 7.1+ automatically uses BroadcastLogger
|
|
167
|
+
# Your configuration can be simplified:
|
|
168
|
+
Rails.application.configure do
|
|
169
|
+
# Rails will automatically wrap this in BroadcastLogger
|
|
170
|
+
base_logger = ActiveSupport::Logger.new($stdout)
|
|
171
|
+
json_logger = JsonLogging.new(base_logger)
|
|
172
|
+
config.logger = json_logger # Rails wraps this in BroadcastLogger automatically
|
|
173
|
+
end
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Key points:**
|
|
177
|
+
- All logger methods (`info`, `warn`, `error`, etc.) work through `BroadcastLogger`
|
|
178
|
+
- Tagged logging (`tagged`) works correctly through `BroadcastLogger`
|
|
179
|
+
- Service-specific tagged loggers work with `BroadcastLogger`
|
|
180
|
+
- Each destination receives properly formatted JSON logs
|
|
181
|
+
- No special configuration needed - just wrap your `JsonLogging` logger in `BroadcastLogger`
|
|
182
|
+
|
|
88
183
|
### Basic setup
|
|
89
184
|
|
|
90
185
|
Create `config/initializers/json_logging.rb`:
|
|
@@ -502,7 +597,7 @@ The gem will automatically filter these from all log entries, including context
|
|
|
502
597
|
```bash
|
|
503
598
|
# Install dependencies
|
|
504
599
|
bundle install
|
|
505
|
-
bundle exec appraisal
|
|
600
|
+
bundle exec appraisal generate
|
|
506
601
|
|
|
507
602
|
# Run tests for current Rails version
|
|
508
603
|
bundle exec rspec
|
|
@@ -8,7 +8,13 @@ module JsonLogging
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def current_tags
|
|
11
|
-
|
|
11
|
+
# If LocalTagStorage is extended on this formatter, use its tag_stack
|
|
12
|
+
# This matches Rails' TaggedLogging behavior where tag_stack attribute shadows the method
|
|
13
|
+
if respond_to?(:tag_stack, true) && instance_variable_defined?(:@tag_stack)
|
|
14
|
+
tag_stack.tags
|
|
15
|
+
else
|
|
16
|
+
@logger.send(:current_tags)
|
|
17
|
+
end
|
|
12
18
|
end
|
|
13
19
|
|
|
14
20
|
def call(severity, timestamp, progname, msg)
|
|
@@ -22,18 +28,42 @@ module JsonLogging
|
|
|
22
28
|
build_fallback_output(severity, timestamp, msg, e)
|
|
23
29
|
end
|
|
24
30
|
|
|
31
|
+
def push_tags(*tags)
|
|
32
|
+
# If LocalTagStorage is present, use it; otherwise use logger's thread-local storage
|
|
33
|
+
if respond_to?(:tag_stack, true) && instance_variable_defined?(:@tag_stack)
|
|
34
|
+
tag_stack.push_tags(tags)
|
|
35
|
+
else
|
|
36
|
+
@logger.send(:push_tags, tags)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
25
40
|
# Support tagged blocks for formatter
|
|
26
41
|
def tagged(*tags)
|
|
27
42
|
if block_given?
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
43
|
+
# If LocalTagStorage is present, use it; otherwise use logger's thread-local storage
|
|
44
|
+
if respond_to?(:tag_stack, true) && instance_variable_defined?(:@tag_stack)
|
|
45
|
+
previous_count = tag_stack.tags.size
|
|
46
|
+
tag_stack.push_tags(tags)
|
|
47
|
+
begin
|
|
48
|
+
yield @logger
|
|
49
|
+
ensure
|
|
50
|
+
tag_stack.pop_tags(tag_stack.tags.size - previous_count)
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
previous = @logger.send(:current_tags).dup
|
|
54
|
+
@logger.send(:push_tags, tags)
|
|
55
|
+
begin
|
|
56
|
+
yield @logger
|
|
57
|
+
ensure
|
|
58
|
+
@logger.send(:set_tags, previous)
|
|
59
|
+
end
|
|
34
60
|
end
|
|
35
61
|
else
|
|
36
|
-
|
|
62
|
+
if respond_to?(:tag_stack, true) && instance_variable_defined?(:@tag_stack)
|
|
63
|
+
tag_stack.push_tags(tags)
|
|
64
|
+
else
|
|
65
|
+
@logger.send(:push_tags, tags)
|
|
66
|
+
end
|
|
37
67
|
self
|
|
38
68
|
end
|
|
39
69
|
end
|
|
@@ -75,7 +75,9 @@ module JsonLogging
|
|
|
75
75
|
# Return a new wrapped logger with tags applied (similar to TaggedLogging)
|
|
76
76
|
logger = JsonLogging.new(self)
|
|
77
77
|
# Extend formatter with LocalTagStorage to preserve current tags when creating nested loggers
|
|
78
|
+
# This matches Rails' TaggedLogging behavior
|
|
78
79
|
logger.formatter.extend(LocalTagStorage)
|
|
80
|
+
# Push tags through formatter (matches Rails delegation pattern)
|
|
79
81
|
logger.formatter.push_tags(*formatter.current_tags, *tags)
|
|
80
82
|
logger
|
|
81
83
|
end
|
|
@@ -132,7 +134,7 @@ module JsonLogging
|
|
|
132
134
|
payload = PayloadBuilder.merge_context(
|
|
133
135
|
payload,
|
|
134
136
|
additional_context: JsonLogging.additional_context.compact,
|
|
135
|
-
tags: current_tags
|
|
137
|
+
tags: formatter.current_tags
|
|
136
138
|
)
|
|
137
139
|
|
|
138
140
|
payload.compact
|
|
@@ -159,19 +161,37 @@ module JsonLogging
|
|
|
159
161
|
# Module for preserving current tags when creating nested tagged loggers
|
|
160
162
|
# Similar to ActiveSupport::TaggedLogging::LocalTagStorage
|
|
161
163
|
# When extended on a formatter, stores tags locally instead of using thread-local storage
|
|
164
|
+
# Uses tag_stack attribute accessor pattern to match Rails' TaggedLogging behavior
|
|
162
165
|
module LocalTagStorage
|
|
166
|
+
attr_accessor :tag_stack
|
|
167
|
+
|
|
163
168
|
def self.extended(base)
|
|
164
|
-
base.
|
|
169
|
+
base.tag_stack = LocalTagStack.new
|
|
165
170
|
end
|
|
166
171
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
end
|
|
172
|
+
# Simple tag stack implementation for local tag storage
|
|
173
|
+
# Similar to ActiveSupport::TaggedLogging::TagStack but simplified for JSON logging
|
|
174
|
+
class LocalTagStack
|
|
175
|
+
attr_reader :tags
|
|
172
176
|
|
|
173
|
-
|
|
174
|
-
|
|
177
|
+
def initialize
|
|
178
|
+
@tags = []
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def push_tags(tags)
|
|
182
|
+
flat = Array(tags).flatten.compact.map(&:to_s).reject(&:empty?)
|
|
183
|
+
return [] if flat.empty?
|
|
184
|
+
@tags.concat(flat)
|
|
185
|
+
flat
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def pop_tags(count = 1)
|
|
189
|
+
@tags.pop(count)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def clear
|
|
193
|
+
@tags.clear
|
|
194
|
+
end
|
|
175
195
|
end
|
|
176
196
|
end
|
|
177
197
|
end
|
data/lib/json_logging/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activesupport-json_logging
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Andrei Makarov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-11-
|
|
11
|
+
date: 2025-11-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -56,42 +56,56 @@ dependencies:
|
|
|
56
56
|
requirements:
|
|
57
57
|
- - "~>"
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
|
-
version: '3
|
|
59
|
+
version: '3'
|
|
60
|
+
type: :development
|
|
61
|
+
prerelease: false
|
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - "~>"
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '3'
|
|
67
|
+
- !ruby/object:Gem::Dependency
|
|
68
|
+
name: webmock
|
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '3'
|
|
60
74
|
type: :development
|
|
61
75
|
prerelease: false
|
|
62
76
|
version_requirements: !ruby/object:Gem::Requirement
|
|
63
77
|
requirements:
|
|
64
78
|
- - "~>"
|
|
65
79
|
- !ruby/object:Gem::Version
|
|
66
|
-
version: '3
|
|
80
|
+
version: '3'
|
|
67
81
|
- !ruby/object:Gem::Dependency
|
|
68
82
|
name: rake
|
|
69
83
|
requirement: !ruby/object:Gem::Requirement
|
|
70
84
|
requirements:
|
|
71
85
|
- - "~>"
|
|
72
86
|
- !ruby/object:Gem::Version
|
|
73
|
-
version: '13
|
|
87
|
+
version: '13'
|
|
74
88
|
type: :development
|
|
75
89
|
prerelease: false
|
|
76
90
|
version_requirements: !ruby/object:Gem::Requirement
|
|
77
91
|
requirements:
|
|
78
92
|
- - "~>"
|
|
79
93
|
- !ruby/object:Gem::Version
|
|
80
|
-
version: '13
|
|
94
|
+
version: '13'
|
|
81
95
|
- !ruby/object:Gem::Dependency
|
|
82
96
|
name: simplecov
|
|
83
97
|
requirement: !ruby/object:Gem::Requirement
|
|
84
98
|
requirements:
|
|
85
99
|
- - "~>"
|
|
86
100
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: '0.
|
|
101
|
+
version: '0.22'
|
|
88
102
|
type: :development
|
|
89
103
|
prerelease: false
|
|
90
104
|
version_requirements: !ruby/object:Gem::Requirement
|
|
91
105
|
requirements:
|
|
92
106
|
- - "~>"
|
|
93
107
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: '0.
|
|
108
|
+
version: '0.22'
|
|
95
109
|
- !ruby/object:Gem::Dependency
|
|
96
110
|
name: rspec_junit_formatter
|
|
97
111
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -126,42 +140,56 @@ dependencies:
|
|
|
126
140
|
requirements:
|
|
127
141
|
- - "~>"
|
|
128
142
|
- !ruby/object:Gem::Version
|
|
129
|
-
version: '1
|
|
143
|
+
version: '1'
|
|
130
144
|
type: :development
|
|
131
145
|
prerelease: false
|
|
132
146
|
version_requirements: !ruby/object:Gem::Requirement
|
|
133
147
|
requirements:
|
|
134
148
|
- - "~>"
|
|
135
149
|
- !ruby/object:Gem::Version
|
|
136
|
-
version: '1
|
|
150
|
+
version: '1'
|
|
137
151
|
- !ruby/object:Gem::Dependency
|
|
138
152
|
name: appraisal
|
|
139
153
|
requirement: !ruby/object:Gem::Requirement
|
|
140
154
|
requirements:
|
|
141
155
|
- - "~>"
|
|
142
156
|
- !ruby/object:Gem::Version
|
|
143
|
-
version: '2
|
|
157
|
+
version: '2'
|
|
144
158
|
type: :development
|
|
145
159
|
prerelease: false
|
|
146
160
|
version_requirements: !ruby/object:Gem::Requirement
|
|
147
161
|
requirements:
|
|
148
162
|
- - "~>"
|
|
149
163
|
- !ruby/object:Gem::Version
|
|
150
|
-
version: '2
|
|
164
|
+
version: '2'
|
|
151
165
|
- !ruby/object:Gem::Dependency
|
|
152
166
|
name: memory_profiler
|
|
153
167
|
requirement: !ruby/object:Gem::Requirement
|
|
154
168
|
requirements:
|
|
155
169
|
- - "~>"
|
|
156
170
|
- !ruby/object:Gem::Version
|
|
157
|
-
version: '1
|
|
171
|
+
version: '1'
|
|
172
|
+
type: :development
|
|
173
|
+
prerelease: false
|
|
174
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
175
|
+
requirements:
|
|
176
|
+
- - "~>"
|
|
177
|
+
- !ruby/object:Gem::Version
|
|
178
|
+
version: '1'
|
|
179
|
+
- !ruby/object:Gem::Dependency
|
|
180
|
+
name: rbs
|
|
181
|
+
requirement: !ruby/object:Gem::Requirement
|
|
182
|
+
requirements:
|
|
183
|
+
- - "~>"
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: '3'
|
|
158
186
|
type: :development
|
|
159
187
|
prerelease: false
|
|
160
188
|
version_requirements: !ruby/object:Gem::Requirement
|
|
161
189
|
requirements:
|
|
162
190
|
- - "~>"
|
|
163
191
|
- !ruby/object:Gem::Version
|
|
164
|
-
version: '
|
|
192
|
+
version: '3'
|
|
165
193
|
description: Lightweight JSON logger and formatter integrating with Rails/ActiveSupport.
|
|
166
194
|
No extra deps beyond Rails/Activesupport. Compatible with Rails 6–8.
|
|
167
195
|
email:
|