2011-09-14 68 views
7

我有一个用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。

+0

@Jonathan莱弗勒,我面临的,因为很长一段时间,这些调整问题,有没有参考页至REF,并采取照顾自己? – Thangaraj

+1

你的意思是你的问题中的布局?输入评论时,有一个帮助超链接;当输入问题或答案时,会有一个橙色问号提供打字区域上方的帮助。缩进4个空格将以下代码作为代码处理;避免制表符。项目符号列表具有以星号或短划线('*'或'-')开头的行;你可以嵌套它们(子项目缩进2个或更多的空格),并且你可以有与它们相关的代码(前缀为8个空格,而不是4个,但是对于第一级项目符号)。编号列表有从'1'开始的行(这个点很重要)。等等 –

+0

@Jonathan Leffler,谢谢 – Thangaraj

回答

12

您需要查看使用dategmtimelocaltime以获取实际日期和时间。

然后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格式,因为它比月份名称更容易排序,这对于提取和操作工具来说至关重要。

+0

这些库的使用是否会导致可移植性问题? – Thangaraj

+0

这些都是纯粹的C89功能 - 它们大概就像你可以合理希望的那样便携。守护进程的许多其他部分不易携带,这是肯定的。 –

+0

@Thangaraj:不,它们都是在ISO C中定义的,就像你可以得到的便携一样:-) – paxdiablo

4

为了得到当前的时间,你可以使用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)的结果将进入您的日志条目字符数组/字符串而不是printf

+0

它可能会更好(虽然基本上等价)使用:'time_t now = time(0);'。 –

+0

@Jonathan Leffler - 学术真的但是是的,基本相同。无论如何,paxdiablo的答案比我现在的答案更完整,我只是发布这个来鼓励他添加一个代码示例。 ;) – ocodo

+0

gr8后...帮助我很多...谢谢 – 2vision2

6

根据@paxdiablo的回答添加我的日志功能。使用本地时间,但可能只是通过修改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; 
} 

您可以使用它们像这样使用GMT:

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 
1

根据@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 
相关问题