views:

32

answers:

1

I'm writing a Django-based webapp that imports a Cocoa framework via PyObjC. The Cocoa framework has NSLog() littered all through it and while I can see them when running the Django server in non-daemon mode, as soon as I go to daemon I simply lose all this useful NSLog() output.

Is there any easy way to get NSLog stuff to bubble up into the Python logging module's world so it can be merged in with the log messages being emitted by the actual Python code?

Did a little Googling and it seems like you might have to redirect stderr and somehow suck it back into Python in order to achieve this, which would be kind of a bummer ...

Any help much appreciated.

+1  A: 

According to this page, NSLog basically works like

fprintf(stderr, format_string, args ...);

so you do need to capture / redirect the standard error output. I wrote a post some time ago which might help for Python-only programs, but I would guess that the Cocoa code accesses the process-level file descriptor 2 (stderr) under the covers. So you'll need to do some low-level fiddling around with the process' stderr. Here's an example:

old_stderr = os.dup(sys.stderr.fileno()) # keep a copy
fd = os.open('path/to/mylog', os.O_CREAT | os.O_WRONLY)
os.dup2(fd, sys.stderr.fileno())
# Now, stderr output, including NSLog output, should go to 'path/to/mylog'
...
os.dup2(old_stderr, sys.stderr.fileno())
#stderr restored to its old state

Once you have fd, you can create a file-like object out of it and pass it to StreamHandler, for example, as a means to merging the output from Python code and Cocoa code.

Vinay Sajip
Thanks for the info Vinay - I suspected as much. I'll implement it and then post my actual solution for merging it into the Python `logging` logs here once I have it working.
glenc