Skip to content

Commit

Permalink
Remove the rewiring stdout and strerr logic
Browse files Browse the repository at this point in the history
The redirection was a workaround for log file parsers and
it is no longer needed. So we remove that part and simplify the logger settings.

Co-authored-by: Neamah Al-Selwi <neamah.alselwi@digital.cabinet-office.gov.uk>
Co-authored-by: Tuomas Nylund <tuomas.nylund@digital.cabinet-office.gov.uk>
  • Loading branch information
3 people committed Jul 5, 2023
1 parent 5836a2e commit 0a6f772
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 28 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,6 @@ check docs](docs/healthchecks.md) for more information on how to use it.

## Rails logging

In Rails applications, the application will be configured to send JSON-formatted
logs to `STDOUT` and unstructured logs to `STDERR`.

To enable production-like logging, an env variable `GOVUK_RAILS_JSON_LOGGING`
is set in the `govuk-helm-charts` and then checked in `railtie.rb`. This will
allow JSON format logs and `Govuk-Request-Id` to be visible.
Expand Down
22 changes: 2 additions & 20 deletions lib/govuk_app_config/govuk_json_logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,14 @@

module GovukJsonLogging
def self.configure
# GOV.UK Rails applications are expected to output JSON to stdout which is
# then indexed in a Kibana instance. These log outputs are created by the
# logstasher gem.
#
# Rails applications will typically write other things to stdout such as
# `Rails.logger` calls or 'puts' statements. However these are not in a
# JSON format which causes problems for the log file parsers.
#
# To resolve this we redirect stdout to stderr, to cover any Rails
# writing. This frees up the normal stdout for the logstasher logs.
#
# We also disable buffering, so that logs aren't lost on crash or delayed
# indefinitely while troubleshooting.

# rubocop:disable Style/GlobalVars
$real_stdout = $stdout.clone
$real_stdout.sync = true
$stdout.reopen($stderr)
$stdout.sync = true
# rubocop:enable Style/GlobalVars

Rails.logger = Logger.new(
$real_stdout, # rubocop:disable Style/GlobalVars
$stdout,
level: Rails.logger.level,
formatter: proc { |severity, datetime, _progname, msg|

begin
message = JSON.parse(msg)
rescue JSON::ParserError, TypeError => _e
Expand Down Expand Up @@ -77,7 +59,7 @@ def self.configure
Rails.application.config.logstasher.source = {}

Rails.application.config.logstasher.logger = Logger.new(
$real_stdout, # rubocop:disable Style/GlobalVars
$stdout,
level: Rails.logger.level,
formatter: proc { |_severity, _datetime, _progname, msg|
"#{msg.is_a?(String) ? msg : msg.inspect}\n"
Expand Down
10 changes: 5 additions & 5 deletions spec/lib/govuk_json_logging_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,23 @@ def self.headers
after { Rails.application = nil }

original_stderr = nil
original_stdout = nil

let(:fake_stdout) { StringIO.new }
let(:fake_stderr) { StringIO.new }
let(:info_log_level) { 1 }

before do
original_stderr = $stderr
original_stdout = $stdout
$stderr = fake_stderr
allow($stdout).to receive(:clone).and_return(fake_stdout)
allow($stdout).to receive(:reopen)
$stdout = fake_stdout
Rails.logger = Logger.new(fake_stdout, level: info_log_level)

end

after do
$stderr = original_stderr
$stdout = original_stdout
end

describe ".configure" do
Expand Down Expand Up @@ -80,7 +81,7 @@ def app
Rails.application
end

it "logs errors thrown by the application" do
it "logs errors thrown by the application with govuk_request_id" do
stub_const("GdsApi::GovukHeaders", govuk_headers_class)
GovukJsonLogging.configure
get "/error"
Expand Down Expand Up @@ -133,7 +134,6 @@ def app

expect(log_json).to include("message" => "test default log entry")
expect(log_json).to include("govuk_request_id" => "some-value")

end
end
end
Expand Down

0 comments on commit 0a6f772

Please sign in to comment.