Skip to content

Commit

Permalink
Ensure all strings with spaces are quoted in logs
Browse files Browse the repository at this point in the history
The current logic covers the case when the log data is already a `String` instance, but not when the data is some other object that, when interpolated into the log string, results in a string containing spaces.

The example that led me here is where an exception is logged and the exception's message contains spaces. The exception gets interpolated into the string and has `to_s` called on it. [`Exception#to_s`](https://ruby-doc.org/core-2.6.5/Exception.html#method-i-to_s) returns the message, so the message (with its spaces) go into the log line, but it's bypassed the logic that adds quotes.

I used `"#{v}"` instead of `v.to_s` because it seems there is a [subtle difference in their behaviour](https://github.com/ruby/spec/blob/master/language/string_spec.rb#L147-L158), to cover the rare case where `to_s` doesn't return a string. I think we want to keep the existing behaviour here.
  • Loading branch information
bensymonds committed Jan 30, 2020
1 parent e8fb352 commit 71ad622
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p

## [Unreleased]
### Changed
- Ensure all strings with spaces are quoted in logs. ([#332](https://github.com/interagent/pliny/pull/332))
- Allow ActiveSupport 5 or 6. ([#331](https://github.com/interagent/pliny/pull/331))

### Fixed
Expand Down
9 changes: 6 additions & 3 deletions lib/pliny/log.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,15 @@ def unparse_pair(k, v)
k
elsif v.is_a?(Float)
"#{k}=#{format("%.3f", v)}"
elsif v.is_a?(String) && v =~ /\s/
quote_string(k, v)
elsif v.is_a?(Time)
"#{k}=#{v.iso8601}"
else
"#{k}=#{v}"
v = "#{v}"
if v =~ /\s/
quote_string(k, v)
else
"#{k}=#{v}"
end
end
end
end
Expand Down
14 changes: 14 additions & 0 deletions spec/log_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,19 @@ def to_s
end
Pliny.log(foo: klass.new)
end

it "quotes strings that are generated from object interpolation" do
expect(@io).to receive(:print).with("foo=\"message with space\"\n")
expect(@io).to receive(:print).with("foo=\"bar with space\"\n")

Pliny.log(foo: StandardError.new("message with space"))

klass = Class.new do
def to_s
"bar with space"
end
end
Pliny.log(foo: klass.new)
end
end
end

0 comments on commit 71ad622

Please sign in to comment.