0

Im currently logging the exceptions of a program via...

def log_message(text):
    log_file = "/var/log/logfile.txt"

    try:
        if os.path.isfile(log_file):
            mode = "a"
        else:
            mode = "w"

        with open(log_file, mode) as myfile:
            myfile.write("%s\n" % (text))

        return True

    except Exception as e:
        print "error : ",e
        return False

try:
    ... some code

except Exception as e:
        log_message("error : %s" % (e))

However im my log I get "TypeError: argument of type 'NoneType' is not iterable" Is there a way to also log the other info from the exception like below. Such as the line number the module file etc etc ?

>>> post_builder_ghost(abc).generate()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "post_builder.py", line 34, in generate
    if 'youtube' in self.video:
TypeError: argument of type 'NoneType' is not iterable
>>>

Thanks,

1
  • why don't you try logging module Commented Apr 24, 2014 at 8:01

2 Answers 2

1

To answer your question directly: look at traceback.print_exc

BUT...

You should have a look at standard logging (tutorial). Your code would become (in it's simplest form):

import logging
logging.basicConfig(stream=open("/var/log/logfile.txt", "a+"))

LOG = logging.getLogger(__name__)

try:
   ... some code
except Exception as e:
   LOG.exception("human readable explanation of what you did")

As mentioned, this is the simplest form of logging. You can got much further than this! Personally, I would advise against basicConfig. But to get you going quickly it will do just fine.

Diving into the logging config you will be able to do much more useful things, like writing debug info in one file, and error messages into another file (or stream like stderr, stdout).

It also supports what you asked, like logging module name, filename and line number, but this is disabled by default. You can enable it, by specifying your own message format (see LogRecord objects for a reference of the fields):

logging.basicConfig(stream=open("/var/log/logfile.txt", "a+"),
                    format="%(levelname)s:%(name)s:%(pathname)s:%(lineno)s:%(message)s")

The LOG.exception method I used above will include the stack trace (which is what you wanted). You have other methods (.debug, .info, .warning, .error, .critical) which will only emit the message.

As a rule of thumb, you want to configure the logging system as soon as possible in your application, but don't do it at the module level to avoid interfering with other libraries if possible. If it's a console application, "entry points" will help (or protect it with an if __name__ == '__main__' block.

After configured (either manually, or using basicConfig), you can then put this in each of your modules:

import logging
LOG = logging.getLogger(__name__)

Which will give a logger (LOG) dedicated to that module and enables you to configure logging (increase/decrease verbosity for example) per module later on (even at run-time).

Sign up to request clarification or add additional context in comments.

Comments

0

You can use traceback.format_exc.

import traceback

try:
    some code ...
except Exception:
    exp = traceback.format_exc()
    log_message("error : %s" % (exp))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.