python logging - удалить временную метку в расширении файла [duplicate]

Насколько мне известно, три наиболее популярных способа анализа аргументов командной строки в C:

  • Getopt (#include из библиотеки POSIX C), который может решить простой анализ аргументов . Если вы немного знакомы с bash, getopt встроенный bash основан на Getopt из GNU libc.
  • Argp (#include из библиотеки GNU C), который может решить больше сложных задач и позаботится о таких вещах, как, например: -?, --help для справочного сообщения , включая адрес электронной почты -V, --version для информации о версии --usage для сообщения об использовании
  • Выполнение этого самостоятельно, что я не рекомендую для программ, которые будут предоставлены кто-то другой, так как слишком много, что может пойти не так или некачественно. Популярная ошибка забывания о «-», чтобы прекратить парсинг параметров - это всего лишь один пример.

В документации библиотеки GNU C есть несколько хороших примеров для Getopt и Argp.

Пример использования Getopt

#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    bool isCaseInsensitive = false;
    int opt;
    enum { CHARACTER_MODE, WORD_MODE, LINE_MODE } mode = CHARACTER_MODE;

    while ((opt = getopt(argc, argv, "ilw")) != -1) {
        switch (opt) {
        case 'i': isCaseInsensitive = true; break;
        case 'l': mode = LINE_MODE; break;
        case 'w': mode = WORD_MODE; break;
        default:
            fprintf(stderr, "Usage: %s [-ilw] [file...]\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    // Now optind (declared extern int by ) is the index of the first non-option argument.
    // If it is >= argc, there were no non-option arguments.

    // ...
}

Пример для использования Argp

#include 
#include 

const char *argp_program_version = "programname programversion";
const char *argp_program_bug_address = "";
static char doc[] = "Your program description.";
static char args_doc[] = "[FILENAME]...";
static struct argp_option options[] = { 
    { "line", 'l', 0, 0, "Compare lines instead of characters."},
    { "word", 'w', 0, 0, "Compare words instead of characters."},
    { "nocase", 'i', 0, 0, "Compare case insensitive instead of case sensitive."},
    { 0 } 
};

struct arguments {
    enum { CHARACTER_MODE, WORD_MODE, LINE_MODE } mode;
    bool isCaseInsensitive;
};

static error_t parse_opt(int key, char *arg, struct argp_state *state) {
    struct arguments *arguments = state->input;
    switch (key) {
    case 'l': arguments->mode = LINE_MODE; break;
    case 'w': arguments->mode = WORD_MODE; break;
    case 'i': arguments->isCaseInsensitive = true; break;
    case ARGP_KEY_ARG: return 0;
    default: return ARGP_ERR_UNKNOWN;
    }   
    return 0;
}

static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 };

int main(int argc, char *argv[])
{
    struct arguments arguments;

    arguments.mode = CHARACTER_MODE;
    arguments.isCaseInsensitive = false;

    argp_parse(&argp, argc, argv, 0, 0, &arguments);

    // ...
}

Пример для Выполнение себя

#include 
#include 
#include 

int main(int argc, char *argv[])
{   
    bool isCaseInsensitive = false;
    enum { CHARACTER_MODE, WORD_MODE, LINE_MODE } mode = CHARACTER_MODE;
    size_t optind;
    for (optind = 1; optind < argc && argv[optind][0] == '-'; optind++) {
        switch (argv[optind][1]) {
        case 'i': isCaseInsensitive = true; break;
        case 'l': mode = LINE_MODE; break;
        case 'w': mode = WORD_MODE; break;
        default:
            fprintf(stderr, "Usage: %s [-ilw] [file...]\n", argv[0]);
            exit(EXIT_FAILURE);
        }   
    }   

    // *argv points to the remaining non-option arguments.
    // If *argv is NULL, there were no non-option arguments.

    // ...
}   

Отказ от ответственности: я новичок в Argp, пример может содержать ошибки.

1
задан SangminKim 2 September 2016 в 17:26
поделиться

2 ответа

Я наследую и переопределяю RotatingFileHandler обработчика ведения журнала python.

Значение RotatingFileHandler имеет значение self.baseFilename, обработчик будет использовать self.baseFilename для создания logFile. (когда он создает файл первым или когда происходит опрокидывание )

self.shouldRollover() method, Он проверяет, должен ли обработчик листать файл журнала опроса или нет.

Если этот метод return 1, это означает, что произойдет опрокидывание или return 0.

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

----------- ------------------------------Редактировать------------------- ----------------------

Я отправляю код примера.

from logging import handlers

class DailyRotatingFileHandler(handlers.RotatingFileHandler):

    def __init__(self, alias, basedir, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0):
        """
        @summary: 
        Set self.baseFilename to date string of today.
        The handler create logFile named self.baseFilename
        """
        self.basedir_ = basedir
        self.alias_ = alias

        self.baseFilename = self.getBaseFilename()

        handlers.RotatingFileHandler.__init__(self, self.baseFilename, mode, maxBytes, backupCount, encoding, delay)

    def getBaseFilename(self):
        """
        @summary: Return logFile name string formatted to "today.log.alias"
        """
        self.today_ = datetime.date.today()
        basename_ = self.today_.strftime("%Y-%m-%d") + ".log" + '.' + self.alias_
        return os.path.join(self.basedir_, basename_)

    def shouldRollover(self, record):
        """
        @summary: 
        Rollover happen 
        1. When the logFile size is get over maxBytes.
        2. When date is changed.

        @see: BaseRotatingHandler.emit
        """

        if self.stream is None:                
            self.stream = self._open()

        if self.maxBytes > 0 :                  
            msg = "%s\n" % self.format(record)
            self.stream.seek(0, 2)  
            if self.stream.tell() + len(msg) >= self.maxBytes:
                return 1

        if self.today_ != datetime.date.today():
            self.baseFilename = self.getBaseFilename()
            return 1

        return 0

Это DailyRotatingFileHandler создаст файл журнала, например

2016-10-05.log.alias
2016-10-05.log.alias.1
2016-10-05.log.alias.2
2016-10-06.log.alias
2016-10-06.log.alias.1
2016-10-07.log.alias.1
2
ответ дан SangminKim 17 August 2018 в 10:00
поделиться
  • 1
    У вас есть пример кода, как вы это сделали? – FredFury 25 September 2016 в 09:27
  • 2
    @FredFury Я добавляю пример кода, он надеется, что это может вам помочь. – SangminKim 5 October 2016 в 11:56

Проверьте следующий код и посмотрите, помогает ли он. Насколько я понял из вашего вопроса, если ваша проблема заключается в достижении имени файла на основе метки времени, это будет работать для вас.

import datetime, time
# This return the epoch timestamp    
epochTime = time.time()
# We generate the timestamp 
# as per the need
timeStamp = datetime.datetime\
                    .fromtimestamp(epochTime)\
                    .strftime('%Y-%m-%d-%H-%M')
# Create a log file 
# use timeStamp as filename
fo = open(timeStamp+".log", "wb")
fo.write("Log data")
fo.close()
1
ответ дан Shubhamoy 17 August 2018 в 10:00
поделиться
  • 1
    Я уже знаю, как обрабатывать время и создавать файлы, но я хочу, чтобы протоколы Python упрощали функции ведения журнала Python. это может быть что-то вроде наследования класса ведения журнала и переопределения метода ведения журнала. – SangminKim 2 September 2016 в 17:15
Другие вопросы по тегам:

Похожие вопросы: