How can a log of the crash of a Python script running on Windows be generated? A python program mysteriously crashes every few hours and the application window is closed so there is not sign of the error messages from the crash.
On Linux we can do python script.py >> /logdir/script.py.log 2>&1. What about on Windows?
The script running is basically an infinite loop:
while True:
if ...
...
else:
....
how about
logger = logging.getLogger("myApplication")
while True:
try:
if ...
...
else:
....
except Exception:
logger.exception("???")
and setup logging to log to a file?
Then, even if there is an exception, the program can keep going. If it truly is a crash that can't be caught as an exception, you should put logging statements in your program so you can see what happened successfully before the crash.
Related
I have this code example:
import time
from datetime import datetime
def log_info(message: str):
with open('somefile.log', 'a') as file:
file.write(f'{datetime.now()}: {message}\n')
try:
log_info('Process started')
time.sleep(1000) # to simulate long running...
finally:
log_info('Process ended')
When I run the code in PyCharm (even in debug mode with breakpoints) or just in console/terminal and after some time I stop the running, the message "Process ended" is still written to the file. This behavior is correct.
However if I create a task in Windows Task Scheduler, I run the task and stop it (through the Task Scheduler), the "Process ended" message is not logged.
How to fix it?
By stopping your program via Task Scheduler, the Python interpreter is unexpectedly stopping, and cannot reach the finally block. The finally block only applies when your program is able to run without unexpectedly stopping.
try:
some code here
except Exception as e:
print("error: ",e)
here if this python exe code produces an exception it immediately closes the exe terminal
how do I stop it from exiting the exe terminal so that I can understand what exception exactly occurred
also I cant run it in CMD I have to run the exe file only
also I cant use the press any key method
The terminal closes when the program terminates. When you catch the exception, you print your error message, and then the program terminate, so you don't really gain much from catching the exception; in fact, you even get less (you don't print the stack trace).
To get the stacktrace, look into traceback:
try:
foo = 123 / 0
except Exception as e:
traceback.print_exception(e)
Then you need to have the program wait a bit that you can actually see the stack trace and error you print. A simple way is to just wait for input:
try:
foo = 123 / 0
except Exception as e:
traceback.print_exception(e)
wait_for_it = input('Press enter to close the terminal window')
Or you could add a break point to have the Python debugger pdb come up. (It does at least on Mac OS when I run this code in a terminal, no idea about Windows.) See the above link for help on it, or type help at its prompt.
try:
foo = 123 / 0
except Exception as e:
breakpoint()
Speaking of terminal: if you just open a command prompt or bash terminal, you can just run your code with python3 myprog.py and that terminal does not automatically close, so that you can see the output without modifying the program. Depending on how you run your code and what module dependencies you have, this may need a bit more setup (like a virtual environment) but is probably worth it in the long run.
I have a script started with nohup python3 script.py & . It looks something like this:
import thing
import anotherthing
logfile = "logfile {}".format(datetime.datetime.today())
while True:
try:
logging.debug("Started loop.")
do_some_stuff()
logging.debug("Stuff was done.")
except Exception as e:
logging.exception("message")
logging.debug("Starting sleep.")
time.sleep(60)
This works fine, however it seems to hang up on time.sleep() (as in it just stops doing anything without killing the process) after about 2 days. According to logs, all parts of the script execute fine, but it always hangs up on the sleep part and doesn't start back. I checked for memory leaks, i/o hangups and connection timeouts, and none of those seem to be the case.
What could be the cause of that behavior and why?
EDIT: Added logging to pinpoint the cause. Logs always finish on DEBUG Starting Sleep.
I have written a programme by python which is successfully tested under eclipse.Then I used pyinstaller to excute it as a .exe file. When the programme raise the exception ,the cmd window will quit immediately. I want to stay in this window to take a good look at this exception. How can I do it ? Thank you.
As Ms Turdy mentioned, you should run it in a command prompt or terminal first, if it will have the same behavior as the exe.
You can execute a python script with python -m pdb script.py and it will enter into the debugger. You run it by pressing C for continue, then it will break when it raises the exception.
That is because the python script has finished its job. You can do this:
import time
# your code
...
time.sleep(20)
This will give you 20 seconds to see the result. And after 20 s, the cmd window will remain 20 s for you to see the result. You can change the time for your requirement.
You can try raw_input to hold the screen:
import traceback
try:
# do something dangerous
except Exception, e:
print 'Error:', e
print traceback.format_exc()
raw_input('Input anything to end...')
I have a python script running like this on my server:
python script.py &
The script works fine, but constantly I'm adding new things to the script and re-running it, somedays it runs for days without any problem, but sometimes the script stops running (Not running out of memory), but since I started the script as background I have no idea how to check for the Exception or error that cause the script to stop running. I'm on a Ubuntu server box running in Amazon. Any advice on how to approach this inconvenience ?
I use something like this. It will dump the exception which caused termination to your syslog, which you can see by examining /var/log/syslog after your script has stopped.
import traceback
import syslog
def syslog_trace(trace):
'''Log a python stack trace to syslog'''
log_lines = trace.split('\n')
for line in log_lines:
if len(line):
syslog.syslog(line)
def main():
# Your actual program here
if __name__ == '__main__':
try:
main()
except:
syslog_trace(traceback.format_exc())