Günlük Python modülünü kullanarak bir dosyaya nasıl yazılır?


128

Python'daki günlük modülünü bir dosyaya yazmak için nasıl kullanabilirim ? Onu her kullanmaya çalıştığımda, sadece mesajı yazdırıyor.

Yanıtlar:


172

Kullanılmasının bir örneği logging.basicConfigyerinelogging.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')

Sırayla, beş bölüm aşağıdakileri yapar:

  1. çıktı dosyasını ayarla ( filename=logname)
  2. üzerine yazmak yerine eklemek üzere ayarlayın ( filemode='a')
  3. çıktı mesajının formatını belirle ( format=...)
  4. çıktı zamanının formatını belirleyin (datefmt='%H:%M:%S' )
  5. ve kabul edeceği minimum mesaj seviyesini belirleyin ( level=logging.DEBUG).

Dosya adı bir hdfs konumu olabilir mi? Varsa nasıl?
Augmented Jacob

o set dosya yolu mümkündür
Neeraja

1
if __name__ == '__main__':apache üzerinde çalışıyorsa bunun altında olmadığından emin olun
Rami Alloush

@RamiAlloush detaylandırır mısın lütfen? Neden? (merak :))
notihs

@notihs, sunucu komut dosyasını doğrudan çalıştırmaz, bu nedenle aşağıdaki bölüm if __name__ == '__main__':çalıştırılmaz.
Rami Alloush

71

" Günlük kaydı yemek kitabından " alınmıştır:

# 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)

Ve gitmekte iyisin.

PS Günlük kaydı NASIL belgesini de okuduğunuzdan emin olun .


4
İlk sorunuzu cevaplamak için, sorduğum sorunun başlığına bakabilirsiniz. Sağladığınız bağlantının üzerinden geçtim ve yardımcı oldu. Bana verdiğiniz kodu kopyaladım ve logger.info ("mesaj") ve logger.warning ("mesaj") 'ı başarıyla kullanabileceğimi varsaymak yanlış mıydı? Logger.warning kullanarak dosyaya yazabildim, ancak logger.info dosyaya yazmıyor gibi görünüyor.
Takkun

SetLevel çağrısını kaldırmayı deneyin. İşleyici belgelerinin okunması, tüm iletiler varsayılan olarak işleniyor gibi görünüyor.
thegrinner

2
Sadece kullanarak dosyaya yazabilirim logger.warning("message"), kullanamam logger.info("message")ne de logger.debug("message"). Bu biraz can sıkıcı.
m3nda

3
Bilgi / hata ayıklama mesajları yazmak istiyorsanız @EliBendersky'nin yazdığı kod örneğinde 1 adım eksik. Kaydedicinin kendi günlük düzeyinin, bu düzeydeki günlük mesajlarını kabul edecek şekilde yapılandırılması gerekir, örn logger.setLevel(logging.DEBUG). Kaydediciler birden çok işleyiciyle yapılandırılabilir; kaydedicide yapılandırılan düzey, işleyicilerinin her birine hangi önem düzeyi günlük mesajlarının gönderileceğini belirler ve işleyicilerde ayarlanan düzeyler, işleyicinin hangi düzeyleri işleyeceğini belirler. Bilgi mesajlarını yazdırmak isteyenlerin yalnızca bunu INFOhem kaydedicide hem de işleyicide ayarlaması gerektiğini unutmayın .
testworks

Yapılacak örneği güncelledim logger.setLevel(logging.DEBUG)- yorumlar için teşekkürler
Eli Bendersky

13

Bir yapılandırma dosyası kullanmayı tercih ederim. Geliştirmeden sürüme geçtiğimde kodu değiştirmeden günlük seviyelerini, konumlarını vb. Değiştirmeme izin veriyor. Basitçe aynı isimde ve aynı tanımlı kaydedicilerle farklı bir yapılandırma dosyası paketliyorum.

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()

İşte günlük yapılandırma dosyası için kodum

#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
Dosyayı bir tarihle adlandırmak %%Python 3'te çift ​​gerektirir . Örn.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
Bu, günlükleri dosyaya kaydeder, bu iyidir. Ya bununla birlikte çıktıları terminalde de günlüğe kaydetmesini istersem?
Rishabh Agrahari

Resmi loggingmodül belgeleri buna izin verir. Hatta terminale hangi günlüklerin gireceğini ve hangilerinin bir dosyaya gireceğini ve daha birçok ilginç uygulamayı seçebilirsiniz. docs.python.org/3/howto/…
Daniel Hernandez

4

işte bunu yapmanın daha basit bir yolu. bu çözüm bir yapılandırma sözlüğü kullanmaz ve aşağıdaki gibi bir döndürme dosyası işleyicisi kullanır:

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')

ya da bunun gibi:

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')

işleyiciler değişkeninin yinelenebilir olması gerekir. logpath + dosya adı ve debug_level yalnızca ilgili bilgileri tutan değişkenlerdir. tabii ki, fonksiyon parametrelerinin değerleri size bağlıdır.

Günlük modülünü ilk kullandığımda aşağıdakileri yazma hatası yaptım, bu da bir işletim sistemi dosya kilidi hatası oluşturuyor (bunun çözümü yukarıdakidir):

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))

ve Bob senin amcan!



0
import sys
import logging

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

0

Bu örnek iyi çalışmalıdır. Konsol için akış işleyici ekledim. Konsol günlüğü ve dosya işleyici verileri benzer olmalıdır.

    # 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

Biçim Açıklama

#%(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. 

Normal arama şekli

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')

Çıktı

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

Dikte, Çağrı değerlerini kullanma

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

Çıktı

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!
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.