I have been implementing a similar feature in quite a few of the stacks I've been setting up, and it'd be nice to have a standard in the spec.
I would prefer we take the duck typing approach to the entry rather than the type restraint, as long as the object supports the 5 methods (and possibly #level for introspective purposes) it would be a valid rack.logger value.
We should require servers to set a default logger so its *always*
available. Then Rails or other middleware down the stack can swap it
out with something else.
--
Joshua Peek
I would argue against a formal logger being required, but generating a default of a wrapper around rack.error seems sufficient enough a default.
--
stadik.net
Thats a good idea.
I just want something to be in rack.logger so we don't have to nil
check and you can count on your message going somewhere.
--
Joshua Peek
I would argue against a formal logger being required, but generating a default of a wrapper around rack.error seems sufficient enough a default.
--
stadik.netOn Jul 27, 2009 1:07 PM, "Joshua Peek" <jo...@joshpeek.com> wrote:
+1
We should require servers to set a default logger so its *always*
available. Then Rails or other middleware down the stack can swap it
out with something else.
--
Joshua Peek
+1, For 1.1
--
Christian Neukirchen <chneuk...@gmail.com> http://chneukirchen.org
>
> Joshua Peek <jo...@joshpeek.com> writes:
>
>> On Mon, Jul 27, 2009 at 4:27 PM, Scytrin dai Kinthra<scy...@gmail.com
>> > wrote:
>>> I would argue against a formal logger being required, but
>>> generating a
>>> default of a wrapper around rack.error seems sufficient enough a
>>> default.
>>
>> Thats a good idea.
>>
>> I just want something to be in rack.logger so we don't have to nil
>> check and you can count on your message going somewhere.
+1, however, I would request please that some form of Null / No-Op
logger is available in core for profile testing (IO sucks).
The 'deferred' spec I find harder to agree with off the bat, as I
think it needs to be registered somewhere in the stack, or heavily
coupled.
I have some questions, as a result (particularly to Yehuda):
* Who implements the scheduling?
* Who implements the running?
* When is it run? (as per some spec definition)
* Does it have to be the same process?
I'd envisage something along the lines of:
l = Rack::SyncLogger.new
l.info { .. happens immediately .. }
l = Merb::Logger.new
l.info { .. happens after the request .. }
l = Rack::NullLogger.new
l.info { .. happens immediately or after request ? .. }
l = Rack::Logger.new # default?
l.info { .. happens when? .. }
Maybe some deferred logging middleware, but rack doesn't really have
this notion of "when done".
I could also be barking up the wrong tree, or maybe declarative is the
answer?
l = Merb::Logger.new
l.schedule { |item| Merb.after_response(item) }
?
Passing a block is a way of avoiding evaluating the argument when the
log level is higher, not a means to defer the logging itself.
I'd leave this "when is the block actually called?" behavior undefined.
jeremy
Who generates the default wrapper?
And if a middleware alters rack.errors, the default wrapper may break.
This is error prone.
jeremy
A little pushback: I dislike the trend of requiring more from the
environment for convenience. It's nice to rely on for a framework, but
it makes ad-hoc usage painful without an extra tool like MockRequest.
Having to tack on a superfluous { 'rack.input' => StringIO.new } was
bad enough. I feel like we're robbing Rack of some of its agility.
jeremy
> I feel like we're robbing Rack of some of its agility.
A valid point that deserves more thought.
Sorry, I was obviously mislead by the use of the term 'defer' in the OP.
> I'd leave this "when is the block actually called?" behavior
> undefined.
Defined by the logger itself then? That seems reasonable, as long as
there is some reasonable level of consistency in the implementations.