लॉगिंग पायथन मॉड्यूल का उपयोग करके, फ़ाइल में कैसे लिखें?


128

मैं एक फ़ाइल को लिखने के लिए पायथन में लॉगिंग मॉड्यूल का उपयोग कैसे कर सकता हूं ? जब भी मैं इसका उपयोग करने की कोशिश करता हूं, यह संदेश को प्रिंट कर देता है।

जवाबों:


172

के logging.basicConfigबजाय उपयोग करने का एक उदाहरणlogging.fileHandler()

logging.basicConfig(filename=logname,
                            filemode='a',
                            format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                            datefmt='%H:%M:%S',
                            level=logging.DEBUG)

logging.info("Running Urban Planning")

self.logger = logging.getLogger('urbanGUI')

आदेश में, पाँच भाग निम्नलिखित करते हैं:

  1. आउटपुट फ़ाइल सेट करें ( filename=logname)
  2. अधिलेखित करने के बजाय इसे संलग्न करें ( filemode='a')
  3. आउटपुट संदेश का प्रारूप निर्धारित करें ( format=...)
  4. आउटपुट समय का प्रारूप निर्धारित करें ( datefmt='%H:%M:%S')
  5. और न्यूनतम संदेश स्तर निर्धारित करेगा जिसे वह स्वीकार करेगा ( level=logging.DEBUG)।

फ़ाइल नाम एक hdfs स्थान हो सकता है? यदि हाँ, तो कैसे?
संवर्धित जैकब

क्या फ़ाइल पथ सेट करना संभव है
नीरजा

1
सुनिश्चित करें कि यह if __name__ == '__main__':अपाचे पर चलने के तहत नहीं है
रामी अल्लौश

@RamiAlloush क्या आप कृपया विस्तार से बता सकते हैं? ऐसा क्यों है? (जिज्ञासा :))
notihs

@ नोट, सर्वर सीधे स्क्रिप्ट फ़ाइल नहीं चलाता है, इसलिए नीचे दिया गया अनुभाग if __name__ == '__main__':निष्पादित नहीं होता है।
रामी अल्लौस

71

" लॉगिंग कुकबुक " से लिया गया :

# create logger with 'spam_application'
logger = logging.getLogger('spam_application')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)

और आप जाने के लिए अच्छे हैं।

PS सुनिश्चित करें कि लॉगिंग HOWTO को भी पढ़ें ।


4
अपने पहले प्रश्न का उत्तर देने के लिए, मेरे द्वारा पूछे गए प्रश्न के शीर्षक को देखने के लिए स्वतंत्र महसूस करें। मैंने आपके द्वारा दिए गए लिंक पर चला गया है और यह मददगार था। मैंने आपके द्वारा दिए गए कोड की प्रतिलिपि बनाई है और क्या मैं यह मान लेना गलत था कि मैं logger.info ("संदेश") और logger.warning ("संदेश") का सफलतापूर्वक उपयोग कर पाऊंगा? मैं logger.warning का उपयोग करके फ़ाइल में लिखने में सक्षम था, हालाँकि logger.info फ़ाइल को लिखना नहीं चाहता है।
ताकुन

सेटलेवल कॉल को हटाने का प्रयास करें। हैंडलर डॉक्स को पढ़ना ऐसा लगता है कि सभी संदेश डिफ़ॉल्ट रूप से संसाधित होते हैं।
thegrinner

2
मैं केवल का उपयोग कर फाइल करने के लिए बाहर लिख सकते हैं logger.warning("message"), उपयोग नहीं कर सकते logger.info("message")और न ही logger.debug("message")। यह थोड़ा कष्टप्रद है।
m3nda

3
@EliBendersky ने जो कोड उदाहरण लिखा है, वह 1 स्टेप गायब है यदि आप जानकारी / डिबग संदेश लिखना चाहते हैं। लॉगिंग संदेशों के उस स्तर को स्वीकार करने के लिए लकड़हारे को स्वयं अपने लॉग स्तर की आवश्यकता होती है logger.setLevel(logging.DEBUG)। लॉगर्स को कई हैंडलर के साथ कॉन्फ़िगर किया जा सकता है; लकड़हारा में कॉन्फ़िगर किया गया स्तर यह निर्धारित करता है कि कौन सा गंभीरता स्तर लॉग संदेश अपने प्रत्येक हैंडलर को भेजने के लिए, और हैंडलर में सेट किए गए स्तर निर्धारित करते हैं कि हैंडलर किस स्तर पर प्रक्रिया करेगा। ध्यान दें कि जो लोग सूचना संदेशों को प्रिंट करना चाहते हैं, उन्हें केवल INFOलकड़हारा और हैंडलर दोनों में इसे सेट करने की आवश्यकता है ।
testworks

मैंने करने के लिए नमूना अपडेट किया है logger.setLevel(logging.DEBUG)- टिप्पणियों के लिए धन्यवाद
एली बेंडरस्की

13

मैं एक कॉन्फ़िगरेशन फ़ाइल का उपयोग करना पसंद करता हूं। यह मुझे कोड बदलने के बिना लॉगिंग स्तरों, स्थानों आदि को बदलने की अनुमति देता है, जब मैं विकास से रिलीज तक जाता हूं। मैं बस एक ही नाम के साथ, और एक ही परिभाषित लॉगर के साथ एक अलग कॉन्फ़िगरेशन फ़ाइल पैकेज करता हूं।

import logging.config
if __name__ == '__main__':
    # Configure the logger
    # loggerConfigFileName: The name and path of your configuration file
    logging.config.fileConfig(path.normpath(loggerConfigFileName))

    # Create the logger
    # Admin_Client: The name of a logger defined in the config file
    mylogger = logging.getLogger('Admin_Client')

    msg='Bite Me'
    myLogger.debug(msg)
    myLogger.info(msg)
    myLogger.warn(msg)
    myLogger.error(msg)
    myLogger.critical(msg)

    # Shut down the logger
    logging.shutdown()

लॉग लॉग फ़ाइल के लिए यहां मेरा कोड है

#These are the loggers that are available from the code
#Each logger requires a handler, but can have more than one
[loggers]
keys=root,Admin_Client


#Each handler requires a single formatter
[handlers]
keys=fileHandler, consoleHandler


[formatters]
keys=logFormatter, consoleFormatter


[logger_root]
level=DEBUG
handlers=fileHandler


[logger_Admin_Client]
level=DEBUG
handlers=fileHandler, consoleHandler
qualname=Admin_Client
#propagate=0 Does not pass messages to ancestor loggers(root)
propagate=0


# Do not use a console logger when running scripts from a bat file without a console
# because it hangs!
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=consoleFormatter
args=(sys.stdout,)# The comma is correct, because the parser is looking for args


[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=logFormatter
# This causes a new file to be created for each script
# Change time.strftime("%Y%m%d%H%M%S") to time.strftime("%Y%m%d")
# And only one log per day will be created. All messages will be amended to it.
args=("D:\\Logs\\PyLogs\\" + time.strftime("%Y%m%d%H%M%S")+'.log', 'a')


[formatter_logFormatter]
#name is the name of the logger root or Admin_Client
#levelname is the log message level debug, warn, ect 
#lineno is the line number from where the call to log is made
#04d is simple formatting to ensure there are four numeric places with leading zeros
#4s would work as well, but would simply pad the string with leading spaces, right justify
#-4s would work as well, but would simply pad the string with trailing spaces, left justify
#filename is the file name from where the call to log is made
#funcName is the method name from where the call to log is made
#format=%(asctime)s | %(lineno)d | %(message)s
#format=%(asctime)s | %(name)s | %(levelname)s | %(message)s
#format=%(asctime)s | %(name)s | %(module)s-%(lineno) | %(levelname)s | %(message)s
#format=%(asctime)s | %(name)s | %(module)s-%(lineno)04d | %(levelname)s | %(message)s
#format=%(asctime)s | %(name)s | %(module)s-%(lineno)4s | %(levelname)-8s | %(message)s

format=%(asctime)s | %(levelname)-8s | %(lineno)04d | %(message)s


#Use a separate formatter for the console if you want
[formatter_consoleFormatter]
format=%(asctime)s | %(levelname)-8s | %(filename)s-%(funcName)s-%(lineno)04d | %(message)s

1
किसी दिनांक के साथ फ़ाइल का नामकरण %%पायथन 3 में डबल की आवश्यकता है । उदाहरण के लिएtime.strftime("%%Y%%m%%D")
AH

9

http://docs.python.org/library/logging.html#logging.basicConfig

logging.basicConfig(filename='/path/to/your/log', level=....)

1
यह फ़ाइल में लॉग बचाता है, यह अच्छा है। क्या होगा अगर इसके साथ, मैं चाहूंगा कि टर्मिनल पर आउटपुट भी लॉग इन करें?
ऋषभ अग्रहरी

आधिकारिक loggingमॉड्यूल प्रलेखन इसके लिए अनुमति देता है। आप यह भी चुन सकते हैं कि लॉग क्या टर्मिनल में जाते हैं और कौन से फ़ाइल में जाते हैं, और कई और दिलचस्प अनुप्रयोग। docs.python.org/3/howto/…
डैनियल हर्नांडेज़

4

यहाँ इसके बारे में जाने का एक सरल तरीका है। यह समाधान कॉन्फिग डिक्शनरी का उपयोग नहीं करता है और रोटेशन फ़ाइल हैंडलर का उपयोग करता है, जैसे:

import logging
from logging.handlers import RotatingFileHandler

logging.basicConfig(handlers=[RotatingFileHandler(filename=logpath+filename,
                     mode='w', maxBytes=512000, backupCount=4)], level=debug_level,
                     format='%(levelname)s %(asctime)s %(message)s', 
                    datefmt='%m/%d/%Y%I:%M:%S %p')

logger = logging.getLogger('my_logger')

या ऐसा है:

import logging
from logging.handlers import RotatingFileHandler

handlers = [
            RotatingFileHandler(filename=logpath+filename, mode='w', maxBytes=512000, 
                                backupCount=4)
           ]
logging.basicConfig(handlers=handlers, level=debug_level, 
                    format='%(levelname)s %(asctime)s %(message)s', 
                    datefmt='%m/%d/%Y%I:%M:%S %p')

logger = logging.getLogger('my_logger')

हैंडलर चर एक चलने की जरूरत है। logpath + फ़ाइल नाम और debug_level संबंधित जानकारी रखने वाले चर हैं। बेशक, फ़ंक्शन परम के लिए मूल्य आपके ऊपर हैं।

पहली बार जब मैं लॉगिंग मॉड्यूल का उपयोग कर रहा था, तो मैंने निम्नलिखित को लिखने की गलती की, जो एक ओएस फ़ाइल लॉक त्रुटि उत्पन्न करता है (ऊपर इसका समाधान है):

import logging
from logging.handlers import RotatingFileHandler

logging.basicConfig(filename=logpath+filename, level=debug_level, format='%(levelname)s %(asctime)s %(message)s', datefmt='%m/%d/%Y
 %I:%M:%S %p')

logger = logging.getLogger('my_logger')
logger.addHandler(RotatingFileHandler(filename=logpath+filename, mode='w', 
                  maxBytes=512000, backupCount=4))

और बॉब तुम्हारे चाचा!


3

http://docs.python.org/library/logging.handlers.html#filehandler

FileHandlerवर्ग, कोर में स्थित loggingपैकेज, एक डिस्क फ़ाइल के लिए लॉगिंग आउटपुट भेजता है।


3
+1 एक पूर्ण उदाहरण के लिए, "बुनियादी ट्यूटोरियल" देखें: docs.python.org/howto/log.html#log-to-a-file
फर्डिनेंड बेयर

मुझे पसंद है कि FileHandlerविभिन्न स्थितियों के लिए कई प्रकार के एस कैसे हैं । ( WatchedFileHandler, RotatingFileHandlerआदि)
JAB

0
import sys
import logging

from util import reducer_logfile
logging.basicConfig(filename=reducer_logfile, format='%(message)s',
                    level=logging.INFO, filemode='w')

0

यह उदाहरण ठीक काम करना चाहिए। मैंने कंसोल के लिए स्ट्रीमहैंडलर जोड़ा है। कंसोल लॉग और फ़ाइल हैंडलर डेटा समान होना चाहिए।

    # MUTHUKUMAR_TIME_DATE.py #>>>>>>>> file name(module)

    import sys
    import logging
    import logging.config
    # ================== Logger ================================
    def Logger(file_name):
        formatter = logging.Formatter(fmt='%(asctime)s %(module)s,line: %(lineno)d %(levelname)8s | %(message)s',
                                      datefmt='%Y/%m/%d %H:%M:%S') # %I:%M:%S %p AM|PM format
        logging.basicConfig(filename = '%s.log' %(file_name),format= '%(asctime)s %(module)s,line: %(lineno)d %(levelname)8s | %(message)s',
                                      datefmt='%Y/%m/%d %H:%M:%S', filemode = 'w', level = logging.INFO)
        log_obj = logging.getLogger()
        log_obj.setLevel(logging.DEBUG)
        # log_obj = logging.getLogger().addHandler(logging.StreamHandler())

        # console printer
        screen_handler = logging.StreamHandler(stream=sys.stdout) #stream=sys.stdout is similar to normal print
        screen_handler.setFormatter(formatter)
        logging.getLogger().addHandler(screen_handler)

        log_obj.info("Logger object created successfully..")
        return log_obj
    # =======================================================


MUTHUKUMAR_LOGGING_CHECK.py #>>>>>>>>>>> file name
# calling **Logger** function
file_name = 'muthu'
log_obj =Logger(file_name)
log_obj.info("yes   hfghghg ghgfh".format())
log_obj.critical("CRIC".format())
log_obj.error("ERR".format())
log_obj.warning("WARN".format())
log_obj.debug("debug".format())
log_obj.info("qwerty".format())
log_obj.info("asdfghjkl".format())
log_obj.info("zxcvbnm".format())
# closing file
log_obj.handlers.clear()

OUTPUT:
2019/07/13 23:54:40 MUTHUKUMAR_TIME_DATE,line: 17     INFO | Logger object created successfully..
2019/07/13 23:54:40 MUTHUKUMAR_LOGGING_CHECK,line: 8     INFO | yes   hfghghg ghgfh
2019/07/13 23:54:40 MUTHUKUMAR_LOGGING_CHECK,line: 9 CRITICAL | CRIC
2019/07/13 23:54:40 MUTHUKUMAR_LOGGING_CHECK,line: 10    ERROR | ERR
2019/07/13 23:54:40 MUTHUKUMAR_LOGGING_CHECK,line: 11  WARNING | WARN
2019/07/13 23:54:40 MUTHUKUMAR_LOGGING_CHECK,line: 12    DEBUG | debug
2019/07/13 23:54:40 MUTHUKUMAR_LOGGING_CHECK,line: 13     INFO | qwerty
2019/07/13 23:54:40 MUTHUKUMAR_LOGGING_CHECK,line: 14     INFO | asdfghjkl
2019/07/13 23:54:40 MUTHUKUMAR_LOGGING_CHECK,line: 15     INFO | zxcvbnm

Thanks, 

0

प्रारूप विवरण

#%(name)s       Name of the logger (logging channel).
#%(levelname)s  Text logging level for the message ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').
#%(asctime)s    Human-readable time when the LogRecord was created. By default this is of the form ``2003-07-08 16:49:45,896'' (the numbers after the comma are millisecond portion of the time).
#%(message)s    The logged message. 

कॉल करने का सामान्य तरीका

import logging
#logging.basicConfig(level=logging.INFO)
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.info('Start reading database')
# read database here
records = {'john': 55, 'tom': 66}
logger.debug('Records: %s', records)
logger.info('Updating records ...')
# update records here
logger.info('Finish updating records')

उत्पादन

INFO:__main__:Start reading database
DEBUG:__main__:Records: {'john': 55, 'tom': 66}
INFO:__main__:Updating records ...
INFO:__main__:Finish updating records

डिक्ट, कॉल मान का उपयोग करना

import logging
import logging.config
import otherMod2

def main():
    """
    Based on http://docs.python.org/howto/logging.html#configuring-logging
    """
    dictLogConfig = {
        "version":1,
        "handlers":{
                    "fileHandler":{
                        "class":"logging.FileHandler",
                        "formatter":"myFormatter",
                        "filename":"config2.log"
                        }
                    },        
        "loggers":{
            "exampleApp":{
                "handlers":["fileHandler"],
                "level":"INFO",
                }
            },

        "formatters":{
            "myFormatter":{
                "format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
                }
            }
        }

    logging.config.dictConfig(dictLogConfig)

    logger = logging.getLogger("exampleApp")

    logger.info("Program started")
    result = otherMod2.add(7, 8)
    logger.info("Done!")

if __name__ == "__main__":
    main()

otherMod2.py

import logging
def add(x, y):
    """"""
    logger = logging.getLogger("exampleApp.otherMod2.add")
    logger.info("added %s and %s to get %s" % (x, y, x+y))
    return x+y

उत्पादन

2019-08-12 18:03:50,026 - exampleApp - INFO - Program started
2019-08-12 18:03:50,026 - exampleApp.otherMod2.add - INFO - added 7 and 8 to get 15
2019-08-12 18:03:50,027 - exampleApp - INFO - Done!
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.