It is running under DEBUG = True mode. Sometimes it can throw out an error message with traceback information when encounter an error but sometimes it just display the following lines:
Unhandled Exception
An unhandled exception was thrown by the application.
I have to switch to development server to see detail message.
How can I make it always display traceback message when an error is encountered?
Just connect to the got_request_exception signal and log the exception:
from django.core.signals import got_request_exception
import logging
def log(*args, **kwargs):
logging.exception('error')
got_request_exception.connect(log)
This will log the whole trace. In the dev server, it logs in the console.
Maybe you can use this snippet, this will log exceptions in apache's log:
utils.py:
def log_traceback(exception, args):
import sys, traceback, logging
exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
logging.debug(exception)
logging.debug(args)
for tb in traceback.format_exception(exceptionType, exceptionValue, exceptionTraceback):
logging.debug(tb)
site_logging.py:
import logging
import sys
logger = logging.getLogger('')
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stderr)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
Put it in your settings.py :
import site_logging
And in your code:
from where.is.your.utils import log_traceback
try:
`do something`
except Exception, args:
log_traceback(Exception, args)
Are you using Apache?
Just out of interest is this your Production or Dev environment where you want to see the traceback?
From the DJango Book on security - Exposed error messages
Users deploying under Apache and mod_python should also make sure they have PythonDebug Off in their Apache conf files; this will ensure that any errors that occur before Django’s had a chance to load won’t be displayed publicly.
I assume you want PythonDebug On, this is recommended for Development only.
That's what DEBUG=True is for: to show the full traceback. The idea is that regular users do not want (nor do you want them to) see anything other than a simple error message.
Related
I am writing the below code to log messages into a file:
#!/usr/bin/python3
import logging
## init logger
logger = logging.getLogger(__name__)
## create handler file
handler = logging.FileHandler('mylog3.log')
## set log level
handler.setLevel(logging.INFO)
## add handler to logger
logger.addHandler(handler)
l = [1, 2, 3, 4]
i = 3
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.debug('This is a debug message. I=%d l=%s', i, l)
logger.error('This is an error message. l =%s', l)
logger.fatal('This is a fatal error message')
The problem I am seeing is that no matter what setting I give, it always prints the warning, error and fatal error messages in file. The debug and info messages are never written.
I verified that I am seeing the issue w/ both PyCharm on Windows and also on my Ubuntu linux Python 3. So, it must be that I am doing something wrong. What can it be? I am at a loss!
Both loggers and handlers have levels. You've set the level for the handler, but not for the logger - and that defaults to WARNING. If you do e.g. logger.setLevel(logging.DEBUG), you should see DEBUG and INFO messages as well (if you don't set a level on the handler at all) or INFO messages but not DEBUG messages (if you set the handler's level to logging.INFO).
See this diagram for more info on the information flow in logging.
The debug and info messages are not shown because of the line handler.setLevel(logging.INFO). This causes all messages of level logging.INFO or less (only info and debug) to not be shown. You can replace loggign.INFO with logging.NOTSET to fix this.
I am using wsgi server to spawn the servers for my web application. I am having problem with information logging.
This is how I am running the app
from gevent import monkey; monkey.patch_all()
from logging.handlers import RotatingFileHandler
import logging
from app import app # this imports app
# create a file to store weblogs
log = open(ERROR_LOG_FILE, 'w'); log.seek(0); log.truncate();
log.write("Web Application Log\n"); log.close();
log_handler = RotatingFileHandler(ERROR_LOG_FILE, maxBytes =1000000, backupCount=1)
formatter = logging.Formatter(
"[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s"
)
log_handler.setFormatter(formatter)
app.logger.setLevel(logging.DEBUG)
app.logger.addHandler(log_handler)
# run the application
server= wsgi.WSGIServer(('0.0.0.0', 8080), app)
server.serve_forever()
However, on running the application it is not logging anything. I guess it must be because of WSGI server because app.logger works in the absence of WSGI. How can I log information when using WSGI?
According to the gevent uwsgi documentation you need to pass your log handler object to the WSGIServer object at creation:
log – If given, an object with a write method to which request (access) logs will be written. If not given, defaults to sys.stderr. You may pass None to disable request logging. You may use a wrapper, around e.g., logging, to support objects that don’t implement a write method. (If you pass a Logger instance, or in general something that provides a log method but not a write method, such a wrapper will automatically be created and it will be logged to at the INFO level.)
error_log – If given, a file-like object with write, writelines and flush methods to which error logs will be written. If not given, defaults to sys.stderr. You may pass None to disable error logging (not recommended). You may use a wrapper, around e.g., logging, to support objects that don’t implement the proper methods. This parameter will become the value for wsgi.errors in the WSGI environment (if not already set). (As with log, wrappers for Logger instances and the like will be created automatically and logged to at the ERROR level.)
so you should be able to do wsgi.WSGIServer(('0.0.0.0', 8080), app, log=app.logger)
You can log like this -
import logging
import logging.handlers as handlers
.
.
.
logger = logging.getLogger('MainProgram')
logger.setLevel(10)
logHandler = handlers.RotatingFileHandler(filename.log,maxBytes =1000000, backupCount=1)
logger.addHandler(logHandler)
logger.info("Logging configuration done")
.
.
.
# run the application
server= wsgi.WSGIServer(('0.0.0.0', 8080), app, log=logger)
server.serve_forever()
I'm using Python 3.4 on Mac OSX. I have the following code to setup a logger:
LOGGER = logging.getLogger(PROGRAM_NAME)
LOGGER.setLevel(logging.DEBUG)
LOGGER.propagate = False
LOGGER_FH = logging.FileHandler(WORKING_DIR + "/syslog.log", 'a')
LOGGER_FH.setLevel(logging.DEBUG)
LOGGER_FH.setFormatter(logging.Formatter('%(name)s: [%(levelname)s] %(message)s'))
LOGGER.addHandler(LOGGER_FH)
LOGGER_SH = logging.handlers.SysLogHandler(address='/var/run/syslog',
facility=logging.handlers.SysLogHandler.LOG_USER)
LOGGER_SH.setLevel(logging.DEBUG)
LOGGER_SH.setFormatter(logging.Formatter('%(name)s: [%(levelname)s] %(message)s'))
LOGGER.addHandler(LOGGER_SH)
The FileHandler works perfectly, and I'm able to see all expected messages at all logging levels show up in the log. The SysLogHandler doesn't work correctly. I'm unable to see any LOGGER.info() or LOGGER.debug() messages in the syslog output. I can see error and warning messages, but not info or debug. Even tweaking the /etc/syslog.conf file has no effect (even after explicitly reloading the syslog daemon with launchctl). What am I missing here ?
Try: address='/dev/log'
It's a bit confusing from the doc, but "address" is expected to be a unix domain socket, not a file.
I have minimalistic Tornado application:
import tornado.ioloop
import tornado.web
class PingHandler(tornado.web.RequestHandler):
def get(self):
self.write("pong\n")
if __name__ == "__main__":
application = tornado.web.Application([ ("/ping", PingHandler), ])
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
Tornado keeps reporting error requests to stderr:
WARNING:tornado.access:404 GET / (127.0.0.1) 0.79ms
Question: It want to prevent it from logging error messages. How?
Tornado version 3.1; Python 2.6
Its clear that "someone" is initializing logging subsystem when we start Tornado. Here is the code from ioloop.py that reveals the mystery:
def start(self):
if not logging.getLogger().handlers:
# The IOLoop catches and logs exceptions, so it's
# important that log output be visible. However, python's
# default behavior for non-root loggers (prior to python
# 3.2) is to print an unhelpful "no handlers could be
# found" message rather than the actual log entry, so we
# must explicitly configure logging if we've made it this
# far without anything.
logging.basicConfig()
basicConfig is called and configures default stderr handler.
So to setup proper logging for tonado access, you need to:
Add a handler to tornado.access logger: logging.getLogger("tornado.access").addHandler(...)
Disable propagation for the above logger: logging.getLogger("tornado.access").propagate = False. Otherwise messages will arrive BOTH to your handler AND to stderr
The previous answer was correct, but a little incomplete. This will send everything to the NullHandler:
hn = logging.NullHandler()
hn.setLevel(logging.DEBUG)
logging.getLogger("tornado.access").addHandler(hn)
logging.getLogger("tornado.access").propagate = False
You could also quite simply (in one line) do:
logging.getLogger('tornado.access').disabled = True
try:
#do something that raises an exception...
except:
logging.error('Error Message')
I want more than just "Error Message" to show in the logs. I want to see the traceback, or at least what the exception was, in the logs as well. How do I do that?
Thanks!
logging.exception(msg[, *args])
Logs a message with level ERROR on the root logger. The arguments are interpreted as for debug(). Exception info is added to the logging message. This function should only be called from an exception handler.
http://docs.python.org/library/logging.html#logging.exception
This is what I use to log the entire stack trace:
import traceback
try:
# your code
except:
stacktrace = traceback.format_exc()
logging.error("%s", stacktrace)
I think this should help you
import logging
try:
#exception code
except Exception as e:
logging.error(e)
You can set the logging details to Debug,Info,Warning,Error or Critical and set in your application. Debug would give you a lot of details.
import logging
logging.getLogger().setLevel(logging.DEBUG)
And you can get the logs of the particular filter in your appengine web console under /logs.