mirror of
https://github.com/meineerde/rackstash.git
synced 2026-01-31 17:27:13 +00:00
Set rack.errors in the Rack::Middlware
This ensures that other middlewares whi want to log to the default rack.errors stream will log to a sensible location instead of the usual default of raw STDOUT or STDERR.
This commit is contained in:
parent
3b8e76329c
commit
26597680af
66
lib/rackstash/rack/errors.rb
Normal file
66
lib/rackstash/rack/errors.rb
Normal file
@ -0,0 +1,66 @@
|
||||
# frozen_string_literal: true
|
||||
# Copyright 2016 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 Rack
|
||||
# Provide an error stream to Rack applications which logs to a
|
||||
# {Rackstash::Logger} instance.
|
||||
#
|
||||
# According to the [Rack SPEC](http://www.rubydoc.info/github/rack/rack/file/SPEC#The_Error_Stream),
|
||||
# the error stream in `env['rack.errors']` must coform to the following
|
||||
# interface:
|
||||
#
|
||||
# > The error stream must respond to `puts`, `write` and `flush`.
|
||||
# >
|
||||
# > * `puts` must be called with a single argument that responds to `to_s`.
|
||||
# > * `write` must be called with a single argument that is a `String`.
|
||||
# > * `flush` must be called without arguments and must be called in order
|
||||
# > to make the error appear for sure.
|
||||
# > * `close` must never be called on the error stream.
|
||||
class Errors
|
||||
# @return [Rackstash::Logger]
|
||||
attr_reader :logger
|
||||
|
||||
# @param logger [Rackstash::Logger] a {Logger} instance to write error
|
||||
# logs to
|
||||
def initialize(logger)
|
||||
@logger = logger
|
||||
end
|
||||
|
||||
# Log a formatted error message to the current buffer of the `logger`. We
|
||||
# will format the given message and log it with an `UNKNOWN` severity to
|
||||
# the current buffer. Usually, the logger's formatter adds a trailing
|
||||
# newline to the message.
|
||||
#
|
||||
# @param msg [#to_s] a message to write to the error stream
|
||||
# @return [String] the given `msg` as a String
|
||||
def puts(msg)
|
||||
msg = msg.to_s
|
||||
@logger.unknown(msg)
|
||||
msg
|
||||
end
|
||||
|
||||
# Log a raw and unformatted error message to the current buffer of the
|
||||
# `logger`. It will be logged as an unformatted {Message} without any
|
||||
# aded newline characters.
|
||||
#
|
||||
# @param msg [String] a raw message to write to the error stream
|
||||
# @return [String] the given `msg`
|
||||
def write(msg)
|
||||
@logger << msg
|
||||
msg
|
||||
end
|
||||
|
||||
# This method does nothing. It is only provided to satisfy the
|
||||
# requirements of the error stream interface. The {Logger} (resp. its
|
||||
# adapters) are responsible to flush their buffers on their own as
|
||||
# suitable or required.
|
||||
def flush
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -7,6 +7,7 @@
|
||||
require 'rack'
|
||||
|
||||
require 'rackstash/helpers/time'
|
||||
require 'rackstash/rack/errors'
|
||||
|
||||
module Rackstash
|
||||
module Rack
|
||||
@ -199,6 +200,7 @@ module Rackstash
|
||||
began_at = clock_time
|
||||
env['rackstash.logger'.freeze] = @logger
|
||||
env['rack.logger'.freeze] = @logger
|
||||
env['rack.errors'.freeze] = Rackstash::Rack::Errors.new(@logger)
|
||||
|
||||
@logger.push_buffer(buffering: @buffering, allow_silent: true)
|
||||
begin
|
||||
|
||||
56
spec/rackstash/rack/errors_spec.rb
Normal file
56
spec/rackstash/rack/errors_spec.rb
Normal file
@ -0,0 +1,56 @@
|
||||
# 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/rack/errors'
|
||||
|
||||
describe Rackstash::Rack::Errors do
|
||||
let(:logger) { instance_double(Rackstash::Logger) }
|
||||
let(:errors) { described_class.new(logger) }
|
||||
|
||||
describe '#initialize' do
|
||||
it 'takes a logger' do
|
||||
errors = described_class.new(logger)
|
||||
expect(errors.logger).to equal logger
|
||||
end
|
||||
end
|
||||
|
||||
describe '#puts' do
|
||||
it 'logs a formatted message' do
|
||||
expect(logger).to receive(:unknown).with('an error')
|
||||
errors.puts('an error')
|
||||
end
|
||||
|
||||
it 'returns the stringified message' do
|
||||
allow(logger).to receive(:unknown)
|
||||
|
||||
expect(errors.puts('error')).to eql 'error'
|
||||
expect(errors.puts(123)).to eql '123'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#write' do
|
||||
it 'logs an unformatted message' do
|
||||
expect(logger).to receive(:<<).with('an error')
|
||||
errors.write('an error')
|
||||
end
|
||||
|
||||
it 'returns the raw message' do
|
||||
allow(logger).to receive(:<<)
|
||||
|
||||
expect(errors.write('error')).to eql 'error'
|
||||
expect(errors.write(123)).to eql 123
|
||||
end
|
||||
end
|
||||
|
||||
describe '#flush' do
|
||||
it 'does nothing' do
|
||||
errors.flush
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -92,6 +92,19 @@ describe Rackstash::Rack::Middleware do
|
||||
expect(called).to be true
|
||||
end
|
||||
|
||||
it 'sets rack.errors environment variable' do
|
||||
called = false
|
||||
app = lambda do |env|
|
||||
called = true
|
||||
expect(env['rack.errors']).to be_instance_of Rackstash::Rack::Errors
|
||||
expect(env['rack.errors'].logger).to equal logger
|
||||
[200, { 'Content-Type' => 'text/plain' }, ['Hello, World!']]
|
||||
end
|
||||
|
||||
::Rack::MockRequest.new(described_class.new(app, logger)).get('/')
|
||||
expect(called).to be true
|
||||
end
|
||||
|
||||
it 'logs basic request data' do
|
||||
get('/demo')
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user