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 Rackstash
module Encoders module Encoders
# The Message encoder only returns the message of log event. All other # The Message encoder only returns the formatted message of log event. All
# fields and tags are ignored. # 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 # If any `prefix_fields` are given in the initializer, we gather their
# required, mostly during development where debug logs are directly consumed # values from the event and prefix them to each line in the message if the
# by humans # 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 class Message
include Rackstash::Encoders::Helpers::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} # @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) def encode(event)
normalize_message(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 end
end end

View File

@ -10,12 +10,39 @@ require 'spec_helper'
require 'rackstash/encoders/message' require 'rackstash/encoders/message'
describe Rackstash::Encoders::Message do describe Rackstash::Encoders::Message do
let(:encoder) { described_class.new } let(:tagged) { [] }
let(:encoder) { described_class.new(tagged: tagged) }
describe '#encode' do describe '#encode' do
it 'gets the message from the event hash' do it 'gets the message from the event hash' do
event = { 'hello' => 'world', 'message' => ["\n\t \nline1\n", "line2\n \n\t\n"] } 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" expect(encoder.encode(event)).to eql "\n\t \nline1\nline2\n \n\t\n"
end 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
end end