top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

Logging to file and not to console in Python

+4 votes
642 views

I have an application which sets up logging after parsing the args in the main() funktion. It needs to be setup after parsing the args because I can set the loglevel via commandline flags.

I have tried many variants on how to do that but every time with an weird result. What I want is logging in from all libs and really understand that doing this should be enough there:

from logging import getLogger

logger = getLogger(__name__)

But, I need to setup the logger in the main() function to log only to a file and not to console because my application has an own shell interface which should not be spammed with log messages - never a message should show up there.

I think it should be only some few lines of code but I can't figure that out. The logger should be configured to have a max file size and rotate logfiles. Can someone help me with this?

posted Oct 27, 2013 by Deepankar Dubey

Share this question
Facebook Share Button Twitter Share Button LinkedIn Share Button

1 Answer

+1 vote
 
Best answer
import logging
import logging.handlers

logger = logging.getLogger(__name__)

def levelnames():
 try:
 names = logging._nameToLevel
 except AttributeError:
 names = (name for name in logging._levelNames if isinstance(name, 
str))

def main():
 import argparse
 parser = argparse.ArgumentParser()
 parser.add_argument("--logging-file", default="tmp.log")
 parser.add_argument("--logging-level", choices=levelnames(), 
default="INFO")
 args = parser.parse_args()

 root = logging.getLogger()

 formatter = logging.Formatter(logging.BASIC_FORMAT)
 handler = logging.handlers.RotatingFileHandler(args.logging_file, 
maxBytes=100, backupCount=3)
 handler.setFormatter(formatter)

 root.addHandler(handler)
 root.setLevel(args.logging_level)

 logger.info("your info")
 logger.warn("your warning")
 logger.critical("your critical message")

if __name__ == "__main__":
 main()

Does this do what you want? (maxBytes is probably a bit low)

answer Oct 27, 2013 by Kumar Mitrasen
Yes! That was exactly what I want! Thank you very much! Now it behaves well. I know that maxBytes is slow but that will be configurable in the future. I just needed some clean way to get debug messages even from libs like APScheduler. When running my application in production mode logging will be completely disabled so it is Ok this way.
Similar Questions
+1 vote

I have a script-service running on a remote server, listening on a specific port. What i need here is to make this also maintain a log file of ALL incoming connections.

Could someone suggest to me a simple codefunction example to implement that on my main running service?

+1 vote

My development setup is Win7 while my production is RHEL6. Both of the environments have the same settings in conf/logging.properties but the files in logs/ are slightly different.

The access logs are named the same way. But on RHEL there's no tomcat7-stdout or tomcat7-stderr log files. Just 'catalina.out.YEAR.MO.DY' and the cumulative "catalina.out" with no date.

What accounts for the differences? Also, how would you stop logging to the 'catalina.out' file. It gets unusably gigantic within a few days.

+2 votes

I am using the below appenders in my domain.xml file to point all the logs from my application to app.log. I see the file is getting created but there are no logging happening.

 <periodic-rotating-file-handler name="CACHE-FILE" autoflush="true">
            <level name="DEBUG"/>
            <formatter>
               <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
            </formatter>
            <file relative-to="jboss.server.log.dir" path="app.log"/>
            <suffix value=".yyyy-MM-dd"/>
            <append value="true"/>
         </periodic-rotating-file-handler>

           <logger category="com.abc.cache" use-parent-handlers="false">
               <level name="DEBUG"/>
               <handlers>
                  <handler name="CACHE-FILE"/>
               </handlers>
           </logger>
+2 votes

Is there a way to force Tomcat to set permissions on log files when they’re created? It seems as though this would be something defined in the logging.properties file, but it doesn’t seem like it’s an option.

I want the permissions of all log files created (on server startup/log rollover) to be 640. The only way I can think of doing this is either adding the command to the startup script, or by running a cron job every hour or so. However, if there is a way to make sure the log files are never more permissive than 640, that would be greatly preferable.

+1 vote

Let's say I want to compare two csv files: file A and file B. They are both similarly built - the first column has product IDs (one product per row) and the columns provide some stats about the products such as sales in # and $.

I want to compare these files - see which product IDs appear in the first column of file A and not in B, and which in B and not A.
Finally, it would be very great if the result could be written into two new CSV files - one product ID per row in the first column. (no other data in the other columns needed)

This is the script I tried:

import csv

#open CSV's and read first column with product IDs into variables pointing to lists
A = [line.split(',')[0] for line in open('Afile.csv')]
B = [line.split(',')[0] for line in open('Bfile.csv')]

#create variables pointing to lists with unique product IDs in A and B respectively 
inAnotB = list(set(A)-set(B))
inBnotA = list(set(B)-set(A))

print inAnotB
print inBnotA

c = csv.writer(open("inAnotB.csv", "wb"))
c.writerow([inAnotB])

d = csv.writer(open("inBnotA.csv", "wb"))
d.writerow([inBnotA])

print "done!" 

But it doesn't produce the required results.
It prints IDs in this format:

247158132n

and nothing to the csv files.

...