Does anyone know of a way to test whether or not a log event actually
made it into the log?
We want to make sure that some of our important events (eg "user x was
archived by user y") actually make it into the log.
but AFAICS there's no way to get information back *out* of logger -
it's input-only.
I could hook up something ugly by setting up a fake logger and
checking if it's empty after running a block of code... but I was
hoping for something more elegent.
Any clues?
Anyone done this before?
Anyone think it's a stupid idea (and willing to share why)?
> I could hook up something ugly by setting up a fake logger and > checking if it's empty after running a block of code... but I was > hoping for something more elegent.
This is classically how you automatically test external services (see action mailer tests, see activemessaging tests)
> Does anyone know of a way to test whether or not a log event actually > made it into the log? > We want to make sure that some of our important events (eg "user x was > archived by user y") actually make it into the log.
> but AFAICS there's no way to get information back *out* of logger - > it's input-only.
> I could hook up something ugly by setting up a fake logger and > checking if it's empty after running a block of code... but I was > hoping for something more elegent.
> Any clues? > Anyone done this before? > Anyone think it's a stupid idea (and willing to share why)?
Ya - done it with ActionMailer - but that seems less ugly because you
can actually access data *from* ActionMailer. For Logger I'd have to
set up a temporary logger file, then use some sort of dodgy system
calls to manually go through the file to figureout the strings in
it. :P
This feels ugly to me.
I'd much prefer to be able to do something like
assert_equal my_msg, logger.last_message
;)
On Mar 4, 3:41 pm, Xavier Shay <xavier-l...@rhnh.net> wrote:
> > I could hook up something ugly by setting up a fake logger and
> > checking if it's empty after running a block of code... but I was
> > hoping for something more elegent.
> This is classically how you automatically test external services (see
> action mailer tests, see activemessaging tests)
On Tue, Mar 4, 2008 at 3:37 PM, taryn <googleGro...@taryneast.org> wrote:
> Does anyone know of a way to test whether or not a log event actually > made it into the log? > We want to make sure that some of our important events (eg "user x was > archived by user y") actually make it into the log.
> but AFAICS there's no way to get information back *out* of logger - > it's input-only.
I've written a rails log parser, but its crude and only reads logs from a fairly specific version of rails.
What I've done in the past is have a separate log (I called it an audit log). The output was tab delimited and in a machine readable format, with fields like time of event in epoch seconds the component (maybe UsersController) an event label (maybe user_archived) then some event specific parameters (user x, user y, etc)
Then reading the logs back later for analysis or, say auditing is very easy
I'd unit test and implement it as its own specific class. From the components which use it, mock up your audit logger's interface
You could implement it as a singleton:
class Audit def self.log(event,*args) ... end end
call it in your code like
Audit.log(:user_archived,user_x.id,user_y.id)
would that work?
> I could hook up something ugly by setting up a fake logger and > checking if it's empty after running a block of code... but I was > hoping for something more elegent.
> Any clues? > Anyone done this before? > Anyone think it's a stupid idea (and willing to share why)?
I'm sure you could create some sort of observer on the class that the logger object is instantiated from and assert that it is sent a method call for info or error(which ever one your calling).
> On Mar 4, 3:42 pm, Cameron Barrie <pho...@mvpaustralia.com.au> wrote: >> Could you check if the logger.class was sent a method such as info or >> error?
> Does anyone know of a way to test whether or not a log event actually > made it into the log? > We want to make sure that some of our important events (eg "user x was > archived by user y") actually make it into the log.
If you're using rspec, you can grab my Not A Mock plugin and use call recording to track calls to the logger, something like:
it "should log correctly" do RAILS_DEFAULT_LOGGER.track_method(:info) # Run your test RAILS_DEFAULT_LOGGER.should have_received(:info).with(...) end
> I'm sure you could create some sort of observer on the class that the > logger object is instantiated from and assert that it is sent a > method call for info or error(which ever one your calling).
Yeah, if you want to test the normal logger, use a mock
> > On Mar 4, 3:42 pm, Cameron Barrie <pho...@mvpaustralia.com.au> wrote: > >> Could you check if the logger.class was sent a method such as info or > >> error?
Interesting idea. So basically have a generic log and an "event log"
for important, auditable events. Cool... and I'd write my own accessor
methods for the latest methods - which would require keeping around
the last few messages, or whatever.
Cool idea, but sadly not a quick-to-implement one ;)
More of a long-term solution - which I assume will not make it past
the PM. :(
But I'll put t to him anyway.
On Mar 4, 3:50 pm, Cameron Barrie <pho...@mvpaustralia.com.au> wrote:
> I'm sure you could create some sort of observer on the class that the
> logger object is instantiated from and assert that it is sent a
> method call for info or error(which ever one your calling).
This sounds like a good idea for the current system. I'll have a look
into observers - of which I have only passing aquaintence through the
user notifier ;)
On Mon, Mar 03, 2008 at 08:46:45PM -0800, taryn wrote:
> On Mar 4, 3:42 pm, Cameron Barrie <pho...@mvpaustralia.com.au> wrote: > > Could you check if the logger.class was sent a method such as info or > > error?
> Not sure how I'd do that. Do you know?
Mock objects.
require 'mocha'
class MockLogTest < Test::Unit::TestCase def test_will_pass RAILS_DEFAULT_LOGGER.expects(:info).at_least_once.with("something funny") RAILS_DEFAULT_LOGGER.info("something funny") end
def test_will_fail RAILS_DEFAULT_LOGGER.expects(:info).at_least_once.with("something funny") RAILS_DEFAULT_LOGGER.info("something else") end end