Add support for custom log timestamps.

Closes #1121.
This commit is contained in:
Roger Light 2019-03-12 23:28:54 +00:00 committed by Roger A. Light
parent a57bba0aae
commit 1a234323a3
5 changed files with 90 additions and 3 deletions

View File

@ -407,6 +407,21 @@
<para>Reloaded on reload signal.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>log_timestamp_format</option> <replaceable>format</replaceable></term>
<listitem>
<para>Set the format of the log timestamp. If left unset,
this is the number of seconds since the Unix epoch.
This option is a free text string which will be passed
to the strftime function as the format specifier. To
get an ISO 8601 datetime, for example:</para>
<programlisting language="config">
log_timestamp_format %Y-%m-%dT%H:%M:%S
</programlisting>
<para>Reloaded on reload signal.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>log_type</option> <replaceable>types</replaceable></term>
<listitem>

View File

@ -610,6 +610,13 @@
# If set to true, add a timestamp value to each log message.
#log_timestamp true
# Set the format of the log timestamp. If left unset, this is the number of
# seconds since the Unix epoch.
# This is a free text string which will be passed to the strftime function. To
# get an ISO 8601 datetime, for example:
# log_timestamp_format %Y-%m-%dT%H:%M:%S
#log_timestamp_format
# =================================================================
# Security
# =================================================================

View File

@ -213,6 +213,8 @@ static void config__init_reload(struct mosquitto_db *db, struct mosquitto__confi
}
#endif
config->log_timestamp = true;
mosquitto__free(config->log_timestamp_format);
config->log_timestamp_format = NULL;
config->max_keepalive = 65535;
config->max_packet_size = 0;
config->max_inflight_messages = 20;
@ -571,6 +573,9 @@ void config__copy(struct mosquitto__config *src, struct mosquitto__config *dest)
dest->log_type = src->log_type;
dest->log_timestamp = src->log_timestamp;
mosquitto__free(dest->log_timestamp_format);
dest->log_timestamp_format = src->log_timestamp_format;
mosquitto__free(dest->log_file);
dest->log_file = src->log_file;
@ -1460,6 +1465,8 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
#endif
}else if(!strcmp(token, "log_timestamp")){
if(conf__parse_bool(&token, token, &config->log_timestamp, saveptr)) return MOSQ_ERR_INVAL;
}else if(!strcmp(token, "log_timestamp_format")){
if(conf__parse_string(&token, token, &config->log_timestamp_format, saveptr)) return MOSQ_ERR_INVAL;
}else if(!strcmp(token, "log_type")){
token = strtok_r(NULL, " ", &saveptr);
if(token){

View File

@ -56,6 +56,43 @@ static int log_priorities = MOSQ_LOG_ERR | MOSQ_LOG_WARNING | MOSQ_LOG_NOTICE |
static DltContext dltContext;
#endif
static int get_time(struct tm **ti)
{
#ifdef WIN32
SYSTEMTIME st;
#elif defined(__APPLE__)
struct timeval tv;
#else
struct timespec ts;
#endif
time_t s;
#ifdef WIN32
s = time(NULL);
GetLocalTime(&st);
*ns = st.wMilliseconds*1000000L;
#elif defined(__APPLE__)
gettimeofday(&tv, NULL);
s = tv.tv_sec;
#else
if(clock_gettime(CLOCK_REALTIME, &ts) != 0){
fprintf(stderr, "Error obtaining system time.\n");
return 1;
}
s = ts.tv_sec;
#endif
*ti = localtime(&s);
if(!(*ti)){
fprintf(stderr, "Error obtaining system time.\n");
return 1;
}
return 0;
}
int log__init(struct mosquitto__config *config)
{
int rc = 0;
@ -149,6 +186,7 @@ int log__vprintf(int priority, const char *fmt, va_list va)
int syslog_priority;
time_t now = time(NULL);
static time_t last_flush = 0;
char time_buf[50];
if((log_priorities & priority) && log_destinations != MQTT3_LOG_NONE){
switch(priority){
@ -233,9 +271,20 @@ int log__vprintf(int priority, const char *fmt, va_list va)
vsnprintf(s, len, fmt, va);
s[len-1] = '\0'; /* Ensure string is null terminated. */
if(int_db.config && int_db.config->log_timestamp && int_db.config->log_timestamp_format){
struct tm *ti = NULL;
get_time(&ti);
if(strftime(time_buf, 50, int_db.config->log_timestamp_format, ti) == 0){
snprintf(time_buf, 50, "Time error");
}
}
if(log_destinations & MQTT3_LOG_STDOUT){
if(int_db.config && int_db.config->log_timestamp){
fprintf(stdout, "%d: %s\n", (int)now, s);
if(int_db.config->log_timestamp_format){
fprintf(stdout, "%s: %s\n", time_buf, s);
}else{
fprintf(stdout, "%d: %s\n", (int)now, s);
}
}else{
fprintf(stdout, "%s\n", s);
}
@ -243,7 +292,11 @@ int log__vprintf(int priority, const char *fmt, va_list va)
}
if(log_destinations & MQTT3_LOG_STDERR){
if(int_db.config && int_db.config->log_timestamp){
fprintf(stderr, "%d: %s\n", (int)now, s);
if(int_db.config->log_timestamp_format){
fprintf(stderr, "%s: %s\n", time_buf, s);
}else{
fprintf(stderr, "%d: %s\n", (int)now, s);
}
}else{
fprintf(stderr, "%s\n", s);
}
@ -251,7 +304,11 @@ int log__vprintf(int priority, const char *fmt, va_list va)
}
if(log_destinations & MQTT3_LOG_FILE && int_db.config->log_fptr){
if(int_db.config && int_db.config->log_timestamp){
fprintf(int_db.config->log_fptr, "%d: %s\n", (int)now, s);
if(int_db.config->log_timestamp_format){
fprintf(int_db.config->log_fptr, "%s: %s\n", time_buf, s);
}else{
fprintf(int_db.config->log_fptr, "%d: %s\n", (int)now, s);
}
}else{
fprintf(int_db.config->log_fptr, "%s\n", s);
}

View File

@ -255,6 +255,7 @@ struct mosquitto__config {
int log_facility;
int log_type;
bool log_timestamp;
char *log_timestamp_format;
char *log_file;
FILE *log_fptr;
uint16_t max_inflight_messages;