1
0
mirror of https://github.com/meineerde/rackstash.git synced 2025-12-19 15:01:12 +00:00

Optionally prefix all message lines with extraced fields in Message encoder

This can be used to achieve similar results as
ActiveSupport::TaggedLogger. With our implementation, the "tags" are
prepended to each line (instead of each message) and we add the same
tags to all message lines.

If required, you can still use ActiveSupport::TaggedLogger with
Rackstash to add tags at the time of adding the log message.
This commit is contained in:
Holger Just 2017-09-29 23:56:15 +02:00
parent 3584244bc1
commit 0941b24b63
2 changed files with 73 additions and 8 deletions

View File

@ -9,21 +9,59 @@ require 'rackstash/encoders/helpers/message'
module Rackstash
module Encoders
# The Message encoder only returns the message of log event. All other
# fields and tags are ignored.
# The Message encoder only returns the formatted message of log event. All
# other fields and tags are ignored. This encoder is useful in environments
# where the added fields are not required, mostly during development where
# (debug) logs are directly consumed by humans.
#
# This encoder is useful in environments where the added fields are not
# required, mostly during development where debug logs are directly consumed
# by humans
# If any `prefix_fields` are given in the initializer, we gather their
# values from the event and prefix them to each line in the message if the
# current event contains a value at the given field names.
#
# encoder = Rackstash::Encoders::Message.new(tagged: ['tags', 'remote_ip'])
#
# event = {
# 'remote_ip' => '127.0.0.1',
# 'tags' => ['foo', 123],
# 'message' => ["Hello\n", "World\n"],
# 'key' => 'value'
# }
# encoder.encode(event)
# # Logs "[foo,123] [127.0.0.1] Hello\n[foo,123] [127.0.0.1] World\n"
class Message
include Rackstash::Encoders::Helpers::Message
# @param [Array<#to_s>] An array of field names whose values are added in
# front of each message line on encode
def initialize(tagged: [])
@tagged_fields = Array(tagged).map(&:to_s)
end
# Return the formatted message of the given event.
#
# @param event [Hash] a log event as produced by the {Flow}
# @return [String] the `"message"` field of the event
# @return [String] the formatted message of the event
def encode(event)
normalize_message(event)
message = event[FIELD_MESSAGE]
event[FIELD_MESSAGE]
tags = @tagged_fields.map { |key| format_tag event[key] }.compact.join
message = message.gsub(/^/) { tags } unless tags.empty?
message
end
private
def format_tag(value)
case value
when nil
nil
when Array
"[#{value.map(&:to_s).join(',')}] "
else
"[#{value}] "
end
end
end
end

View File

@ -10,12 +10,39 @@ require 'spec_helper'
require 'rackstash/encoders/message'
describe Rackstash::Encoders::Message do
let(:encoder) { described_class.new }
let(:tagged) { [] }
let(:encoder) { described_class.new(tagged: tagged) }
describe '#encode' do
it 'gets the message from the event hash' do
event = { 'hello' => 'world', 'message' => ["\n\t \nline1\n", "line2\n \n\t\n"] }
expect(encoder.encode(event)).to eql "\n\t \nline1\nline2\n \n\t\n"
end
context 'with prefix_fields' do
let(:tagged) { [:sym, 'field', 'tags'] }
it 'adds fields to all lines' do
event = { 'message' => ["line1\t\n", "line2\nline3\n\t\n"], 'field' => 'BXC' }
expect(encoder.encode(event))
.to eql "[BXC] line1\t\n[BXC] line2\n[BXC] line3\n[BXC] \t\n"
end
it 'uses stringified fields' do
event = { 'message' => ["line1\n", "line2\nline3\n"], 'sym' => 'SYM', 'field' => 123 }
expect(encoder.encode(event))
.to eql "[SYM] [123] line1\n[SYM] [123] line2\n[SYM] [123] line3\n"
end
it 'formats arrays' do
event = { 'message' => ["line1\n", "line2\n"], 'tags' => ['foo', 'bar'] }
expect(encoder.encode(event)).to eql "[foo,bar] line1\n[foo,bar] line2\n"
end
it 'ignores missing fields' do
event = { 'message' => ["line1\n", "line2\n"] }
expect(encoder.encode(event)).to eql "line1\nline2\n"
end
end
end
end