Linux 如何在日志文件中引入日期和时间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7411301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to introduce date and time in log file
提问by Thangaraj
I have one daemon written in C. I am logging the events in a log file, but now I want to add date and time while writing event to log file. How can I achieve that?
我有一个用 C 编写的守护进程。我将事件记录在日志文件中,但现在我想在将事件写入日志文件时添加日期和时间。我怎样才能做到这一点?
Current log file:-
当前日志文件:-
Event one occurred: result:
Event two occurred: result:
I want the log file to look like:-
我希望日志文件看起来像:-
Sep 14 11:35:55 Event one occurred: result:
Sep 14 11:35:55 Event two occurred: result:
My environment is C and Linux.
我的环境是 C 和 Linux。
采纳答案by paxdiablo
You need to look into using date
and either gmtime
or localtime
to get the actual date and time.
您需要考虑使用date
andgmtime
或localtime
获取实际日期和时间。
Then strftime
can format it for you.
然后strftime
可以为您格式化。
Sample program follows:
示例程序如下:
#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;
}
This outputs:
这输出:
2011-09-14 04:52:11 Event occurred now
I prefer the use of UTC rather than local time since it allows you to tie together events from geographically separated machine without worrying about timezone differences. In other words, use gmtime
rather than localtime
unless you're verycertain you won't be crossing timezones.
我更喜欢使用 UTC 而不是本地时间,因为它允许您将来自不同地理位置的机器的事件联系在一起,而不必担心时区差异。换句话说,除非您非常确定不会跨越时区,否则请使用gmtime
而不是。localtime
I also tend to prefer the YYYY-MM-DD HH:MM:SS
format since it's easier to sort than month names, vital for extraction and manipulation tools.
我也倾向于更喜欢这种YYYY-MM-DD HH:MM:SS
格式,因为它比月份名称更容易排序,这对于提取和操作工具至关重要。
If you have an implementation that provides the optional bounds-checking functions (as per Appendix K of C11), you can probably use gmtime_s
in preference. It allows you to specify your ownbuffer for receiving the result and is thus safer in re-entrant and/or threaded code.
如果您有一个提供可选边界检查功能的实现(根据 C11 的附录 K),您可能可以gmtime_s
优先使用。它允许您指定自己的缓冲区来接收结果,因此在可重入和/或线程代码中更安全。
To use that, you need to change your code to something like:
要使用它,您需要将代码更改为:
#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;
}
Although you should be aware that the folks at Microsoft have somehow managed to get the arguments for gmtime_s
around the wrong way. You'll need to take that into account.
尽管您应该知道,Microsoft 的人们以某种方式设法以gmtime_s
错误的方式获得了争论。你需要考虑到这一点。
POSIX (and Linux) also provides a gmtime_r
function which performs in the same way as the standard gmtime_s
function (with the arguments in the correctorder).
POSIX(和 Linux)还提供了一个gmtime_r
函数,其执行方式与标准gmtime_s
函数相同(参数顺序正确)。
回答by ocodo
To get the current time you can use time.h
for example...
要获取当前时间,您可以使用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;
}
You can also use strftime
as suggested by paxdiablo for more time/date formatting possibilities.
您还可以strftime
按照 paxdiablo 的建议使用以获取更多时间/日期格式的可能性。
Of course, for your case, the result of ctime(&now)
will go into your log entry char array/string instead of printf
.
当然,对于您的情况,结果ctime(&now)
将进入您的日志条目字符数组/字符串而不是printf
.
回答by inolasco
Adding my log functions, based on the answer by @paxdiablo. Using local time, but could use gmt just by modifying getFormattedTime()
根据@paxdiablo 的回答添加我的日志功能。使用本地时间,但可以通过修改 getFormattedTime() 来使用 gmt
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;
}
You can use them like this:
您可以像这样使用它们:
LOGDEBUG("This is a log");
LOGDEBUG("This is a log with params %d", 42);
Which produces the output:
产生输出:
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
回答by chen_767
based on the answer by @inolasco, static variable is not thread safe. using local variable instead.
根据@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__)
call them like this:
像这样称呼他们:
info("%s", "a log");
infol("%s", "a log");
produce:
生产:
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