จะเขียนลงไฟล์โดยใช้โมดูล Python การบันทึกได้อย่างไร


128

ฉันจะใช้โมดูลการบันทึกใน Python เพื่อเขียนลงไฟล์ได้อย่างไร ทุกครั้งที่พยายามใช้มันก็แค่พิมพ์ข้อความออกมา

คำตอบ:


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 ได้หรือไม่? ถ้าใช่อย่างไร
Augmented Jacob

เป็นไปได้ไหมที่จะกำหนดเส้นทางของไฟล์
neeraja

1
ตรวจสอบให้แน่ใจว่าสิ่งนี้ไม่อยู่ภายใต้if __name__ == '__main__':หากใช้งานบน apache
Rami Alloush

@RamiAlloush คุณช่วยอธิบายได้ไหม? ทำไมถึงเป็นเช่นนั้น? (ความอยากรู้ :))
ประกาศ

@notihs เซิร์ฟเวอร์ไม่ได้เรียกใช้ไฟล์สคริปต์โดยตรงดังนั้นส่วนด้านล่างif __name__ == '__main__':จึงไม่ถูกเรียกใช้งาน
Rami Alloush

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)

และคุณพร้อมที่จะไป

ปล. อย่าลืมอ่านHOWTO การบันทึกด้วย


4
หากต้องการตอบคำถามแรกของคุณโปรดดูที่ชื่อคำถามที่ฉันถาม ฉันไปดูลิงค์ที่คุณให้มาและมันมีประโยชน์ ฉันได้คัดลอกรหัสที่คุณให้มาและฉันคิดผิดหรือไม่ที่คิดว่าฉันจะสามารถใช้ logger.info ("ข้อความ") และ logger.warning ("ข้อความ") ได้สำเร็จ ฉันสามารถเขียนไฟล์โดยใช้ logger.warning แต่ดูเหมือนว่า logger.info จะไม่เขียนลงในไฟล์
Takkun

ลองลบการโทร setLevel การอ่านเอกสารตัวจัดการดูเหมือนว่าข้อความทั้งหมดจะได้รับการประมวลผลตามค่าเริ่มต้น
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)- ขอบคุณสำหรับความคิดเห็น
Eli Bendersky

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
การตั้งชื่อไฟล์ด้วยวันที่ต้องใช้สองครั้ง%%ใน Python 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
สิ่งนี้ช่วยบันทึกในไฟล์ได้ดี จะเป็นอย่างไรหากร่วมกับสิ่งนี้ฉันต้องการให้มันบันทึกเอาต์พุตบนเทอร์มินัลด้วย?
Rishabh Agrahari

loggingเอกสารโมดูลอย่างเป็นทางการอนุญาตให้ทำสิ่งนี้ได้ คุณยังสามารถเลือกได้ว่าจะบันทึกอะไรในเทอร์มินัลและบันทึกใดไปยังไฟล์และแอปพลิเคชันที่น่าสนใจอื่น ๆ docs.python.org/3/howto/…
Daniel Hernandez

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 เป็นเพียงตัวแปรที่เก็บข้อมูลที่เกี่ยวข้อง แน่นอนว่าค่าสำหรับพารามิเตอร์ของฟังก์ชันขึ้นอยู่กับคุณ

ครั้งแรกที่ฉันใช้โมดูลการบันทึกฉันทำผิดพลาดในการเขียนสิ่งต่อไปนี้ซึ่งทำให้เกิดข้อผิดพลาดในการล็อกไฟล์ OS (ด้านบนเป็นวิธีแก้ปัญหานั้น):

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/logging.html#logging-to-a-file
Ferdinand Beyer

ฉันชอบวิธีที่มีหลายประเภท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

ตัวอย่างนี้ควรใช้งานได้ดี ฉันได้เพิ่ม streamhandler สำหรับคอนโซลแล้ว ข้อมูลบันทึกคอนโซลและตัวจัดการไฟล์ควรคล้ายกัน

    # 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

ใช้ Dict ค่าโทร

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!
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.