mirror of
https://github.com/meineerde/rackstash.git
synced 2026-01-31 17:27:13 +00:00
Add filters to add default fields or tags to an event
This commit is contained in:
parent
fa73e63a3e
commit
2e5c39d5d0
@ -6,6 +6,8 @@
|
||||
# of the MIT license. See the LICENSE.txt file for details.
|
||||
|
||||
require 'rackstash/filters/clear_color'
|
||||
require 'rackstash/filters/default_fields'
|
||||
require 'rackstash/filters/default_tags'
|
||||
require 'rackstash/filters/rename'
|
||||
require 'rackstash/filters/replace'
|
||||
require 'rackstash/filters/skip_event'
|
||||
|
||||
60
lib/rackstash/filters/default_fields.rb
Normal file
60
lib/rackstash/filters/default_fields.rb
Normal file
@ -0,0 +1,60 @@
|
||||
# frozen_string_literal: true
|
||||
#
|
||||
# Copyright 2017 Holger Just
|
||||
#
|
||||
# This software may be modified and distributed under the terms
|
||||
# of the MIT license. See the LICENSE.txt file for details.
|
||||
|
||||
module Rackstash
|
||||
module Filters
|
||||
# The {DefaultFields} filter allows to define fields which should be added
|
||||
# to an event if they aren't already explicitly set.
|
||||
#
|
||||
# Fields can be given either as a `Hash` or a `Proc` which in turn returns a
|
||||
# `Hash` on `call`. The `Hash` can be nested arbitrarily deep.
|
||||
#
|
||||
# Each `Hash` value can again optionally be a `Proc` which is expected to
|
||||
# return a field value on `call`. You can set nested Hashes or Arrays and
|
||||
# define nested Procs which in turn are resolved recursively when applying
|
||||
# the filter. That way, you can set lazy-evaluated values which are only
|
||||
# resolved at the time the filter is applied to a logged event.
|
||||
#
|
||||
# @example
|
||||
# Rackstash::Flow.new(STDOUT) do
|
||||
# # All three defined filters set the same default fields
|
||||
# filter :default_fields, 'beep' => 'boop'
|
||||
# filter :default_fields, 'beep' => -> { 'boop' }
|
||||
# filter :default_fields, -> { { 'beep' => 'boop' } }
|
||||
# end
|
||||
class DefaultFields
|
||||
# @param default_fields [Hash<#to_s => Object>, Proc] a `Hash` specifying
|
||||
# default values for the named keys. You can either give a literal
|
||||
# `Hash` object or a `Proc` which returns such a `Hash`.
|
||||
def initialize(default_fields)
|
||||
@default_fields = default_fields
|
||||
end
|
||||
|
||||
# Add the defined `default_fields` to the event hash, retaining all
|
||||
# existing values.
|
||||
#
|
||||
# @param event [Hash] an event hash
|
||||
# @return [Hash] the given `event` with the fields renamed
|
||||
def call(event)
|
||||
resolver = lambda do |key, old_val, new_val|
|
||||
if old_val.nil?
|
||||
new_val
|
||||
elsif old_val.is_a?(Hash) && new_val.is_a?(Hash)
|
||||
old_val.merge(new_val, &resolver)
|
||||
elsif old_val.is_a?(Array) && new_val.is_a?(Array)
|
||||
old_val | new_val
|
||||
else
|
||||
old_val
|
||||
end
|
||||
end
|
||||
|
||||
fields = Rackstash::Fields::Hash(@default_fields).to_h
|
||||
event.merge!(fields, &resolver)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
54
lib/rackstash/filters/default_tags.rb
Normal file
54
lib/rackstash/filters/default_tags.rb
Normal file
@ -0,0 +1,54 @@
|
||||
# frozen_string_literal: true
|
||||
#
|
||||
# Copyright 2017 Holger Just
|
||||
#
|
||||
# This software may be modified and distributed under the terms
|
||||
# of the MIT license. See the LICENSE.txt file for details.
|
||||
|
||||
module Rackstash
|
||||
module Filters
|
||||
# The {DefaultTags} filter allows to define tags which should be added
|
||||
# to an event if they aren't already explicitly set there. All existing tags
|
||||
# on the event are retained.
|
||||
#
|
||||
# The default tags are added to the `"tags"` field of the event `Hash`. They
|
||||
# can be given either as an `Array` of `String`s or a `Proc` which in turn
|
||||
# returns an `Array` of `String`s on `call`.
|
||||
#
|
||||
# Each value of the Array can again optionally be a Proc which in turn is
|
||||
# expected to return a String on `call`. All the (potentially nested) procs
|
||||
# are called recursively when applying the filter. That way, you can set
|
||||
# lazy-evaluated values which are only resolved at the time the filter is
|
||||
# applied to a logged event.
|
||||
#
|
||||
# @example
|
||||
# Rackstash::Flow.new(STDOUT) do
|
||||
# # All three defined filters set the same default tags
|
||||
# filter :default_tags, ['important', 'request']
|
||||
# filter :default_tags, -> { ['important', 'request'] }
|
||||
# filter :default_tags, ['important', -> { 'request' }]
|
||||
# end
|
||||
class DefaultTags
|
||||
# @param default_tags [Array<#to_s>, Set<#to_s>, Proc] an `Array`
|
||||
# specifying default tags for each event. You can either give a literal
|
||||
# `Array` containing Strings or a `Proc` which returns such an `Array`.
|
||||
def initialize(*default_tags)
|
||||
@default_tags = default_tags
|
||||
end
|
||||
|
||||
# Add the defined `default_tags` to the event hash, retaining all
|
||||
# existing tags. The `"tags"` field on the event will be normalized to a
|
||||
# plain `Array` containing only `String`s.
|
||||
#
|
||||
# @param event [Hash] an event hash
|
||||
# @return [Hash] the given `event` with the fields renamed
|
||||
def call(event)
|
||||
tags = Rackstash::Fields::Tags(event[FIELD_TAGS])
|
||||
tags.merge!(@default_tags)
|
||||
|
||||
event[FIELD_TAGS] = tags.to_a
|
||||
event
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
67
spec/rackstash/filters/default_fields_spec.rb
Normal file
67
spec/rackstash/filters/default_fields_spec.rb
Normal file
@ -0,0 +1,67 @@
|
||||
# frozen_string_literal: true
|
||||
#
|
||||
# Copyright 2017 Holger Just
|
||||
#
|
||||
# This software may be modified and distributed under the terms
|
||||
# of the MIT license. See the LICENSE.txt file for details.
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rackstash/filters/default_fields'
|
||||
|
||||
describe Rackstash::Filters::DefaultFields do
|
||||
let(:event) {
|
||||
{
|
||||
'foo' => 'v1',
|
||||
'bar' => 'v2'
|
||||
}
|
||||
}
|
||||
|
||||
def filter!(default_fields)
|
||||
described_class.new(default_fields).call(event)
|
||||
end
|
||||
|
||||
it 'adds missing normalized fields' do
|
||||
filter! 'new' => 'boing', 123 => :number
|
||||
|
||||
expect(event).to eql({
|
||||
'foo' => 'v1',
|
||||
'bar' => 'v2',
|
||||
'new' => 'boing',
|
||||
'123' => 'number'
|
||||
})
|
||||
end
|
||||
|
||||
it 'retains existing fields' do
|
||||
filter! foo: 'ignored'
|
||||
|
||||
expect(event).to eql({
|
||||
'foo' => 'v1',
|
||||
'bar' => 'v2'
|
||||
})
|
||||
end
|
||||
|
||||
it 'deep_merges fields' do
|
||||
event['deep'] = { 'key' => [42, { 'foo' => 'bar' }, nil], 'new' => nil }
|
||||
filter! 'deep' => { key: [123], new: 'new' }
|
||||
|
||||
expect(event).to eql({
|
||||
'foo' => 'v1',
|
||||
'bar' => 'v2',
|
||||
'deep' => {
|
||||
'key' => [42, { 'foo' => 'bar' }, nil, 123],
|
||||
'new' => 'new'
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
it 'resolves Procs' do
|
||||
filter! -> { { 'beep' => -> { 'boop' } } }
|
||||
|
||||
expect(event).to eql({
|
||||
'foo' => 'v1',
|
||||
'bar' => 'v2',
|
||||
'beep' => 'boop'
|
||||
})
|
||||
end
|
||||
end
|
||||
47
spec/rackstash/filters/default_tags_spec.rb
Normal file
47
spec/rackstash/filters/default_tags_spec.rb
Normal file
@ -0,0 +1,47 @@
|
||||
# frozen_string_literal: true
|
||||
#
|
||||
# Copyright 2017 Holger Just
|
||||
#
|
||||
# This software may be modified and distributed under the terms
|
||||
# of the MIT license. See the LICENSE.txt file for details.
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rackstash/filters/default_tags'
|
||||
|
||||
describe Rackstash::Filters::DefaultTags do
|
||||
let(:event) {
|
||||
{
|
||||
'key' => 'value'
|
||||
}
|
||||
}
|
||||
|
||||
def filter!(*default_tags)
|
||||
described_class.new(*default_tags).call(event)
|
||||
end
|
||||
|
||||
it 'adds missing tags' do
|
||||
filter! 'foo', 'bar'
|
||||
expect(event['tags']).to eql ['foo', 'bar']
|
||||
end
|
||||
|
||||
it 'retains existing tags' do
|
||||
event['tags'] = ['tag']
|
||||
filter! 'foo', 'bar'
|
||||
|
||||
expect(event['tags']).to eql ['tag', 'foo', 'bar']
|
||||
end
|
||||
|
||||
it 'flattens and normalizes tags' do
|
||||
event['tags'] = 'bare'
|
||||
filter! [:foo, [[123]]]
|
||||
|
||||
expect(event['tags']).to eql ['bare', 'foo', '123']
|
||||
end
|
||||
|
||||
it 'resolves Procs' do
|
||||
filter! -> { ['beep', -> { ['boop'] }] }
|
||||
|
||||
expect(event['tags']).to eql ['beep', 'boop']
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user