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

Insert an ellipsis if messages are removed in TruncateMessage filter

If messages are removed by the final cut step (but not when applying the
selectors), we insert an ellipsis, by default a Message with the
contents of "[...]\n", at the place where we removed messages. This
helps the investigating human who reads the logs to understand that
there were logs messages removed from the event.
This commit is contained in:
Holger Just 2017-10-05 01:05:53 +02:00
parent 37c85ec038
commit 4ee34e5d4e
2 changed files with 43 additions and 5 deletions

View File

@ -27,6 +27,8 @@ module Rackstash
# message list, with `cut: :bottom` (the default) with the very last # message list, with `cut: :bottom` (the default) with the very last
# message and with `cut: :middle` we are deleting from the middle of the # message and with `cut: :middle` we are deleting from the middle of the
# message list preserving the messages at the beginning and the end. # message list preserving the messages at the beginning and the end.
# If there are any messages deleted in this last step, we insert the
# `elipsis` once at the location where the messages were removed.
# #
# Note that in any case, we are only ever deleting whole messages (which # Note that in any case, we are only ever deleting whole messages (which
# usually but not necessarily amount to whole lines). We are not splitting # usually but not necessarily amount to whole lines). We are not splitting
@ -51,6 +53,8 @@ module Rackstash
# cut: :middle # cut: :middle
# end # end
class TruncateMessage class TruncateMessage
ELLIPSIS = "[...]\n".freeze
# @param max_size [Integer] The maximum desired number of characters for # @param max_size [Integer] The maximum desired number of characters for
# all the messages in an event combined # all the messages in an event combined
# @param selectors [Array<#call>] An optional list of message filters # @param selectors [Array<#call>] An optional list of message filters
@ -59,7 +63,10 @@ module Rackstash
# @param cut [Symbol] where to start removing messages if the message list # @param cut [Symbol] where to start removing messages if the message list
# is still too large after all filters were applied. One of `:top`, # is still too large after all filters were applied. One of `:top`,
# `:middle`, or `:bottom`. # `:middle`, or `:bottom`.
def initialize(max_size, selectors: [], cut: :bottom) # @param ellipsis [String] A string to insert at the location where lines
# were removed by the final cut (if any) to mark the location in the
# logs. Set this to `nil` to not insert an ellipsis.
def initialize(max_size, selectors: [], cut: :bottom, ellipsis: ELLIPSIS)
@max_size = Integer(max_size) @max_size = Integer(max_size)
@selectors = Array(selectors) @selectors = Array(selectors)
@ -67,6 +74,7 @@ module Rackstash
raise ArgumentError, 'cut must be one of :top, :middle, :bottom' raise ArgumentError, 'cut must be one of :top, :middle, :bottom'
end end
@cut = cut @cut = cut
@ellipsis = ellipsis
end end
# Remove messages if the overall size in bytes of all the messages in the # Remove messages if the overall size in bytes of all the messages in the
@ -90,6 +98,7 @@ module Rackstash
return event if messages.size <= 1 return event if messages.size <= 1
overall_size = overall_size_of(messages) overall_size = overall_size_of(messages)
ellipsis = nil
until overall_size <= @max_size || messages.size <= 1 until overall_size <= @max_size || messages.size <= 1
case @cut case @cut
when :top when :top
@ -100,6 +109,18 @@ module Rackstash
msg = messages.pop msg = messages.pop
end end
overall_size -= msg.size overall_size -= msg.size
unless ellipsis || @ellipsis.nil?
ellipsis = Rackstash::Message.new(@ellipsis)
overall_size += ellipsis.size
end
end
if ellipsis
case @cut
when :top then messages.unshift(ellipsis)
when :middle then messages.insert((messages.size + 1) / 2, ellipsis)
when :bottom then messages.push(ellipsis)
end
end end
event event

View File

@ -10,7 +10,7 @@ require 'spec_helper'
require 'rackstash/filters/truncate_message' require 'rackstash/filters/truncate_message'
describe Rackstash::Filters::TruncateMessage do describe Rackstash::Filters::TruncateMessage do
let(:max_size) { 30 } let(:max_size) { 36 }
let(:args) { { selectors: [], cut: :bottom } } let(:args) { { selectors: [], cut: :bottom } }
let(:filter) { described_class.new(max_size, **args) } let(:filter) { described_class.new(max_size, **args) }
@ -67,7 +67,11 @@ describe Rackstash::Filters::TruncateMessage do
it 'removes the messages at the beginning' do it 'removes the messages at the beginning' do
filter.call(event) filter.call(event)
expect(messages).to eql ['sweet middle text', 'final message'] expect(messages).to match [
instance_of(Rackstash::Message), # the ellipsis
'sweet middle text',
'final message'
]
end end
end end
@ -78,7 +82,11 @@ describe Rackstash::Filters::TruncateMessage do
it 'removes the messages in the middle' do it 'removes the messages in the middle' do
filter.call(event) filter.call(event)
expect(messages).to eql ['some long message', 'final message'] expect(messages).to match [
'some long message',
instance_of(Rackstash::Message), # the ellipsis
'final message'
]
end end
end end
@ -89,8 +97,17 @@ describe Rackstash::Filters::TruncateMessage do
it 'removes the messages at the end' do it 'removes the messages at the end' do
filter.call(event) filter.call(event)
expect(messages).to eql ['some long message'] expect(messages).to match [
'some long message',
instance_of(Rackstash::Message) # the ellipsis
]
end end
end end
it 'does not include an ellipsis if it is nil' do
args[:ellipsis] = nil
filter.call(event)
expect(messages).to eql ['some long message', 'sweet middle text']
end
end end
end end