views:

51

answers:

2

I am working on a Pylons app that runs on top of Apache with mod_wsgi. I would like to send logging messages that my app generates to files in my app's directory, instead of to Apache's logs. Further, I would like to specify the location of logfiles via a relative path so that it'll be easier to deploy my app on other people's servers. Right now I can log to files, but only via a fragile absolute path.

Here is the relevant part of my development.ini file:

# Logging configuration
[loggers]
keys = root, routes, myapp, sqlalchemy, debugging-logger

[handlers]
keys = console, debugging-logger-file

[formatters]
keys = generic

[logger_debugging-logger]
level = DEBUG
handlers = debugging-logger-file
qualname = myapp.controllers.logging-test-controller.debugging-logger

[handler_debugging-logger-file]
class = FileHandler
args = ('/var/pylons/myapp/logs/myapp-debugging-errors.log', 'a')
level = DEBUG
formatter = generic

Although the .ini helpfully advises using %(here)s to refer to the current path, using %(here)s in the "args = ('foo')" line of the error handler does not behave the way that I expect it to. The syntax of this ini file is documented on the Paste Deploy site, but does not specify how %(here)s can be used in relation to quoted strings.

What syntax should I use in the "args = ('foo')" line to specify the current path?

A: 

Configuration files for Paste Deploy allow a 'here' tag to indicate directory where configuration file is. You can then work relative to that.

Graham Dumpleton
I have updated the question with a clarification in response to your answer.
Sean M
+1  A: 

The problem is that Paste Deploy creates one ConfigParser object to store the 'here' tag in it's set of defaults, and logging.config.fileConfig() is never passed that set of defaults. Therefore, when fileConfig() reads the .ini file, it doesn't have access to the 'here' tag, and the ConfigParser's interpolation can't find it.

You could do something like this:

[DEFAULT]
my_log_dir = '/var/pylons/myapp/logs'
...
[handler_debugging-logger-file]
args = (%(my_log_dir)s + '/myapp-debugging-errors.log', 'a')

Not exactly what you're looking for, but a tiny bit more configurable.

Another possibility is:

args = (os.getcwd() + '/myapp-debugging-errors.log', 'a')

(This works because 'os' is a valid variable in the logging module's namespace when it calls eval() on the args value. But this is an implementation detail of the logging package that may not be reliable long term.) But this most likely won't give you what you want-- it will most likely use the Apache process's working directory.

You could even set an environment variable outside the program, and use it like:

args = (os.environ['MY_LOG_DIR'] + '/myapp-debugging-errors.log', 'a')

And yet another possibility is overriding the behavior of some of the functions or class methods in the logging module or paste package.

Hope those give you some ideas.

ma3
Ah, that got me over the brain-work hump. Thank you. I'm using the first option for now - it at least stops me from being egregiously non-DRY, because I'm splitting messages into a few different log files.
Sean M