Add config.logtail.enabled to turn the integration off per environment - #60
Merged
Merged
Conversation
Each case boots a small app in a subprocess, since booting patches Rails classes for the whole process. With `config.logtail.enabled = false` in an environment file, no Logtail middleware may be installed, DebugExceptions must keep its own logging, the Rails.event subscriber stays off, and Rails.logger has to write log/<env>.log, also when config/application.rb created the logger with create_default_logger. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new initializer runs once the environment files are loaded and before Rails' :initialize_logger. When the switch is off, it disables all integrations before the :logtail initializer picks the middlewares, and replaces a Logtail::Logger in config.logger, typically the one create_default_logger built in config/application.rb, with one writing to log/<env>.log, so structured logger calls keep working. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mattr_accessor ignores its default: option before Rails 5.2, so EventLogSubscriber.enabled starts as nil there. It only matters on Rails 8.1 and newer anyway. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
logtail-rack 0.2.8 times responses with the monotonic clock, which Timecop doesn't freeze, so "Completed 200 OK in 0.0ms" no longer holds. The last CI run on main still resolved logtail-rack 0.2.7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With config.logtail.enabled = false the log file starts with Ruby Logger's "# Logfile created on … by logger.rb" line, which Rails' own log file doesn't have. This test fails until the file is opened the way Rails does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… as Rails Passing the path to Logger made it create the file and write its "# Logfile created on …" header. Rails opens log/<env>.log itself in append mode, so its log has no such line. Doing the same makes the log output with config.logtail.enabled = false identical to an app without the gem. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PetrHeinz
marked this pull request as ready for review
October 2, 2026 09:21
This was referenced Oct 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
There is no way to turn the Rails integration off in one environment. Installing the gem is enough to change local logging: the gem silences DebugExceptions' own logging, so development logs lose exception backtraces;
log/development.logstops being written onceconfig/application.rbsetsconfig.logger = Logtail::Logger.create_default_logger(...)as the docs show; and when the logger is only configured for production, the default Rails logger prints raw Ruby hashes. The red-team reproduced all three on Rails 8.1, e.g. with the docs setup in development a failing request logged onlyArgumentError (issue10 boom), without a backtrace, and nolog/development.logwas written. Reported in #10This adds
config.logtail.enabled, true by default:Logtail::Config#enabled=and#enabled?inlib/logtail-rails/config.rb, reachable asconfig.logtail.enabledinconfig/application.rbandconfig/environments/*.rb.:logtail_enabledinitializer runs after the environment files are loaded and before Rails':initialize_logger. When the switch is off, it callsLogtail::Integrations::Rails.enabled = falsebefore the:logtailinitializer builds its middleware list, so no Logtail middleware is installed, DebugExceptions,Rails::Rack::Loggerand the log subscribers stay unpatched, and theRails.eventsubscriber stays disabled.config.loggerholds aLogtail::Loggerat that point, typically the onecreate_default_loggerbuilt inconfig/application.rb, it's replaced by aLogtail::Loggerthat writes tolog/<env>.log. Calls likeRails.logger.info("message", key: value)keep working, nothing goes to Better Stack, andrails serverstill mirrors the log to the console.Behaviour and compatibility:
config/application.rbor an environment file.config/initializers/*run after Rails has set up its logger, which is too late.Logtail::Loggerinconfig.loggeris replaced, not only one built bycreate_default_logger, since a disabled environment shouldn't send logs.Sidekiq.loggerkeeps the logger thatcreate_default_loggergave it. This PR doesn't change that.The tests boot a small app in a subprocess per case, because booting patches Rails classes for the whole process: switched off in development (where
create_default_loggerbuilds the HTTP logger) and in test (where it returns the STDOUT logger), plus a control boot with the default.Targets the 0.2.15 patch release. No dependencies.
The commit "Expect real response durations in the request specs" is the same change as in #59: logtail-rack 0.2.8 times responses with the monotonic clock, which Timecop doesn't freeze, so three existing specs now fail on every branch based on main. It's identical in both PRs, so it merges cleanly whichever lands first.
The first commit only adds the tests and is expected to fail on CI. The implementation follows in the next commit.
Follow-up (f2e1f30 test, 0cb8ae6 fix): with the switch off, the log file used to start with Ruby Logger's
# Logfile created on … by logger.rbline. That happened because the path was passed to Logger, which then created the file. Rails openslog/<env>.logitself, so stock Rails has no such line. The file is now opened the same way. I ran the same app side by side, once without the gem and once withconfig.logtail.enabled = false:log/development.log,log/test.logand the console output were identical apart from timings.🤖 Generated with Claude Code