MEDIUM: logs: remove the hostname, tag and pid part from the logheader
At the moment we have to call snprintf() for every log line just to rebuild a constant. Thanks to sendmsg(), we send the message in 3 parts: time-based header, proxy-specific hostname+log-tag+pid, session-specific message.
This commit is contained in:
parent
59cee973cd
commit
68d2e3a742
@ -138,6 +138,11 @@ char *lf_ip(char *dst, struct sockaddr *sockaddr, size_t size, struct logformat_
|
||||
*/
|
||||
char *lf_port(char *dst, struct sockaddr *sockaddr, size_t size, struct logformat_node *node);
|
||||
|
||||
/*
|
||||
* Write hostname, log_tag and pid to the log string
|
||||
*/
|
||||
char *lf_host_tag_pid(char *dst, const char *hostname, const char *log_tag, int pid, size_t size);
|
||||
|
||||
|
||||
#endif /* _PROTO_LOG_H */
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#define NB_LOG_FACILITIES 24
|
||||
#define NB_LOG_LEVELS 8
|
||||
#define NB_MSG_IOVEC_ELEMENTS 2
|
||||
#define NB_MSG_IOVEC_ELEMENTS 3
|
||||
#define SYSLOG_PORT 514
|
||||
#define UNIQUEID_LEN 128
|
||||
|
||||
|
@ -346,6 +346,7 @@ struct proxy {
|
||||
struct list logsrvs;
|
||||
struct list logformat; /* log_format linked list */
|
||||
char *log_tag; /* override default syslog tag */
|
||||
struct chunk log_htp; /* a syslog header part that contains hostname, log_tag and pid */
|
||||
char *header_unique_id; /* unique-id header */
|
||||
struct list format_unique_id; /* unique-id format */
|
||||
int to_log; /* things to be logged (LW_*) */
|
||||
|
@ -7818,6 +7818,27 @@ int check_config_validity()
|
||||
}
|
||||
out_uri_auth_compat:
|
||||
|
||||
/* write a syslog header string that contains hostname, log_tag and pid */
|
||||
curproxy->log_htp.str = lf_host_tag_pid(logheader,
|
||||
global.log_send_hostname ? global.log_send_hostname : "",
|
||||
curproxy->log_tag ? curproxy->log_tag : global.log_tag, pid,
|
||||
global.max_syslog_len);
|
||||
|
||||
if ((curproxy->log_htp.str == NULL) ||
|
||||
(curproxy->log_htp.len = curproxy->log_htp.str - logheader) >= global.max_syslog_len) {
|
||||
Alert("Proxy '%s': cannot write a syslog header string that contains "
|
||||
"hostname, log_tag and pid.\n",
|
||||
curproxy->id);
|
||||
cfgerr++;
|
||||
}
|
||||
else {
|
||||
curproxy->log_htp.str = (char *)malloc(curproxy->log_htp.len);
|
||||
memcpy(curproxy->log_htp.str, logheader, curproxy->log_htp.len);
|
||||
curproxy->log_htp.size = 0;
|
||||
}
|
||||
|
||||
logheader[0] = 0;
|
||||
|
||||
/* compile the log format */
|
||||
if (!(curproxy->cap & PR_CAP_FE)) {
|
||||
if (curproxy->conf.logformat_string != default_http_log_format &&
|
||||
|
@ -1328,6 +1328,7 @@ void deinit(void)
|
||||
LIST_DEL(&log->list);
|
||||
free(log);
|
||||
}
|
||||
chunk_destroy(&p->log_htp);
|
||||
|
||||
list_for_each_entry_safe(lf, lfb, &p->logformat, list) {
|
||||
LIST_DEL(&lf->list);
|
||||
|
54
src/log.c
54
src/log.c
@ -152,8 +152,7 @@ char default_tcp_log_format[] = "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%
|
||||
char *log_format = NULL;
|
||||
|
||||
/* This is a global syslog header, common to all outgoing messages. It
|
||||
* begins with the syslog tag and the date that are updated by
|
||||
* update_log_hdr().
|
||||
* begins with time-based part and is updated by update_log_hdr().
|
||||
*/
|
||||
char *logheader = NULL;
|
||||
|
||||
@ -740,14 +739,26 @@ char *lf_port(char *dst, struct sockaddr *sockaddr, size_t size, struct logforma
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *lf_host_tag_pid(char *dst, const char *hostname, const char *log_tag, int pid, size_t size)
|
||||
{
|
||||
char *ret = dst;
|
||||
int iret;
|
||||
|
||||
iret = snprintf(dst, size, "%s%s[%d]: ", hostname, log_tag, pid);
|
||||
if (iret < 0 || iret > size)
|
||||
return NULL;
|
||||
ret += iret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Re-generate the syslog header at the beginning of logheader once a second and
|
||||
* return the pointer to the first character after the header.
|
||||
*/
|
||||
static char *update_log_hdr(const char *log_tag)
|
||||
char *update_log_hdr()
|
||||
{
|
||||
static long tvsec;
|
||||
static char *dataptr = NULL; /* backup of last end of header, NULL first time */
|
||||
int tag_len;
|
||||
|
||||
if (unlikely(date.tv_sec != tvsec || dataptr == NULL)) {
|
||||
/* this string is rebuild only once a second */
|
||||
@ -758,10 +769,9 @@ static char *update_log_hdr(const char *log_tag)
|
||||
get_localtime(tvsec, &tm);
|
||||
|
||||
hdr_len = snprintf(logheader, global.max_syslog_len,
|
||||
"<<<<>%s %2d %02d:%02d:%02d %s",
|
||||
"<<<<>%s %2d %02d:%02d:%02d ",
|
||||
monthname[tm.tm_mon],
|
||||
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
global.log_send_hostname ? global.log_send_hostname : "");
|
||||
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
/* WARNING: depending upon implementations, snprintf may return
|
||||
* either -1 or the number of bytes that would be needed to store
|
||||
* the total message. In both cases, we must adjust it.
|
||||
@ -774,11 +784,7 @@ static char *update_log_hdr(const char *log_tag)
|
||||
|
||||
dataptr[0] = 0; // ensure we get rid of any previous attempt
|
||||
|
||||
tag_len = snprintf(dataptr, logheader + global.max_syslog_len - dataptr, "%s[%d]: ", log_tag, pid);
|
||||
if (tag_len < 0 || tag_len > logheader + global.max_syslog_len - dataptr)
|
||||
tag_len = logheader + global.max_syslog_len - dataptr;
|
||||
|
||||
return dataptr + tag_len;
|
||||
return dataptr;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -821,7 +827,6 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
|
||||
struct list *logsrvs = NULL;
|
||||
struct logsrv *tmp = NULL;
|
||||
int nblogger;
|
||||
char *log_tag = global.log_tag;
|
||||
char *log_ptr;
|
||||
char *hdr_ptr;
|
||||
size_t hdr_size;
|
||||
@ -836,15 +841,12 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
|
||||
if (!LIST_ISEMPTY(&p->logsrvs)) {
|
||||
logsrvs = &p->logsrvs;
|
||||
}
|
||||
if (p->log_tag) {
|
||||
log_tag = p->log_tag;
|
||||
}
|
||||
}
|
||||
|
||||
if (!logsrvs)
|
||||
return;
|
||||
|
||||
hdr_ptr = update_log_hdr(log_tag);
|
||||
hdr_ptr = update_log_hdr();
|
||||
hdr_size = hdr_ptr - logheader;
|
||||
|
||||
/* Send log messages to syslog server. */
|
||||
@ -854,7 +856,9 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
|
||||
int *plogfd = logsrv->addr.ss_family == AF_UNIX ?
|
||||
&logfdunix : &logfdinet;
|
||||
int sent;
|
||||
int maxlen;
|
||||
int hdr_max = 0;
|
||||
int htp_max = 0;
|
||||
int max = 1;
|
||||
char backup;
|
||||
|
||||
@ -904,7 +908,15 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
|
||||
goto send;
|
||||
}
|
||||
|
||||
max = MIN(size, logsrv->maxlen - hdr_max);
|
||||
maxlen = logsrv->maxlen - hdr_max;
|
||||
htp_max = p->log_htp.len;
|
||||
|
||||
if (unlikely(htp_max >= maxlen)) {
|
||||
htp_max = maxlen - 1;
|
||||
goto send;
|
||||
}
|
||||
|
||||
max = MIN(size, maxlen - htp_max);
|
||||
|
||||
log_ptr += max - 1;
|
||||
|
||||
@ -918,8 +930,10 @@ send:
|
||||
|
||||
iovec[0].iov_base = hdr_ptr;
|
||||
iovec[0].iov_len = hdr_max;
|
||||
iovec[1].iov_base = dataptr;
|
||||
iovec[1].iov_len = max;
|
||||
iovec[1].iov_base = p->log_htp.str;
|
||||
iovec[1].iov_len = htp_max;
|
||||
iovec[2].iov_base = dataptr;
|
||||
iovec[2].iov_len = max;
|
||||
|
||||
msghdr.msg_name = (struct sockaddr *)&logsrv->addr;
|
||||
msghdr.msg_namelen = get_addr_len(&logsrv->addr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user