Нужно сделать ежедневную ротацию журнала (0utc) с использованием Python

Я признанный нуб в Python. Я написал небольшой регистратор, который берет данные с последовательного порта и записывает их в файл журнала. У меня есть небольшая процедура, которая открывает файл для добавления, записывает, затем закрывает. Я подозреваю, что это может быть не лучший способ сделать это, но это то, что я понял до сих пор.

Я хотел бы, чтобы он автоматически выполнял ротацию журнала в 00:00 UTC, но пока мои попытки сделать это с помощью RotatingFileHandler не увенчались успехом.

Вот как выглядит код:

import time, serial, logging, logging.handlers,os,sys
from datetime import *

CT12 = serial.Serial()
CT12.port = "/dev/ct12k"
CT12.baudrate = 2400
CT12.parity = 'E'
CT12.bytesize = 7
CT12.stopbits = 1
CT12.timeout = 3

logStart = datetime.now()
dtg = datetime.strftime(logStart, '%Y-%m-%d %H:%M:%S ')
ctlA = unichr(1)
bom = unichr(2)
eom = unichr(3)
bel = unichr(7)
CT12Name = [ctlA, 'CT12-NWC-test']
CT12Header = ['-Ceilometer Logfile \r\n', '-File created: ', dtg, '\r\n']

def write_ceilo ( text ) :
    f = open ('/data/CT12.log', 'a')
    f.write (text)
    f.close ()

write_ceilo(''.join(CT12Header))

CT12.open()

discard = CT12.readlines()
#print (discard)

while CT12.isOpen():
    response = CT12.readline()
    if len(response) >= 3:
        if response[0] == '\x02' :
            now=datetime.now()
            dtg=datetime.strftime(now, '-%Y-%m-%d %H:%M:%S\r\n')
            write_ceilo(dtg)
            write_ceilo(''.join(CT12Name))
            write_ceilo(response)

Что я могу сделать, чтобы это вращалось автоматически, проставляя либо дату вращения, либо серийный номер для идентификации. Я не собираюсь менять какие-либо из них, просто веду ежедневный журнал данных. (или, может быть, почасовой файл?)


person GerryC    schedule 29.09.2013    source источник
comment
Вместо этого я бы порекомендовал вам изучить logrotate. linuxcommand.org/man_pages/logrotate8.html   -  person Lennart Regebro    schedule 29.09.2013
comment
Вполне возможно. Я надеялся научиться использовать инструменты в Python, но я могу пойти по более простому (и более понятному, по крайней мере для меня) пути.   -  person GerryC    schedule 29.09.2013


Ответы (3)


Вы можете просто сделать это:

import os
import time
date1 = time.strftime('%Y%m%d%H%M%S')
cmd1= "cp logfile logfile{0}".format(date1)
cmd2= "cat /dev/null > logfile"
os.system(cmd1)
os.system(cmd2)

'logfile' - это имя файла. Я скопировал старый журнал в новый файл журнала с именем, основанным на времени и дате, а затем очистил исходный файл. Если вы хотите менять его каждый час, поместите этот скрипт в cron.

person Abhishek dot py    schedule 29.09.2013
comment
Спасибо, это будет работать очень хорошо. Из-за того, как я пишу в файл журнала, он создаст новый, если я просто сделаю cmd1 «mv» вместо «cp», я полагаю. Хотя я надеялся немного узнать об инструментах ведения журналов в Python, имея это в руках, я могу потратить некоторое время на эксперименты. Цените совет! - person GerryC; 29.09.2013

Для тех, кому не нравится идея ротации файлов, а просто хочется использовать обработчик файлов, который сразу записывает в файл с определенной датой в имени: написать свой собственный обработчик несложно. Вот пример:

class FileHandlerWithOneFilePerPeriod(FileHandler):
"""A handler which writes formatted logging records to files, one file per period."""

def __init__(self, filename_pattern, mode='a', encoding=None, delay=False):
    """
    Constructs the file handler.

    :param filename_pattern: the filename. Use strftime() directives to specify the format of the period.
    For example, %Y%m%d can be used to generate one log file per day.
    :param mode: the mode to open the file before writing. Common values are 'w' for writing (truncating the file
    if it already exists), 'x' for creating and writing to a new file, and 'a' for appending (which on some Unix
    systems, means that all writes append to the end of the file regardless of the current seek position).
    :param encoding: encoding is the name of the encoding used to decode or encode the file. This should only be
    used in text mode.
    :param delay: True if the file is opened when the first log message is emitted; False if the file is opened now
    by the constructor.
    """
    self.filename_pattern = filename_pattern
    filename = datetime.now().strftime(self.filename_pattern)
    super().__init__(filename, mode, encoding, delay)

def emit(self, record: LogRecord):
    new_filename = datetime.fromtimestamp(record.created).strftime(self.filename_pattern)
    if self.stream is None:
        self.set_new_filename(new_filename)
    elif self.differs_from_current_filename(new_filename):
        self.close()
        self.set_new_filename(new_filename)

    super().emit(record)

def set_new_filename(self, new_filename):
    self.baseFilename = new_filename

def differs_from_current_filename(self, filename: str) -> bool:
    return filename != self.baseFilename

Чтобы использовать этот обработчик, настройте его со следующими значениями в словаре (используя logging.config.dictConfig():

version: 1
formatters:
  simple:
    format: '%(asctime)s %(name)s %(levelname)s %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
  file:
    class: my_package.my_module.FileHandlerWithOneFilePerPeriod
    level: DEBUG
    formatter: simple
    filename_pattern: my_logging-%Y%m%d.log
root:
  level: DEBUG
  handlers: [console, file]

Это войдет в консоль и в файл. Используется один файл в день. Измените my_package и my_module, чтобы они соответствовали модулю, в который вы поместили обработчик. Измените my_logging на более подходящее имя.

Изменяя шаблон даты в filename_pattern, вы фактически контролируете создание новых файлов. Каждый раз, когда шаблон, примененный к дате и времени создания сообщения журнала, отличается от предыдущего примененного шаблона, будет создан новый файл.

person gogognome    schedule 10.04.2019

person    schedule
comment
Это не работает, если код Python или приложение, которое ведет журнал, не работает постоянно. Вы знаете решение для этого? - person Adarsh Trivedi; 18.01.2019
comment
Журналы @AdarshTrivedi не будут создаваться, пока процесс не запущен, но они будут правильно подобраны при следующем запуске процесса (добавление к журналу текущего дня или создание нового дня в зависимости от ситуации). Если вам нужен отдельный процесс ведения журнала, который всегда выполняется, вы можете объединить его с регистратором очереди или использовать средство ведения журнала вашей операционной системы, но оба эти вопроса должны быть новыми. Надеюсь, это поможет! - person ZachP; 19.01.2019