Skip to content

Commit 1e3c7b2

Browse files
ndbroadbentclaude
andcommitted
Fix development logs being wrapped when LogStruct is disabled
The TaggedLogging formatter monkey patch was unconditionally wrapping all string log messages in hashes, even when LogStruct was disabled. This caused development logs to appear as {message: "..."} instead of plain text. Added an early return check to preserve original Rails logging behavior when LogStruct is disabled. Fixes #1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5e7bdb6 commit 1e3c7b2

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

lib/log_struct/monkey_patches/active_support/tagged_logging/formatter.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,15 @@ module FormatterExtension
2727
# plain strings in a Hash under a `msg` key.
2828
# The data is then passed to our custom log formatter that transforms it
2929
# into a JSON string before logging.
30+
#
31+
# IMPORTANT: This only applies when LogStruct is enabled. When disabled,
32+
# we preserve the original Rails logging behavior to avoid wrapping
33+
# messages in hashes (which would break default Rails log formatting).
3034
sig { params(severity: T.any(String, Symbol), time: Time, progname: T.untyped, data: T.untyped).returns(String) }
3135
def call(severity, time, progname, data)
36+
# Skip hash wrapping when LogStruct is disabled to preserve default Rails behavior
37+
return super unless ::LogStruct.enabled?
38+
3239
# Convert data to a hash if it's not already one
3340
data = {message: data.to_s} unless data.is_a?(Hash)
3441

test/log_struct/configuration_test.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,26 @@ def test_merge_rails_filter_parameters_preserves_regex_filters
198198
LogStruct.config.filters.filter_matchers = T.must(original_matchers)
199199
end
200200

201+
# Test that development server process is DISABLED by default
202+
# (development is not in enabled_environments by default)
203+
def test_disabled_for_development_server_with_default_environments
204+
LogStruct.config.enabled = true
205+
# Use default enabled_environments: [:test, :production]
206+
LogStruct.config.enabled_environments = [:test, :production]
207+
208+
original_argv = ::ARGV.dup
209+
::ARGV.replace(["server"])
210+
211+
Rails.stub(:env, ActiveSupport::StringInquirer.new("development")) do
212+
LogStruct.set_enabled_from_rails_env!
213+
214+
assert_not LogStruct.config.enabled,
215+
"LogStruct should be DISABLED for development server (development not in enabled_environments)"
216+
end
217+
ensure
218+
::ARGV.replace(original_argv) if defined?(original_argv)
219+
end
220+
201221
# Test server process detection
202222
def test_enabled_for_server_process_in_production
203223
LogStruct.config.enabled = false
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# typed: true
2+
# frozen_string_literal: true
3+
4+
require "test_helper"
5+
6+
module LogStruct
7+
module MonkeyPatches
8+
class TaggedLoggingFormatterTest < ActiveSupport::TestCase
9+
setup do
10+
@original_config = LogStruct.config.dup
11+
@output = StringIO.new
12+
@logger = Logger.new(@output)
13+
@tagged_logger = ActiveSupport::TaggedLogging.new(@logger)
14+
end
15+
16+
teardown do
17+
LogStruct.configuration = @original_config
18+
end
19+
20+
def test_preserves_original_rails_behavior_when_disabled
21+
LogStruct.config.enabled = false
22+
23+
@tagged_logger.info("Test message")
24+
25+
output = @output.string
26+
27+
assert_includes output, "Test message"
28+
refute_includes output, "message:"
29+
refute_includes output, "{"
30+
end
31+
32+
def test_wraps_messages_in_hash_when_enabled
33+
LogStruct.config.enabled = true
34+
35+
@tagged_logger.info("Test message")
36+
37+
output = @output.string
38+
39+
assert_includes output, "message"
40+
end
41+
42+
def test_passes_through_hash_data_when_enabled
43+
LogStruct.config.enabled = true
44+
45+
@tagged_logger.info({event: "test", data: "value"})
46+
47+
output = @output.string
48+
49+
assert_includes output, "event"
50+
assert_includes output, "data"
51+
end
52+
53+
def test_passes_through_hash_data_when_disabled
54+
LogStruct.config.enabled = false
55+
56+
@tagged_logger.info({event: "test", data: "value"})
57+
58+
output = @output.string
59+
60+
assert_includes output, "event"
61+
assert_includes output, "data"
62+
end
63+
end
64+
end
65+
end

0 commit comments

Comments
 (0)