I am having problems logging in my Django project.
In my view.py in an "application" I am doing the following:
import logging
logging.basicConfig(filename="django.log",level=logging.DEBUG)
def request(request):
logging.debug("test debugging")
with a django.log file in the same directory as the view.py file.
Now when making a request from the browser I keep getting a 500 Internal Server error as shown in Firebug. I can get logging to work just fine when I simply run it through the interactive python shell or executing it from a .py file like the following:
import logging
logging.basicConfig(filename="django.log",level=logging.DEBUG)
def testLogging():
logging.debug("test debugging")
if __name__ == "__main__"
testLogging()
, and then executing python nameOfFile.py.
What am I doing wrong? I am running Django 1.1.1 and Python 2.6.5. Maybe I should upgrade Django?
Could it be related to permissions? I can imagine that in a web-server environment, writing to a file may be restricted. In truth, I don't know, but please check the official Django logging documentation - it uses the standard logging module, but you may have to configure it differently.
Is that your entire view? It would have been helpful to post the actual traceback, but note that a view must return an HttpResponse, even if it's an empty one. So if that is your entire view, the 500 error is probably happening because you're not returning anything.
Add return HttpResponse() to the end of that view, and if that still doesn't work, please post the traceback itself.
Related
I'm working on a system built in Pyramid and one of the views is for importing data. I'd like to make a script that will call that view. I created a console script import_data in my setup.py and that is successfully added to my bin directory. In the import_data function I think I should be using the pyramid.paste bootstrap function, but when I pass the bootstrap function my ini file bootstrap responses with '*** transaction.interfaces.NoTransaction'. I've read that in assigning the bootstrap I must also set the transaction manager but this also returned NoTransaction.
from pyramid.paster import bootstrap
def import_data():
with bootstrap(sys.argv[1]) as env:
with env['request'].tm:
# Post request to pyramid view.
If anybody could steer me in the right direction I'd very much appreciate it.
You can use prequest to run a "request" from commandline,
altenatively look at:
https://github.com/Pylons/pyramid-cookiecutter-starter/blob/latest/%7B%7Bcookiecutter.repo_name%7D%7D/%7B%7Bcookiecutter.repo_name%7D%7D/sqlalchemy_scripts/initialize_db.py#L28
For an example of a script that touches database.
I am trying to make sure that my site is properly protected from showing the details of the error in production.
I've been struggling with this for a while, as at beginning I understood that in order to avoid Django from showing the error (module, line of code, etc.) all that was needed was changing DEBUG from True to False in settings.py.
However, I realized that Django was still showing error details, so investigating a bit more and I came to know that the following was also needed:
TEMPLATE_DEBUG = DEBUG in settings.py
404.html and 500.htmlinside the templates folder
Is there anything else needed to make sure that the user does not get those messages?
And how does Django deal with the other kind of errors, like 400? I saw here that there are handlers for 400 and 403, but I do not understand it and I don't know if they are needed at all for a basic using case.
If DEBUG is False, Django doesn't show error details to the user. If it did in your case, the most likely explanations are either that it's not using the settings.py file you think it's using (in which case you should check the Python path, the directory from which you run manage.py, and the value of DJANGO_SETTINGS_MODULE), or that you did not restart Gunicorn/uWSGI/Apache after you made the change to settings.py (Django does not restart itself automatically in production like it does in development).
As for 400 and 403, just leave the Django defaults. If Django receives a bad request (unlikely in production, because this will usually be caught by Apache or nginx), it will call bad_request() which will just show a "400 bad request" to the user. Likewise for other errors.
I've been using Flask for a little while and find I prefer it to Rails in some ways, particularly for being lightweight. However, one area in which Rails is far superior in my opinion is error reporting. There are many times in Flask where I get an error in my browser, but my console shows no error at all (for example, trying to pull non-existant querystring parameters out of request.form produces a 400 Bad Request, but all you see on the console is the incoming request).
Is there any kind of a verbose mode on Flask which will give me detailed information on all of its behavior?
The debug mode can be enabled via env variable (export FLASK_DEBUG=1) or within the code to allow printing traceback in case of errors as noted below:
app = Flask(__name__)
app.debug = True
You probably want to enable debug mode.
Error handling is off by default in production mode at the moment and can be set up here: http://flask.pocoo.org/docs/errorhandling/
I'm new to GAE, and have not been able to figure out how to configure 'print' statements to the logging console rather than the browser. For example:
class Feed(webapp.RequestHandler):
def post(self):
feeditem = Feeditem()
feeditem.author = self.request.get('from')
feeditem.content = self.request.get('content')
feeditem.put()
notify_friends(feeditem)
self.redirect('/')
def notify_friends(feeditem):
"""Alerts friends of a new feeditem"""
print 'Feeditem = ', feeditem
When I do something like the above, the print in notify_friends outputs to the browser and somehow prevents the self.redirect('/') in the post method that called it. Commenting it out corrects the issue.
Is there a way to change this behavior?
EDIT: Google App Engine tag removed as this is general.
You should instead use the logging module, like so:
import logging
def notify_friends(feeditem):
"""Alerts friends of a new feeditem"""
logging.info('Feeditem = %s', feeditem)
There are a variety of logging levels you can use, from debug to critical. By default, though, the App Engine SDK only shows you log messages at level info and above, so that's what I've suggested here. You can ask it to show you debug messages if you want, but you'll probably be overwhelmed with useless (to you) logging information, at least when running in the SDK.
See the logging module docs for more info.
Oh, and the nice thing about using the logging module is that you'll have access to your log messages in production, under the "Logs" section of your app's the App Engine dashboard.
This is not just a problem with GAE. It is a general issue. You can't print out HTML and then try to have a redirect header. The answer to your question is no, you can't change the behavior. What exactly are you trying to achieve? You might be able to get what you want a different way.
I started playing around with web2py the other day for a new project. I really like the structure and the whole concept which feels like a breath of fresh air after spending a few years with PHP frameworks.
The only thing (currently) that is bothering me is the ticketing system. Each time I make a misstake a page with a link to a ticket is presented. I guess I could live with that if the link worked. It currently points to an admin page with http as protocol instead of https. I've done a bit of reading and the forced https for admin seems to be a security measure, but this makes debugging a pain.
Whats the standard solution here? Alter the error page, allow http for admin och use logs for debugging?
Best regards
Fredrik
I was in the same boat as you, I did not like the default mechanism. Luckily, customized exception handling with web2py is very straightforward. Take a look at routes.py in the root of your web2py directory. I've added the following to mine:
routes_onerror = [('application_name/*','/application_name/error/index')]
This routes any exceptions to my error handler controller (application_name/controllers/error.py) in which I defined my def index as:
def index():
if request.vars.code == '400':
return(dict(app=request.application,
ticket=None,
traceback="A 400 error was raised, this is controller/method path not found",
code=None,
layer=None,
wasEmailed=False))
elif request.vars.code == '404':
return(dict(app=request.application,
ticket=None,
traceback="A 404 error was raised, this is bad.",
code=None,
layer=None,
wasEmailed=False))
else:
fH = file('applications/%s/errors/%s' % (request.application,request.vars.ticket.split("/")[1]))
e = cPickle.load(fH)
fH.close()
__sendEmail(request.application,e['layer'],e['traceback'],e['code'])
return(dict(app=request.application,
ticket=request.vars.ticket,
traceback=e['traceback'],
code=e['code'],
layer=e['layer'],
wasEmailed=True))
As you can see for non-400 and 404 errors, I'm emailing the traceback to myself and then invoking the corresponding views/error/index.html. In production, this view gives a generic "I'm sorry an error has occurred, developers have been emailed". On my development server, it displays the formatted traceback.
Normally, I just use http://127.0.0.1/ (if you are local or over ssh) or edit/navigate using https://...
So, you will logon the admin app the first time, but always will the show the tickets after.