Module: GovukLogging

Defined in:
lib/govuk_app_config/govuk_logging.rb,
lib/govuk_app_config/rails_ext/action_dispatch/debug_exceptions.rb

Defined Under Namespace

Modules: RailsExt

Class Method Summary collapse

Class Method Details

.configureObject



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/govuk_app_config/govuk_logging.rb', line 6

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've directed stdout to stderr, to cover any Rails
  # writing. This frees up the normal stdout for the logstasher logs.

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

  # Send Rails' logs to STDERR because they're not JSON formatted.
  Rails.logger = ActiveSupport::TaggedLogging.new(Logger.new($stderr, level: Rails.logger.level))

  # Custom that will be added to the Rails request logs
  LogStasher.add_custom_fields do |fields|
    # Mirrors Nginx request logging, e.g GET /path/here HTTP/1.1
    fields[:request] = "#{request.request_method} #{request.fullpath} #{request.headers['SERVER_PROTOCOL']}"

    # Pass request Id to logging
    fields[:govuk_request_id] = request.headers["GOVUK-Request-Id"]

    fields[:varnish_id] = request.headers["X-Varnish"]

    fields[:govuk_app_config] = GovukAppConfig::VERSION
  end

  Rails.application.config.logstasher.enabled = true

  # Log controller actions so that we can graph response times
  Rails.application.config.logstasher.controller_enabled = true

  # The other loggers are not that interesting in production
  Rails.application.config.logstasher.mailer_enabled = false
  Rails.application.config.logstasher.record_enabled = false
  Rails.application.config.logstasher.view_enabled = false
  Rails.application.config.logstasher.job_enabled = false

  Rails.application.config.logstasher.logger = Logger.new(
    $real_stdout, # rubocop:disable Style/GlobalVars
    level: Rails.logger.level,
    formatter: proc { |_severity, _datetime, _progname, msg|
      "#{msg.is_a?(String) ? msg : msg.inspect}\n"
    },
  )
  Rails.application.config.logstasher.suppress_app_log = true

  if defined?(GdsApi::Base)
    GdsApi::Base.default_options ||= {}

    # The GDS API Adapters gem logs JSON to describe the requests it
    # makes and the responses it gets, so direct this to the
    # logstasher logger
    GdsApi::Base.default_options[:logger] =
      Rails.application.config.logstasher.logger
  end

  RailsExt::ActionDispatch.monkey_patch_log_error if RailsExt::ActionDispatch.should_monkey_patch_log_error?
end