How to use Logbook handler?

I have a flask app and I'm using ElasticAPM to monitor it. There is only an example of LoggingHandler
and no example of Logbook handler on the page: https://www.elastic.co/guide/en/apm/agent/python/current/flask-support.html

So I use as follows:

    handler = LogbookHandler(client=apm.client)

    app.logger.addHandler(handler)

And

    app.logger.info('App created with `{}` config'.format(app.config['CONFIG_NAME']))

Gave me an error:

  File "/Users/frederic/.virtualenvs/everyclass-server-jMUaPnUb/lib/python3.6/site-packages/elasticapm/handlers/logbook.py", line 56, in emit
    if record.channel.startswith("elasticapm.errors"):
AttributeError: 'LogRecord' object has no attribute 'channel'

So what's the right way to use Elastic APM LogbookHandler?

Hi @fr0der1c

if you use logbook, you can't use app.logger, as that is a logging.Logger instance. Instead, you have to create a logbook.Logger and use that instead. Also, you need to bind the handler. Something like this should work:

handler = LogbookHandler(client=apm.client)
log = logbook.Logger(__name__)

@app.route('/foo/bar')
def foo():
    log.warning("It's foo!")

if __name__ == '__main__':
    with handler.applicationbound():
        app.run(port=5000)

Thank you! It works!
However I found a new problem. Sometimes the log item is just an info, not an error. But the handler recorded it with stacktrace like it was an error, which I think is unnecessary. Can I disable sending stacktrace?

At the moment, you can only disable capturing of stack traces for Logbook logs globally, using the auto_log_stacks config option.

For the stdlib logger, we have the option of disabling it per call, by passing stack=False to the log call. I'll add that option for Logbook as well and ping you here once it is out (hopefully today) :slight_smile:

OK. Thank you!

I'm actually not very familiar with Logbook. I thought traceback is part of exc_info, so setting exc_info to False when logging would disable stack traces.

logger.info('App created with `{}` config'.format(app.config['CONFIG_NAME']), exc_info=False)

But changing this option is not helping. Could you please tell me why it's not working?

exc_info is something slightly different. It's the exception info if you are currently in an exception handler. Imagine this case:

try:
    do_something_dangerous()
    log.info("I did something dangerous, and it worked!") # 1
except SomethingBadHappened:
    log.error("I did something dangerous, and it blew up!") # 2

In the #1 log statement, exc_info will be empty, as there is no exception. But we will still gather a stack trace so you can see where exactly the log.info() call happened.

In the #2 log statement, we actually capture two stack traces: one from where the exception was raised (2nd line in the example), and one from where log.error() is called.

I just released version 3.0.1 of the agent, which supports the stack=False flag for Logbook. So something like this

log.info("Nothing to see here", stack=False)

won't capture any stack trace anymore

Why two stack traces are captured instead of one in the #2 log statement? I thought exception in 2nd line is handled so it won't be captured.

My another question is, since we already have LogStash, why we need to use logging feature from APM? I'm also currently using Sentry in my application for better error tracking. I want to get things less complicated, so I'm thinking about using a single Logbook logger with a SentryHandler from Sentry, and one handler between APM and LogStash. So I want to know how they differ from each other.

Sorry for the delayed answer @fr0der1c.

In a log call in an exception handler, we capture the exception stack trace even if it is handled, as it may contain valuable information.

As for whether you should use the APM agent as opposed to Logstash or Filebeat for getting your logs into Elasticsearch, this is something I'd decide on a case-by-case basis, depending if you need all the additional information we capture, like the stack trace. If all you need is the information that is already in the log line, using Logstash and Filebeat sounds like a great choice!

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.