Skip to content

Commit

Permalink
Enable adding custom LogStasher fields from apps
Browse files Browse the repository at this point in the history
I.e. allow apps to add their own custom fields in addition to those that
`GovukJsonLogging` already adds.

It looks like `LogStasher.add_custom_fields` can only be called one
time, otherwise subsequent calls overwrite previous ones.

We found this happening in the wild in the Content Store app, where
`govuk_request_id` et al were missing from the Rails framework logs but
present whenever the logger had been invoked directly from our own code.

I am curious about the possibility of being able to add custom fields to
both types of logs, together or separately, but the bug we're currently
experiencing is just a conflict between two calls to
`LogStasher.add_custom_fields`, so that's what I'm addressing.

---

I've manually tested this change locally with Content Store, both with
and without its own custom field config.
  • Loading branch information
mike29736 committed Nov 27, 2023
1 parent 6c67586 commit 3cdb633
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Unreleased

* Enable adding custom LogStasher fields from apps ([#327](https://github.com/alphagov/govuk_app_config/pull/327))

# 9.6.0

* Allow YouTube thumbnails from https://i.ytimg.com in the global Content Security Policy ([#328](https://github.com/alphagov/govuk_app_config/pull/328))
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,20 @@ allow JSON format logs and `Govuk-Request-Id` to be visible.
For development logs, in order to see the production style logs, developers should
set `GOVUK_RAILS_JSON_LOGGING`in `govuk-docker` -> `docker-compose` files.

### Logger configuration

To include additional custom fields in your Rails logs, you can declare them
within a `GovukJsonLogging.configure` block in a `config/initializers/` file.

Example of adding a key/value to log entries based on a request header:

```ruby
GovukJsonLogging.configure do
add_custom_fields do |fields|
fields[:govuk_custom_field] = request.headers["GOVUK-Custom-Header"]
end
end
```

## Content Security Policy generation

Expand Down
20 changes: 19 additions & 1 deletion lib/govuk_app_config/govuk_json_logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,23 @@
require "action_controller"

module GovukJsonLogging
def self.configure
class Configuration
def initialize
@custom_fields_block = proc {}
end

attr_reader :custom_fields_block

def add_custom_fields(&block)
@custom_fields_block = block if block_given?
end
end

def self.configure(&block)
configuration = Configuration.new

configuration.instance_eval(&block) if block_given?

# We disable buffering, so that logs aren't lost on crash or delayed
# indefinitely while troubleshooting.
$stdout.sync = true
Expand Down Expand Up @@ -31,6 +47,8 @@ def self.configure
fields[:govuk_request_id] = request.headers["GOVUK-Request-Id"]
fields[:varnish_id] = request.headers["X-Varnish"]
fields[:govuk_app_config] = GovukAppConfig::VERSION

instance_exec(fields, &configuration.custom_fields_block) if block_given?
end

Rails.application.config.logstasher.enabled = true
Expand Down

0 comments on commit 3cdb633

Please sign in to comment.