Forums

Print data in a log file

Hi guys,

I'm trying to do some debugging, and I just wanted to print a json I receive from a PC application to a log file. I'm trying by using the logging library and I actuallyy succeed in creating a new "app.log" file in my /home/<myName> folder. I call the "logging.debug(<myJSON>)" from the API call in my Flask script. The problem is that the "app.log" file is not being populated by the json files I would like to print in there. I think I set up the logging configuration properly since the "app.log" file is created when the PC application uses the API call.

Have you set the logging level correctly? If you've set it to something above debug, then debug messages will not be logged.

Ok, this is the code I used in the configuration file

path = '/home/<myName>/log'
os.makedirs(path, exist_ok=True)

info_fh = RotatingFileHandler(os.path.join(path, 'app.log'), maxBytes=10000000, backupCount=3)
info_fh.setFormatter(logging.Formatter(
    '%(asctime)s %(levelname)s: %(message)s '
    '[in %(pathname)s:%(lineno)d]'
))

info_fh.setLevel(logging.DEBUG)
l = logging.getLogger()
l.addHandler(info_fh)

I can see the app.log file once I use an API call, but it is an empty file. The code I use is:

logger = logging.getLogger()

as a global variable, and:

logger.debug(<Object>)

inside the API call.

Does <object> have a string representation that is not just an empty string? First try logging a simple string to see whether that works.

Yes I tried with "hello" and it's not working. I tried with a dictionary at first.

Hi -- I've got two questions that might help us go further:

  • did you check the error logs (if so, do you see any relevant errors there)?

  • since you're defining your logger as l and then use logger is it in separate modules? are you sure you're using the same logger everywhere?

Ok you are right, there is something wrong with my logic here. As you said I use "l" in the configuration file and "logger" in the API call. Now I fixed the configuration file by using "logger" instead of "l". But now my question is? How should I make the configuration file and the API call communicating?

PS: the log is fine, it is a successful call. I simply want to print the json posted in the call (the json is actually posted in the database).

Normally you should be able to import the logger object from the module where you define it. What do you call a configuration file?

I'm talking about the file in which the flask_app is called "/var/www/<myname>_pythonanywhere_com_wsgi.py"

All right, so in that case you should rather move the logging setup to your web app code.

Ok so I should keep this in the configuration file:

path = '/home/<myName>/log'
os.makedirs(path, exist_ok=True)

and move all the other stuff in the web app code right?

Maybe is not necessary to keep the path creation code in the configuration

Ok now I have this in the web app code working globally:

path = '/home/<myname>/log'
info_fh = RotatingFileHandler(os.path.join(path, 'app.log'), maxBytes=10000000, backupCount=3)
info_fh.setFormatter(logging.Formatter(
    '%(asctime)s %(levelname)s: %(message)s '
    '[in %(pathname)s:%(lineno)d]'
))

info_fh.setLevel(logging.DEBUG)
logger = logging.getLogger()
logger.addHandler(info_fh)

and then I use this in the API call (which is successful when I call it from my android app)

logger.debug('hello')

But it didn't work. The "app.log" file is still empty.

OK, sorry, I think I've introduced some confusion, had to re-read the logging docs. getLogger returns the same logging object; when called without argument, returns the root logger. Maybe try using a named logger (calling getLogger with a string representing the logger name), and reference that named logger where you need it.

Btw, as the code is now, when I set the level to Info, instead of Debug, it seems I fixed the problem. Now I can see the object printed in the app.log file.

Hmm, that's interesting. Perhaps the problem is that although your handler has the level set to DEBUG, the logger itself does not? Try adding

logger.setLevel(logging.DEBUG)

...to your code at the same time as you add the handler.

it doesn't work :( Btw, I'm happy I solved by using INFO which does what I need.

Glad to hear that you were able to do what you need!