From b9b7ef7192905f61ccd9cbfaf9d6eb51c62203e0 Mon Sep 17 00:00:00 2001 From: Tom de Bruijn Date: Thu, 3 Oct 2024 11:09:42 +0200 Subject: [PATCH] Quote values with multiple words When a custom payload value is a String that contains multiple words, logfmt formatters break. Surround these values with quotes so that logfmt parsers don't think the second word is the start of the message I've chosen to let Ruby handle the escaping of the value by calling `inspect` so that single and double quotes are properly (double) escaped. I don't know if the default KeyValue formatter is supposed to be logfmt compatible, but it's very close so following the logfmt format here for escaping multi word values seems like a good idea. Change the RuboCop config to exclude all Ruby files in the `spec` dir for the "Metrics/BlockLength" rule so that the shared examples files aren't breaking the build. --- .rubocop.yml | 2 +- lib/lograge/formatters/key_value.rb | 2 ++ spec/support/examples.rb | 12 +++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 265ef77f..350a36be 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -17,7 +17,7 @@ Metrics/AbcSize: Metrics/BlockLength: Exclude: - - spec/**/*_spec.rb + - spec/**/*.rb Style/BlockDelimiters: Enabled: false diff --git a/lib/lograge/formatters/key_value.rb b/lib/lograge/formatters/key_value.rb index 0296170b..1ba37012 100644 --- a/lib/lograge/formatters/key_value.rb +++ b/lib/lograge/formatters/key_value.rb @@ -25,6 +25,8 @@ def parse_value(key, value) # a single quote return "'#{value}'" if key == :error return Kernel.format('%.2f', value) if value.is_a? Float + # Surround values with a space in them in quotes + return value.inspect if value.is_a?(String) && value.include?(' ') value end diff --git a/spec/support/examples.rb b/spec/support/examples.rb index 7507c997..6f7eda26 100644 --- a/spec/support/examples.rb +++ b/spec/support/examples.rb @@ -8,7 +8,9 @@ method: 'GET', path: '/', controller: 'welcome', - action: 'index' + action: 'index', + custom_sentence: 'Hello world', + custom_sentence_with_quotes: "I'm a \"test value\"" } end @@ -29,4 +31,12 @@ it "includes the 'custom' key/value" do expect(subject).to include('custom=data') end + + it "includes the 'custom_sentence' key/value" do + expect(subject).to include('custom_sentence="Hello world"') + end + + it "includes the 'custom_sentence_with_quotes' key/value" do + expect(subject).to include('custom_sentence_with_quotes="I\'m a \"test value\"') + end end