Как ввести дату и время в лог-файл - PullRequest
9 голосов
/ 14 сентября 2011

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

Текущий файл журнала: -

Event one occurred: result:
Event two occurred: result:

Я хочу, чтобы файл журнала выглядел следующим образом: -

Sep 14 11:35:55 Event one occurred: result:
Sep 14 11:35:55 Event two occurred: result:

Моя среда C иLinux.

Ответы [ 4 ]

13 голосов
/ 14 сентября 2011

Вам нужно использовать date и либо gmtime, либо localtime, чтобы получить фактическую дату и время.

Тогда strftime может отформатировать его для вас.

Пример программы следующий:

#include <stdio.h>
#include <time.h>

int main (void) {
    char buff[20];
    struct tm *sTm;

    time_t now = time (0);
    sTm = gmtime (&now);

    strftime (buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", sTm);
    printf ("%s %s\n", buff, "Event occurred now");

    return 0;
}

Это выводит:

2011-09-14 04:52:11 Event occurred now

Я предпочитаю использовать UTC, а не местное время, поскольку оно позволяет связывать события с географически разделенной машины, не беспокоясь о различиях часовых поясов. Другими словами, используйте gmtime вместо localtime, если вы не очень уверены, что не будете пересекать часовые пояса.

Я также предпочитаю формат YYYY-MM-DD HH:MM:SS, поскольку его легче сортировать, чем названия месяцев, что очень важно для инструментов извлечения и манипулирования.


Если у вас есть реализация, предоставляющая дополнительные функции проверки границ (согласно Приложению K к C11), вы, вероятно, можете использовать gmtime_s в предпочтении. Он позволяет вам указать свой собственный буфер для получения результата и, таким образом, безопаснее в повторно вводимом и / или многопоточном коде.

Чтобы использовать это, вам нужно изменить код на что-то вроде:

#include <stdio.h>
#define __STDC_WANT_LIB_EXT1__ 1
#include <time.h>

int main (void) {
    char buff[20];
    struct tm sTm;

    time_t now = time (0);
    gmtime_s (&now, &sTm);

    strftime (buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", &sTm);
    printf ("%s %s\n", buff, "Event occurred now");

    return 0;
}

Хотя вы должны знать, что ребята из Microsoft каким-то образом сумели получить аргументы для gmtime_s в неправильном направлении. Вы должны будете принять это во внимание.

POSIX (и Linux) также предоставляет функцию gmtime_r, которая выполняет те же функции, что и стандартная функция gmtime_s (с аргументами в правильном порядке).

7 голосов
/ 19 марта 2014

Добавление моих функций журнала, основанных на ответе @paxdiablo.Используя местное время, но можно использовать gmt, просто изменив getFormattedTime ()

common.h

// Returns the local date/time formatted as 2014-03-19 11:11:52
char* getFormattedTime(void);

// Remove path from filename
#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

// Main log macro
#define __LOG__(format, loglevel, ...) printf("%s %-5s [%s] [%s:%d] " format "\n", getFormattedTime(), loglevel, __func__, __SHORT_FILE__, __LINE__, ## __VA_ARGS__)

// Specific log macros with 
#define LOGDEBUG(format, ...) __LOG__(format, "DEBUG", ## __VA_ARGS__)
#define LOGWARN(format, ...) __LOG__(format, "WARN", ## __VA_ARGS__)
#define LOGERROR(format, ...) __LOG__(format, "ERROR", ## __VA_ARGS__)
#define LOGINFO(format, ...) __LOG__(format, "INFO", ## __VA_ARGS__)

common.c

#include <time.h> // time_t, tm, time, localtime, strftime

// Returns the local date/time formatted as 2014-03-19 11:11:52
char* getFormattedTime(void) {

    time_t rawtime;
    struct tm* timeinfo;

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    // Must be static, otherwise won't work
    static char _retval[20];
    strftime(_retval, sizeof(_retval), "%Y-%m-%d %H:%M:%S", timeinfo);

    return _retval;
}

Вы можете использовать их следующим образом:

 LOGDEBUG("This is a log");
 LOGDEBUG("This is a log with params %d", 42);

, который производит вывод:

2014-03-19 13:22:14 DEBUG [main] [main.c:54] This is a log
2014-03-19 13:22:14 DEBUG [main] [main.c:55] This is a log with params 42
4 голосов
/ 14 сентября 2011

Для получения текущего времени вы можете использовать time.h, например ...

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
  time_t now;
  time(&now);

  printf("%s", ctime(&now)); // use ctime to format time to a string.

  return EXIT_SUCCESS;
}

Вы также можете использовать strftime, как предложеноpaxdiablo для большего количества возможностей форматирования времени / даты.

Конечно, для вашего случая результат ctime(&now) войдет в массив / строку char вашей записи вместо printf.

1 голос
/ 06 сентября 2017

на основе ответа @inolasco, статическая переменная не является поточно-ориентированной.используя вместо этого локальную переменную.

void getFormattedTime(char * const p, int sz) {
    time_t rawtime;
    struct tm* timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    strftime(p, sz, "%Y-%m-%d %H:%M:%S", timeinfo);
}

int mylog(const char* fmt, ...) {
    // TODO: log to file also.
    // TODO: create a new log file daily
    va_list argptr;
    va_start(argptr, fmt);
    vfprintf(stderr, fmt, argptr);//log to stderr
    va_end(argptr);
}


#ifdef _WIN32
#define __SHORT_FILE__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#else
#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif

#define  ___LOG___(fmt,level,path, ...) do{\
    /* using local var and using a long name to avoid conflict*/ \
    char LAgGV3nzJsTholGvGL2eTNXmhsqYe___xxooxxoo___[24];\
    getFormattedTime(LAgGV3nzJsTholGvGL2eTNXmhsqYe___xxooxxoo___,\
        sizeof(LAgGV3nzJsTholGvGL2eTNXmhsqYe___xxooxxoo___));\
    mylog("%s [%s] [%s:%d] [%s] " fmt "\n", \
        LAgGV3nzJsTholGvGL2eTNXmhsqYe___xxooxxoo___, \
        level,\
        path,\
        __LINE__, \
        __func__, \
        ## __VA_ARGS__);\
}while(0)

#define  trace(fmt, ...) ___LOG___(fmt, "TRACE",__SHORT_FILE__, ## __VA_ARGS__)
#define  debug(fmt, ...) ___LOG___(fmt, "DEBUG",__SHORT_FILE__, ## __VA_ARGS__)
#define   info(fmt, ...) ___LOG___(fmt,  "INFO",__SHORT_FILE__, ## __VA_ARGS__)
#define   warn(fmt, ...) ___LOG___(fmt,  "WARN",__SHORT_FILE__, ## __VA_ARGS__)
#define  error(fmt, ...) ___LOG___(fmt, "ERROR",__SHORT_FILE__, ## __VA_ARGS__)
#define tracel(fmt, ...) ___LOG___(fmt, "TRACE",      __FILE__, ## __VA_ARGS__)
#define debugl(fmt, ...) ___LOG___(fmt, "DEBUG",      __FILE__, ## __VA_ARGS__)
#define  infol(fmt, ...) ___LOG___(fmt,  "INFO",      __FILE__, ## __VA_ARGS__)
#define  warnl(fmt, ...) ___LOG___(fmt,  "WARN",      __FILE__, ## __VA_ARGS__)
#define errorl(fmt, ...) ___LOG___(fmt, "ERROR",      __FILE__, ## __VA_ARGS__)

называйте их так:

info("%s", "a log");
infol("%s", "a log");

производите:

2017-09-06 15:55:42 [INFO] [main.c:25] [main] a log
2017-09-06 15:58:08 [INFO] [d:\main.c:25] [main] a log
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...