activesupport-json_logging 1.0.0 → 1.1.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 +8 -40
- data/README.md +48 -21
- data/lib/activesupport/json_logging.rb +0 -1
- data/lib/json_logging/payload_builder.rb +11 -3
- data/lib/json_logging/version.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4854135797f8609d12de7e48f10b2ece4151e828ae9d6699fcd8f367f645cf5f
|
|
4
|
+
data.tar.gz: 7fe2c2710e8adcab432233e3c55f97d337ba89ca1d5bd286c4e8b290662a3ac7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd806fd601a0c4f761bd235f46e848f16701fe09e2995039c22e07c4aaa26545ad15f756ec635da3768a20a678fe7d3f6f35d2535a98f482fe885137758c1a58
|
|
7
|
+
data.tar.gz: 72c2460e491be67a3ead7de92e549cf11d13c51b3da774251080263311b51c3c8a79a7bc0ad4354b9bb2b0d11d16ae47f74511b800f1230b2fb5aaf3adc68b8c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,44 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# CHANGELOG
|
|
2
2
|
|
|
3
|
-
## 1.
|
|
3
|
+
## 1.1.0 (2025-11-04)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- 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"]`)
|
|
6
|
+
- Filter system-controlled keys (severity, timestamp, message, tags, context) from user context to prevent conflicts
|
|
7
|
+
- Prevent nested context objects when user context includes a `context` key
|
|
8
|
+
- Fix pending spec for TimeWithZone objects by requiring ActiveSupport time extensions
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
- feat: native tagged logging with `logger.tagged("TAG")` API compatible with Rails
|
|
9
|
-
- feat: thread-safe context via `JsonLogging.with_context` for per-thread fields
|
|
10
|
-
- feat: smart message parsing for hashes, JSON strings, and plain strings
|
|
11
|
-
- feat: inherit all ActiveSupport::Logger features (silence, local_level, etc.)
|
|
12
|
-
- feat: BroadcastLogger compatibility for Rails 7.1+ automatic wrapping
|
|
13
|
-
- feat: timestamp precision in microseconds (iso8601 with 6 decimals)
|
|
14
|
-
- feat: Rails ParameterFilter integration for automatic sensitive data filtering
|
|
15
|
-
- feat: input sanitization removing control characters and truncating long strings
|
|
16
|
-
- feat: sensitive key pattern matching fallback when ParameterFilter unavailable
|
|
17
|
-
- feat: depth and size limits for nested structures to prevent log bloat
|
|
18
|
-
- feat: single-line JSON output to prevent log injection via newlines
|
|
19
|
-
- feat: graceful error handling with fallback entries on serialization errors
|
|
20
|
-
- feat: Rails 6.0, 6.1, 7.0, 7.1, 7.2, 8.0 support
|
|
21
|
-
- feat: IsolatedExecutionState for thread/Fiber isolation (Rails 7.1+)
|
|
22
|
-
- feat: backward compatible fallback to Thread.current for Rails 6-7.0
|
|
23
|
-
- feat: kwargs support in logger initialization for Rails 7+
|
|
24
|
-
- perf: ~0.006ms per log entry overhead (250-400% vs plain text, typical for JSON)
|
|
25
|
-
- perf: memory efficient with ~3KB per entry and zero retained memory
|
|
26
|
-
- feat: performance benchmarks with memory profiling included
|
|
27
|
-
- test: 93.78% code coverage with comprehensive RSpec suite
|
|
28
|
-
- test: BroadcastLogger integration tests
|
|
29
|
-
- test: IsolatedExecutionState thread safety tests
|
|
30
|
-
- test: Appraisals configured for multi-version testing (Rails 6-8)
|
|
31
|
-
- test: GitHub Actions CI workflow
|
|
32
|
-
- docs: complete README with installation, usage, and API docs
|
|
33
|
-
- docs: Rails environment configuration examples (development, production, test)
|
|
34
|
-
- docs: Lograge integration with third-party logger configurations
|
|
35
|
-
- docs: Puma integration example
|
|
36
|
-
- docs: security best practices and ParameterFilter guide
|
|
37
|
-
- docs: inherited Rails logger features documentation
|
|
10
|
+
## 1.0.0 (2025-10-31)
|
|
38
11
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
## 0.1.0
|
|
42
|
-
|
|
43
|
-
- feat: initial JSON formatter and logger implementation
|
|
44
|
-
- test: basic RSpec test coverage
|
|
12
|
+
- Initial stable release
|
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://github.com/amkisko/activesupport-json_logging.rb/actions/workflows/ci.yml) [](https://badge.fury.io/rb/activesupport-json_logging) [](https://github.com/amkisko/activesupport-json_logging.rb/actions/workflows/ci.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,7 @@ Supports Rails versions from 6 to 8.
|
|
|
8
8
|
|
|
9
9
|
Sponsored by [Kisko Labs](https://www.kiskolabs.com).
|
|
10
10
|
|
|
11
|
+
|
|
11
12
|
## Installation
|
|
12
13
|
|
|
13
14
|
Add to your Gemfile:
|
|
@@ -30,22 +31,6 @@ Rails.application.configure do
|
|
|
30
31
|
end
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
### Development: Using from Local Repository
|
|
34
|
-
|
|
35
|
-
When developing the gem or testing changes in your application, you can point your Gemfile to a local path:
|
|
36
|
-
|
|
37
|
-
```ruby
|
|
38
|
-
# In your application's Gemfile
|
|
39
|
-
gem "activesupport-json_logging", path: "../activesupport-json_logging.rb"
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Then run:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
bundle install
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
**Note:** When using `path:` in your Gemfile, Bundler will use the local gem directly. Changes you make to the gem code will be immediately available in your application without needing to rebuild or reinstall the gem. This is ideal for development and testing.
|
|
49
34
|
|
|
50
35
|
## What you get
|
|
51
36
|
|
|
@@ -329,10 +314,10 @@ logger.tagged("BCX").tagged("Jason").info("Stuff")
|
|
|
329
314
|
# Wrap a TaggedLogging logger - works perfectly
|
|
330
315
|
tagged_logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
|
331
316
|
json_logger = JsonLogging.new(tagged_logger)
|
|
332
|
-
json_logger.tagged("TEST") { json_logger.info("message") } # Tags appear in JSON
|
|
317
|
+
json_logger.tagged("TEST") { json_logger.info("message") } # Tags appear at root level in JSON
|
|
333
318
|
```
|
|
334
319
|
|
|
335
|
-
**Note:** If you wrap a `JsonLogging` logger with `ActiveSupport::TaggedLogging`, the TaggedLogging's text-based tags will appear as part of the message string in the JSON output, not as structured tags
|
|
320
|
+
**Note:** If you wrap a `JsonLogging` logger with `ActiveSupport::TaggedLogging`, the TaggedLogging's text-based tags will appear as part of the message string in the JSON output, not as structured tags at the root level. For best results, wrap loggers with `JsonLogging` last.
|
|
336
321
|
|
|
337
322
|
### JsonLogging::JsonLogger
|
|
338
323
|
|
|
@@ -359,7 +344,7 @@ formatter.call("INFO", Time.now, nil, "message")
|
|
|
359
344
|
|
|
360
345
|
# With tags (useful for Puma or other standalone use cases)
|
|
361
346
|
formatter = JsonLogging::Formatter.new(tags: ["Puma"])
|
|
362
|
-
formatter.call("INFO", Time.now, nil, "message") # Output includes "Puma" tag
|
|
347
|
+
formatter.call("INFO", Time.now, nil, "message") # Output includes "Puma" tag at root level
|
|
363
348
|
|
|
364
349
|
# Multiple tags
|
|
365
350
|
formatter = JsonLogging::Formatter.new(tags: ["Puma", "Worker"])
|
|
@@ -511,6 +496,7 @@ Rails.application.config.filter_parameters += [
|
|
|
511
496
|
|
|
512
497
|
The gem will automatically filter these from all log entries, including context data. Encrypted attributes (using Rails 7+ `encrypts`) are automatically filtered as well.
|
|
513
498
|
|
|
499
|
+
|
|
514
500
|
## Development
|
|
515
501
|
|
|
516
502
|
```bash
|
|
@@ -536,6 +522,47 @@ bundle exec appraisal rails-7.0 rspec
|
|
|
536
522
|
bundle exec standardrb --fix
|
|
537
523
|
```
|
|
538
524
|
|
|
525
|
+
### Development: Using from Local Repository
|
|
526
|
+
|
|
527
|
+
When developing the gem or testing changes in your application, you can point your Gemfile to a local path:
|
|
528
|
+
|
|
529
|
+
```ruby
|
|
530
|
+
# In your application's Gemfile
|
|
531
|
+
gem "activesupport-json_logging", path: "../activesupport-json_logging.rb"
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Then run:
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
bundle install
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
**Note:** When using `path:` in your Gemfile, Bundler will use the local gem directly. Changes you make to the gem code will be immediately available in your application without needing to rebuild or reinstall the gem. This is ideal for development and testing.
|
|
541
|
+
|
|
542
|
+
## Contributing
|
|
543
|
+
|
|
544
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/amkisko/activesupport-json_logging.rb
|
|
545
|
+
|
|
546
|
+
Contribution policy:
|
|
547
|
+
- New features are not necessarily added to the gem
|
|
548
|
+
- Pull request should have test coverage for affected parts
|
|
549
|
+
- Pull request should have changelog entry
|
|
550
|
+
|
|
551
|
+
Review policy:
|
|
552
|
+
- It might take up to 2 calendar weeks to review and merge critical fixes
|
|
553
|
+
- It might take up to 6 calendar months to review and merge pull request
|
|
554
|
+
- It might take up to 1 calendar year to review an issue
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
## Publishing
|
|
558
|
+
|
|
559
|
+
```sh
|
|
560
|
+
rm activesupport-json_logging-*.gem
|
|
561
|
+
gem build activesupport-json_logging.gemspec
|
|
562
|
+
gem push activesupport-json_logging-*.gem
|
|
563
|
+
```
|
|
564
|
+
|
|
539
565
|
## License
|
|
540
566
|
|
|
541
|
-
MIT
|
|
567
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
568
|
+
|
|
@@ -29,14 +29,22 @@ module JsonLogging
|
|
|
29
29
|
additional_context || {}
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
# Filter out system-controlled keys from user context
|
|
33
|
+
# These keys should never be set by user context as they're controlled by the logger
|
|
34
|
+
system_controlled_keys = [:tags, "tags", :severity, "severity", :timestamp, "timestamp", :message, "message", :context, "context"]
|
|
35
|
+
user_context_filtered = sanitized_context.except(*system_controlled_keys)
|
|
36
|
+
|
|
37
|
+
# Also prevent overriding any existing payload keys (additional safety)
|
|
38
|
+
deduped_additional = user_context_filtered.reject { |k, _| payload.key?(k) }
|
|
33
39
|
merged_context = existing_context.merge(deduped_additional)
|
|
34
40
|
|
|
41
|
+
# Put tags at root level, separate from context
|
|
42
|
+
# Merge with existing tags from payload (e.g., when logging a hash with tags: [...] at root)
|
|
35
43
|
unless tags.empty?
|
|
36
|
-
existing_tags = Array(
|
|
44
|
+
existing_tags = Array(payload[:tags] || payload["tags"])
|
|
37
45
|
# Sanitize tag strings (remove control chars, truncate)
|
|
38
46
|
sanitized_tags = tags.map { |tag| Sanitizer.sanitize_string(tag.to_s) }
|
|
39
|
-
|
|
47
|
+
payload[:tags] = (existing_tags + sanitized_tags).uniq
|
|
40
48
|
end
|
|
41
49
|
|
|
42
50
|
payload[:context] = merged_context unless merged_context.empty?
|
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.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- amkisko
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -92,6 +92,34 @@ dependencies:
|
|
|
92
92
|
- - "~>"
|
|
93
93
|
- !ruby/object:Gem::Version
|
|
94
94
|
version: '0.21'
|
|
95
|
+
- !ruby/object:Gem::Dependency
|
|
96
|
+
name: rspec_junit_formatter
|
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - "~>"
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '0.6'
|
|
102
|
+
type: :development
|
|
103
|
+
prerelease: false
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - "~>"
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: '0.6'
|
|
109
|
+
- !ruby/object:Gem::Dependency
|
|
110
|
+
name: simplecov-cobertura
|
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - "~>"
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '3'
|
|
116
|
+
type: :development
|
|
117
|
+
prerelease: false
|
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
119
|
+
requirements:
|
|
120
|
+
- - "~>"
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
version: '3'
|
|
95
123
|
- !ruby/object:Gem::Dependency
|
|
96
124
|
name: standard
|
|
97
125
|
requirement: !ruby/object:Gem::Requirement
|