mirror of
https://github.com/meineerde/rackstash.git
synced 2025-10-17 14:01:01 +00:00
The Rackstash::Logger class will server as the public main entry point for users. It will eventually implement the mostly complete interface of Ruby's Logger. The idea of Rackstash is the we will allow to buffer multiple log messages allong with additional data until a combined log event is eventually flushed to an underlying log target. This allows to keep connected log messages and data as a single unit from the start without having to painstakingly parse and connect these in later systems again.
220 lines
7.0 KiB
Ruby
220 lines
7.0 KiB
Ruby
# 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/logger'
|
|
|
|
describe Rackstash::Logger do
|
|
let(:targets) { double('targets') }
|
|
let(:logger) { Rackstash::Logger.new(targets) }
|
|
|
|
describe '#formatter' do
|
|
it 'defaults to a Rackstash::Formatter' do
|
|
expect(logger.formatter).to be_a Rackstash::Formatter
|
|
end
|
|
|
|
it 'allows to set a custom formatter' do
|
|
formatter = ->(_severity, _time, _progname, msg) { msg.reverse }
|
|
logger.formatter = formatter
|
|
expect(logger.formatter).to equal formatter
|
|
end
|
|
end
|
|
|
|
describe '#level' do
|
|
it 'defaults to DEBUG' do
|
|
expect(logger.level).to eql 0
|
|
end
|
|
|
|
it 'can be set as an integer' do
|
|
logger.level = 3
|
|
expect(logger.level).to eql 3
|
|
|
|
logger.level = 42
|
|
expect(logger.level).to eql 42
|
|
|
|
logger.level = -25
|
|
expect(logger.level).to eql -25
|
|
|
|
end
|
|
|
|
it 'can be set as a symbol' do
|
|
%i[debug info warn error fatal unknown].each_with_index do |level, i|
|
|
logger.level = level
|
|
expect(logger.level).to eql i
|
|
end
|
|
|
|
%i[DeBuG InFo WaRn ErRoR FaTaL UnKnOwN].each_with_index do |level, i|
|
|
logger.level = level
|
|
expect(logger.level).to eql i
|
|
end
|
|
end
|
|
|
|
it 'can be set as a string' do
|
|
%w[debug info warn error fatal unknown].each_with_index do |level, i|
|
|
logger.level = level
|
|
expect(logger.level).to eql i
|
|
end
|
|
|
|
%w[DeBuG InFo WaRn ErRoR FaTaL UnKnOwN].each_with_index do |level, i|
|
|
logger.level = level
|
|
expect(logger.level).to eql i
|
|
end
|
|
end
|
|
|
|
it 'rejects invalid values' do
|
|
expect { logger.level = 'invalid' }.to raise_error(ArgumentError)
|
|
expect { logger.level = Object.new }.to raise_error(ArgumentError)
|
|
expect { logger.level = nil }.to raise_error(ArgumentError)
|
|
expect { logger.level = false }.to raise_error(ArgumentError)
|
|
expect { logger.level = true }.to raise_error(ArgumentError)
|
|
end
|
|
end
|
|
|
|
describe '#progname' do
|
|
it 'defaults to PROGNAME' do
|
|
expect(logger.progname).to match %r{\Arackstash/v\d+(\..+)*\z}
|
|
end
|
|
|
|
it 'can be set to a custom value' do
|
|
logger.progname = 'my app'
|
|
expect(logger.progname).to eql 'my app'
|
|
end
|
|
end
|
|
|
|
describe '#sink' do
|
|
it 'returns the created sink' do
|
|
expect(logger.sink).to be_a Rackstash::Sink
|
|
end
|
|
end
|
|
|
|
describe '#add' do
|
|
let(:messages) { [] }
|
|
|
|
let(:buffer) {
|
|
double('Rackstash::Buffer').tap do |buffer|
|
|
expect(buffer).to receive(:add_message) { |message| messages << message }
|
|
.at_least(:once)
|
|
end
|
|
}
|
|
|
|
let(:buffer_stack) {
|
|
double('Rackstash::BufferStack').tap do |buffer_stack|
|
|
expect(buffer_stack).to receive(:with_buffer)
|
|
.at_least(:once)
|
|
.and_yield(buffer)
|
|
end
|
|
}
|
|
|
|
before(:each) do
|
|
class_double('Rackstash::Message').as_stubbed_const.tap do |klass|
|
|
expect(klass).to receive(:new) { |msg, **kwargs| {message: msg, **kwargs} }
|
|
.at_least(:once)
|
|
end
|
|
expect(logger).to receive(:buffer_stack)
|
|
.at_least(:once)
|
|
.and_return(buffer_stack)
|
|
end
|
|
|
|
it 'sets the current time as UTC to the message' do
|
|
logger.add(nil, 'msg')
|
|
expect(messages.last[:time]).to be_a(Time).and be_frozen.and be_utc
|
|
end
|
|
|
|
it 'sets the provided a severity' do
|
|
logger.log(Rackstash::DEBUG, 'Debug message')
|
|
expect(messages.last).to include message: 'Debug message', severity: 0
|
|
|
|
logger.log(Rackstash::INFO, 'Info message')
|
|
expect(messages.last).to include message: 'Info message', severity: 1
|
|
|
|
logger.log(Rackstash::WARN, 'Warn message')
|
|
expect(messages.last).to include message: 'Warn message', severity: 2
|
|
|
|
logger.log(Rackstash::ERROR, 'Error message')
|
|
expect(messages.last).to include message: 'Error message', severity: 3
|
|
|
|
logger.log(Rackstash::FATAL, 'Fatal message')
|
|
expect(messages.last).to include message: 'Fatal message', severity: 4
|
|
|
|
logger.log(Rackstash::UNKNOWN, 'Unknown message')
|
|
expect(messages.last).to include message: 'Unknown message', severity: 5
|
|
|
|
# Positive severities are passed along
|
|
logger.log(42, 'The answer')
|
|
expect(messages.last).to include message: 'The answer', severity: 42
|
|
|
|
# nil is changed to UNKNOWN
|
|
logger.log(nil, 'Missing')
|
|
expect(messages.last).to include message: 'Missing', severity: 5
|
|
|
|
# Non-number arguments result in an error
|
|
expect { logger.log(:debug, 'Missing') }.to raise_error(TypeError)
|
|
expect { logger.log('debug', 'Missing') }.to raise_error(ArgumentError)
|
|
end
|
|
|
|
it 'defaults to severity to UNKNOWN' do
|
|
logger.add(nil, 'test')
|
|
expect(messages.last).to include severity: 5
|
|
end
|
|
|
|
it 'calls the block if message is nil' do
|
|
temp = 0
|
|
expect do
|
|
logger.log(nil, nil, 'TestApp') do
|
|
temp = 1 + 1
|
|
end
|
|
end.to_not raise_error
|
|
expect(temp).to eql 2
|
|
end
|
|
|
|
it 'ignores the block if the message is not nil' do
|
|
temp = 0
|
|
expect do
|
|
logger.log(nil, 'not nil', 'TestApp') do
|
|
temp = 1 + 1
|
|
end
|
|
end.to_not raise_error
|
|
expect(temp).to eql 0
|
|
end
|
|
|
|
it 'follows Ruby\'s logger logic to find the message' do
|
|
# If there is a message, it will be logged
|
|
logger.add(0, 'Hello', nil)
|
|
expect(messages.last).to include message: 'Hello', severity: 0, progname: Rackstash::PROGNAME
|
|
|
|
logger.add(4, 'Hello', 'prog')
|
|
expect(messages.last).to include message: 'Hello', severity: 4, progname: 'prog'
|
|
|
|
logger.add(5, 'Hello', 'prog') { 'block' }
|
|
expect(messages.last).to include message: 'Hello', severity: 5, progname: 'prog'
|
|
|
|
logger.add(nil, 'Hello', nil)
|
|
expect(messages.last).to include message: 'Hello', severity: 5, progname: Rackstash::PROGNAME
|
|
|
|
# If there is no message, we use the block
|
|
logger.add(1, nil, 'prog') { 'Hello' }
|
|
expect(messages.last).to include message: 'Hello', severity: 1, progname: 'prog'
|
|
logger.add(1, nil, nil) { 'Hello' }
|
|
expect(messages.last).to include message: 'Hello', severity: 1, progname: Rackstash::PROGNAME
|
|
|
|
# If there is no block either, we use the progname and pass the default
|
|
# progname to the message
|
|
logger.add(2, nil, 'prog')
|
|
expect(messages.last).to include message: 'prog', severity: 2, progname: Rackstash::PROGNAME
|
|
# ... which defaults to `Rackstash::BufferedLogger::PROGNAME`
|
|
logger.add(3, nil, nil)
|
|
expect(messages.last).to include message: Rackstash::PROGNAME, severity: 3, progname: Rackstash::PROGNAME
|
|
|
|
# If we resolve the message to a blank string, we still add it
|
|
logger.add(1, '', nil) { 'Hello' }
|
|
expect(messages.last).to include message: '', severity: 1, progname: Rackstash::PROGNAME
|
|
# Same with nil which is later inspect'ed by the formatter
|
|
logger.add(0, nil, 'prog') { nil }
|
|
expect(messages.last).to include message: nil, severity: 0, progname: 'prog'
|
|
end
|
|
end
|
|
end
|