Logging does not work - python

I am using standard logging configurations, set in settings.py file, and accessed in program but I get the error
error No handlers could be found for logger.
It works when run from the console but does not work when run from Eclipse.
The code is as follows:
import logging
from config import settings
logger = logging.getLogger('engine')
class ReplyUser(object):
def __init__(self):
logger.info("Initalizes ReplyUser")
def myfun(self):
logger.info("Hi")
print "hi"

I am guessing the problem is in the PATH which eclipse is using and it is unable to find settings.py as the handler information is stored in the settings.py file, hence the error.

Related

Python How can I set up global logger setting in multi python files?

I just started Python and I am struggling to use Logger. I have two python files: app.py and liba.py. I want to setup logging at app.py and use it for liba.py (and another libraries). Do you have any good ideas or can you share any references?
file structure
entry.py
lib/liba.py
app.py
#! /usr/bin/env python3
import logging
logger = logging.getLogger(__name__)
from lib import liba
handler = logging.FileHandler('/tmp/app.log', 'a+')
logger.addHandler(handler)
logger.warn('sample')
liba.out()
lib/liba.py
#! /usr/bin/env python3
import logging
logger = logging.getLogger(__name__)
def out():
logger.warn('liba')
run python
$ python3 app.py
liba
app.py output log to the logfile. liba.py does not output the log into the file. I want to save logs in the same file.
Do like so:
app.py
#! /usr/bin/env python3
import logging
logger = logging.getLogger()
handler = logging.FileHandler('/tmp/app.log', 'a+')
logger.addHandler(handler)
logger.warn('sample')
from lib import liba
liba.out()
lib/liba.py
#! /usr/bin/env python3
import logging
def out():
logging.warn('liba')
You don't need to instantiate the logging, unless you want to configure handlers, which you only do in your main script. Then all logging will go to the root logger which is what you get when instantiating with no specific name logging.getLogger(). I like to use it this way as you don't need to match names across all your modules for it to work. In your modules you just send log messages out by using logging.warn('blabla'). You further need to make sure you define all your handlers before any call to logging.warn is made, otherwise some default handler will take its place.

How python logging get it's configuration

I used to Python logging, it works fine. The logging.basicConfig(...) set in one module (a some.py file), then we can use logging every where. Obviously, logging is global.
The question is how logging find it's settings, when we not call the module where basicConfig(...) appeared (in some.py file )? Is logging scan all the packages?
Even the logging.basicConfig(...) put into an any.py and the module (any.py) never get imported, or not used anywhere, the logging setting take effect!
To understand logging you have dive into Python's standard library sources.
Here is the trick:
#/usr/lib/python3.2/logging/__init__.py
...
root = RootLogger(WARNING)
Logger.root = root
Logger.manager = Manager(Logger.root)
...
# and
def basicConfig(**kwargs):
...
hdlr = StreamHandler(stream)
fs = kwargs.get("format", BASIC_FORMAT)
dfs = kwargs.get("datefmt", None)
style = kwargs.get("style", '%')
fmt = Formatter(fs, dfs, style)
hdlr.setFormatter(fmt)
root.addHandler(hdlr)
So, when you call basicconfig() with certain parameters, root logger is set.
Finally getLogger:
def getLogger(name=None):
"""
Return a logger with the specified name, creating it if necessary.
If no name is specified, return the root logger.
"""
if name:
return Logger.manager.getLogger(name)
else:
return root
I think there is no magic scanning here.
Try to test it this way in a separate test directory:
test/main.py:
import logging
logging.info('test')
test/any.py:
import logging
logging.basicConfig(filename='test.log', level=logging.INFO)
python main.py
Result: NO test.log file.
Now let's update the test:
test/main.py:
import logging
import any
logging.info('test')
python main.py
Result: new test.log file with INFO:root:test string inside.
So I guess that any.py in your case is imported somehow,
despite your expectations.
You may find the way any.py is imported easily,
just add few lines there:
test/any.py:
from traceback import print_stack
print_stack()
...
python main.py
Result:
File "main.py", line 2, in
import any
File "any.py", line 2, in
print_stack()
This stack shows that any.py is imported from main.py.
I hope you will find where it is imported from in your case.

app engine python is this bug: when open switch interactive console

While I am working at localhost:8080, when I open interactive console and do some operations, like getting list of Kind etc (address: http://localhost:8080/_ah/admin/interactive) then it gives me this error:
<class 'google.appengine.dist._library.UnacceptableVersionError'>: django 1.2 was requested, but 0.96.4.None is already in use
This errors happened several times, in similar cases. It is stuck until restart localhost by dev_appserver.py
Is this a bug or what I am doing wrong?
Example for what I did at interactive console:
from myapp.models import *
for room in Room.all():
room.update_time = room.create_time
room.put()
Note:
This is my django_bootstrap :
import os
import sys
import logging
import __builtin__
from google.appengine.ext.webapp import util
import pickle
sys.modules['cPicle'] =pickle
logging.getLogger().setLevel(logging.INFO)
sys.path.insert(0, os.path.abspath((os.path.dirname(__file__))))
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')
import django.core.handlers.wsgi
def main():
application = django.core.handlers.wsgi.WSGIHandler()
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
my index.ymal in root folder says:
# AUTOGENERATED
# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run. If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED"). If you want to manage some indexes
# manually, move them above the marker line. The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.
Thus each time I open http://localhost:8080/_ah/admin/datastore, this file updated: which is still has the same content but timestamp of file on operating system says it is updated.
I think here, As the http://localhost:8080 sees that models.py is not the same then it could load it then can not start django_bootstrap.
However if I first open http://localhost:8080/_ah/admin/datastore and then http://localhost:8080, it works. So this is why sometimes I get error sometimes not: It depends of order urls respective

where to store a log file name in python?

I have a Python program that consists of several modules. The "main" module creates a file variable log_file for logging the output; all the other modules would need to write to that file as well.
However, I don't want to import the "main" module into other modules, since it would be a really weird dependency (not to mention it might not even work due to circular dependency).
Where, then, should I store the log_file variable?
EDIT:
Following #pyfunc answer - would this be ok:
--- config.py ---
# does not mention log_file
# unless it's required for syntax reasons; in which case log_file = None
# ...
--- main.py ---
from datetime import datetime
import config.py
log_filename = str(datetime.now()) + '.txt'
config.log_file = open(log_filename, 'w')
# ...
--- another_module.py ---
import config.py
# ...
config.log_file.write(some_stuff)
Put the "global" variable in a "settings" module.
settings.py
log_file = "/path/to/file"
main.py
import settings
import logging
logging.basicConfig(filename=settings.log_file,level=logging.DEBUG)
logging.debug("This should go to the log file")
other_module.py
import logging
logging.debug("This is a message from another place.")
While the logging module may solve your immediate problem and many others, the settings module pattern is useful for a lot of other things besides log file names. It is used by Django to configure just about everything.
One way is to take all that code into another module so that you could import it in main file and other modules as well.
Hope you have checked on : http://docs.python.org/library/logging.html

Django unit testing - Why can't I just run ./tests.py on myApp?

So I'm very familiar with manage.py test myapp. But I can't figure out how to make my tests.py work as an stand-alone executable. You may be wondering why I would want to do this.. Well I'm working (now) in Eclipse and I can't seem to figure out how to set up the tool to simply run this command. Regardless it would be very nice to simply wrap tests.py in a simple manner to just run that.
Here is what my tests.py looks like.
"""
This simply tests myapp
"""
import sys
import logging
from django.test import TestCase
from django.conf import settings
from django.test.utils import get_runner
class ModelTest(TestCase):
def test_model_test1(self):
"""
This is test 1
"""
self.failUnlessEqual(1 + 1, 2)
def test_model_test2(self):
"""
This is test 2
"""
self.failUnlessEqual(1 + 1, 2)
def test_model_test3(self):
"""
This is test 3
"""
self.failUnlessEqual(1 + 1, 2)
def run_tests():
test_runner = get_runner(settings)
failures = test_runner([], verbosity=9, interactive=False)
sys.exit(failures)
if __name__ == '__main__':
# Setup Logging
loglevel = logging.DEBUG
logging.basicConfig(format="%(levelname)-8s %(asctime)s %(name)s %(message)s",
datefmt='%m/%d/%y %H:%M:%S', stream=sys.stdout)
log = logging.getLogger("")
run_tests()
I think the solution is located on this line but I can't seem to figure out what the first argument needs to be in order for it to magically start working..
failures = test_runner([], verbosity=9, interactive=False)
Thanks for helping!!
**** Updates ****
What I am looking to do (Doh!) is to simply run "myApp" tests. The problem is that this works (and chmod is not the problem) but it wants to run the entire test suite. I don't want that. I just want to run the myApp test suite.
Thanks again!
You could create an "External Tool" configuration for your project, such as:
Location: ${project_loc}/src/${project_name}/manage.py
Working Directory: ${project_loc}/src/${project_name}/
Arguments: test ${string_prompt}
This will run manage.py test <whatever name you type in the string prompt>.
The values above assume that you created a pydev project in Eclipse and then housed your Django project in the pydev src directory. It also assumes that you have the project name for pydev be the same name of your Django project. It will use the currently selected project in the package explorer to determine project_loc and project_name.
a. this should be the first line at your code file (tests.py)
#!/usr/bin/env python
b. run $ chmod +x tests.py

Categories

Resources