I’m trying to direct all my logging to a single file, specified by me. Unfortunately, while much of my game’s output does indeed go to that file, I still seem to get some output directed to the console, and some to files named in the pattern “log.<date-and-time>”. And I’m not sure of what I’m doing wrong. :/
This is, roughly speaking, how I’m setting up logging. The code is a little more spread out than I’m depicting here, but this should give you the general idea of my approach:
In the “Common” class, which handles logging:
# An exit-handler designed to print crash-reports and the like to the log-file.
# This seems to be somewhat hit-and-miss.
if hasattr(sys, "last_traceback"):
errorList = traceback.format_exception(sys.last_type, sys.last_value, sys.last_traceback)
errorString = "".format(errorList)
# Initial setup of logging.
filename = Filename(USER_DIR + "/logfile.txt")
# Replace the file if it exists (so that it doesn't
# append every run's output one after another)
Common.nout = MultiplexStream()
# Initialisation code general to this class,
# part of which is a final bit of logging setup.
Common.notifier = DirectNotify().newCategory("GameMessages")
if Common.nout is not None:
base.notify.__class__.streamWriter = StreamWriter(Notify.out(), False)
# Other logic follows that's unrelated.
In the game’s core-class:
# A bit of code in-between...
The only thing I find odd in your code is Common.warn in your exitHandler method;
Shouldn’t that be Common.notifier.warn instead?
Apart from that I wouldn’t really know. Perhaps the order in which ShowBase is instantiated and Common.setupLogging etc. is called, but I’m just guessing here.
The reason I mention this is that I recently adopted the use of Panda’s own logging system as well, and I found out that instantiating ShowBase resets a custom severity level (through a previous call to notifier.setSeverity or setDebug etc.) to its default value.
A more complete code sample might provide more insight, ideally one that leads to the creation of the unwanted log files, but if this cannot easily be reproduced, then that is more easily said than done of course, hmmm…
Ah, sorry–I have a convenience method in my “Common” class that allows me to use the same method-call whether or not I have logging enabled. (The full game uses logging, while the level-editor and other assorted utilities just output to the console, as I recall.)
Here’s the code for that method:
if Common.notifier is not None:
As you can see, it calls “Common.notifier.warning” if “Common.notifier” has been assigned (and thus logging is enabled), and simply “prints” otherwise.
Fair enough–I appreciate the suggestions and reply nevertheless! And they may prove helpful, still.
Perhaps–it might be worth investigating.
I think that I might try to put together some sort of minimal example (perhaps tomorrow, depending on how some other bug-hunting goes)–that might help to isolate the issue.
However, a real (and actually rather obvious) mistake in that exitHandler method is in the preceding line of code: errorString = "".format(errorList).
That should of course be: errorString = "".join(errorList)
All tracebacks should now go into the log file as intended .
Aha! If I comment out Common.notifier.setLogging(True) in the initialise method, it looks like no additional log files of the form log.<date-and-time> are created anymore! That call also doesn’t seem necessary, as the logfile.txt file is still being created with the tracebacks in it.