Direct Notify Output

In my game, I have a logger setup.

from panda3d.core import loadPrcFileData
import sys
import time

log = time.strftime('test-%m%d%y_%H%M%S.log')
sys.stdout = open(log, 'w')
sys.stderr = open(log, 'w')
loadPrcFileData('notify-output', log)

Using this, I get regular python print in my file and any errors, but nothing from direct notify. I’ve tried using info and warning but nothing happens. Any suggestions?

The problem is that DirectNotify (and the lower-level C++ notify system) read the output filename at the very startup of the application, that is when you import panda3d.core, so by the time you have run loadPrcFileData() it is too late to change it.

One solution would be to put the notify-output command in an external prc file, which is always read at application start. This doesn’t help if you want to generate a dynamic filename as you are doing here, though.

So, another solution is to use the low-level calls to specifically redirect the notify systems to your log file, instead of going through the prc system, like this:

fs = pofstream()
Notify.ptr().setOstreamPtr(fs, False)
base.notify.__class__.streamWriter = StreamWriter(Notify.out(), False)


Got it working :slight_smile:
It sures looks ugly for coding, but it works.

Do you suggest I should start my program like this?

from direct.showbase.ShowBase import ShowBase
class MyApp(ShowBase):
    def __init__(self):
app = MyApp()

One more question. How would I do real-time logging instead of having to close out the window for all of my log information to be in the log file?

Edit: I lied. It doesn’t work completely. My custom errors will appear, but info will not show up. In my config.prc, I already have set notify-level to info.

That seems like a fine template for beginning a program.

Not sure what you mean when you say you can’t get the info output to appear. Can you show a code sample?


I’m really off-topic, but I’ve been working on this and I need help :imp:

from panda3d.core import pofstream, Filename, Notify, StreamWriter
from sys import stdout, stderr
from time import strftime

class TheLog:
    def __init__(self):
        log = strftime('test-%m%d%y_%H%M%S.log')
        stdout = open(log, 'w')
        stderr = open(log, 'w')
        fs = pofstream()
        Notify.ptr().setOstreamPtr(fs, False)

    def um(self):
        base.notify.__class__.streamWriter = StreamWriter(Notify.out(), False)

def run():
    global TheLog
    TheLog = TheLog()

In another part of my code, I’ll do something like

from testclass import testlogger

And all I get is an instant ppython.exe has stopped working from Windows.

You are naming your variable “TheLog” the same as your class “TheLog”. This is probably not a good thing.

For what it’s worth, you’re also not calling um().

I know, that’s because the first part would be called before base = ShowBase.ShowBase(), and then afterwards um() would be called otherwise it gets mad at me saying base doesn’t exist.
I just didn’t include that in the code.

And David, let me show you what I mean when I can’t get the info to appear.

In my config.prc I have notify-level set to info.
Then in my code, I’ll have this.

from direct.directnotify import DirectNotifyGlobal
notify = DirectNotifyGlobal.directNotify.newCategory('NotifyTest')
notify.warning('Hi! I show in the log file.')'Hi :( I don\'t show in the log file, not even in the console.')

Are you sure that you have notify-level set to info in your Config.prc file? Maybe it’s reading a different Config.prc file than the one you think, or something like that. Try:

from panda3d.core import *
print ConfigVariableString('notify-level')
print ConfigPageManager.getGlobalPtr()


Yes, it is reading my custom Config.prc, as there is the window title I set, along with the icon, graphics pipe, audio library, etc. But here’s the weird thing. I use the code that you provided, and this is what I got in the console.

(The … is just for privacy, normally there would be my name and the directory.)

So yeah, it’s reading that my notify-level is set to info. But then after that, the default one in the Panda3D directory shows up. I wonder if that’s modifying it. I’ll try changing it and see what happens.

I didn’t have default-directnotify-level in my config. Whoops.
I’m still having issues with logging, but that’s for later I suppose.