mirror of
https://github.com/nginx/nginx.git
synced 2024-11-27 15:39:01 +08:00
Added syslog support for error_log and access_log directives.
This commit is contained in:
parent
1736c180f4
commit
493b898ae9
@ -37,7 +37,8 @@ CORE_DEPS="src/core/nginx.h \
|
||||
src/core/ngx_resolver.h \
|
||||
src/core/ngx_open_file_cache.h \
|
||||
src/core/ngx_crypt.h \
|
||||
src/core/ngx_proxy_protocol.h"
|
||||
src/core/ngx_proxy_protocol.h \
|
||||
src/core/ngx_syslog.h"
|
||||
|
||||
|
||||
CORE_SRCS="src/core/nginx.c \
|
||||
@ -69,7 +70,8 @@ CORE_SRCS="src/core/nginx.c \
|
||||
src/core/ngx_resolver.c \
|
||||
src/core/ngx_open_file_cache.c \
|
||||
src/core/ngx_crypt.c \
|
||||
src/core/ngx_proxy_protocol.c"
|
||||
src/core/ngx_proxy_protocol.c \
|
||||
src/core/ngx_syslog.c"
|
||||
|
||||
|
||||
REGEX_MODULE=ngx_regex_module
|
||||
|
@ -77,6 +77,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
|
||||
#include <ngx_open_file_cache.h>
|
||||
#include <ngx_os.h>
|
||||
#include <ngx_connection.h>
|
||||
#include <ngx_syslog.h>
|
||||
#include <ngx_proxy_protocol.h>
|
||||
|
||||
|
||||
|
@ -148,6 +148,12 @@ ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
|
||||
break;
|
||||
}
|
||||
|
||||
if (log->writer) {
|
||||
log->writer(log, level, errstr, p - errstr);
|
||||
log = log->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
(void) ngx_write_fd(log->file->fd, errstr, p - errstr);
|
||||
|
||||
if (log->file->fd == ngx_stderr) {
|
||||
@ -366,15 +372,33 @@ ngx_log_init(u_char *prefix)
|
||||
ngx_int_t
|
||||
ngx_log_open_default(ngx_cycle_t *cycle)
|
||||
{
|
||||
static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH);
|
||||
ngx_log_t *log;
|
||||
static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH);
|
||||
|
||||
if (cycle->new_log.file == NULL) {
|
||||
cycle->new_log.file = ngx_conf_open_file(cycle, &error_log);
|
||||
if (cycle->new_log.file == NULL) {
|
||||
if (ngx_log_get_file_log(&cycle->new_log) != NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (cycle->new_log.log_level != 0) {
|
||||
/* there are some error logs, but no files */
|
||||
|
||||
log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
|
||||
if (log == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cycle->new_log.log_level = NGX_LOG_ERR;
|
||||
log->log_level = NGX_LOG_ERR;
|
||||
ngx_log_insert(&cycle->new_log, log);
|
||||
|
||||
} else {
|
||||
/* no error logs at all */
|
||||
log = &cycle->new_log;
|
||||
log->log_level = NGX_LOG_ERR;
|
||||
}
|
||||
|
||||
log->file = ngx_conf_open_file(cycle, &error_log);
|
||||
if (log->file == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
@ -390,7 +414,8 @@ ngx_log_redirect_stderr(ngx_cycle_t *cycle)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
fd = cycle->log->file->fd;
|
||||
/* file log always exists when we are called */
|
||||
fd = ngx_log_get_file_log(cycle->log)->file->fd;
|
||||
|
||||
if (fd != ngx_stderr) {
|
||||
if (ngx_set_stderr(fd) == NGX_FILE_ERROR) {
|
||||
@ -405,6 +430,21 @@ ngx_log_redirect_stderr(ngx_cycle_t *cycle)
|
||||
}
|
||||
|
||||
|
||||
ngx_log_t *
|
||||
ngx_log_get_file_log(ngx_log_t *head)
|
||||
{
|
||||
ngx_log_t *log;
|
||||
|
||||
for (log = head; log; log = log->next) {
|
||||
if (log->file != NULL) {
|
||||
return log;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
|
||||
{
|
||||
@ -482,8 +522,9 @@ ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
char *
|
||||
ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head)
|
||||
{
|
||||
ngx_log_t *new_log;
|
||||
ngx_str_t *value, name;
|
||||
ngx_log_t *new_log;
|
||||
ngx_str_t *value, name;
|
||||
ngx_syslog_peer_t *peer;
|
||||
|
||||
if (*head != NULL && (*head)->log_level == 0) {
|
||||
new_log = *head;
|
||||
@ -506,13 +547,30 @@ ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head)
|
||||
ngx_str_null(&name);
|
||||
cf->cycle->log_use_stderr = 1;
|
||||
|
||||
} else {
|
||||
name = value[1];
|
||||
}
|
||||
new_log->file = ngx_conf_open_file(cf->cycle, &name);
|
||||
if (new_log->file == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
new_log->file = ngx_conf_open_file(cf->cycle, &name);
|
||||
if (new_log->file == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
|
||||
} else if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) {
|
||||
peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t));
|
||||
if (peer == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
new_log->writer = ngx_syslog_writer;
|
||||
new_log->wdata = peer;
|
||||
|
||||
} else {
|
||||
new_log->file = ngx_conf_open_file(cf->cycle, &value[1]);
|
||||
if (new_log->file == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_log_set_levels(cf, new_log) != NGX_CONF_OK) {
|
||||
|
@ -43,6 +43,8 @@
|
||||
|
||||
|
||||
typedef u_char *(*ngx_log_handler_pt) (ngx_log_t *log, u_char *buf, size_t len);
|
||||
typedef void (*ngx_log_writer_pt) (ngx_log_t *log, ngx_uint_t level,
|
||||
u_char *buf, size_t len);
|
||||
|
||||
|
||||
struct ngx_log_s {
|
||||
@ -54,6 +56,9 @@ struct ngx_log_s {
|
||||
ngx_log_handler_pt handler;
|
||||
void *data;
|
||||
|
||||
ngx_log_writer_pt writer;
|
||||
void *wdata;
|
||||
|
||||
/*
|
||||
* we declare "action" as "char *" because the actions are usually
|
||||
* the static strings and in the "u_char *" case we have to override
|
||||
@ -227,6 +232,7 @@ void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...);
|
||||
u_char *ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err);
|
||||
ngx_int_t ngx_log_open_default(ngx_cycle_t *cycle);
|
||||
ngx_int_t ngx_log_redirect_stderr(ngx_cycle_t *cycle);
|
||||
ngx_log_t *ngx_log_get_file_log(ngx_log_t *head);
|
||||
char *ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head);
|
||||
|
||||
|
||||
|
332
src/core/ngx_syslog.c
Normal file
332
src/core/ngx_syslog.c
Normal file
@ -0,0 +1,332 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Nginx, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_event.h>
|
||||
|
||||
|
||||
#define NGX_SYSLOG_MAX_STR \
|
||||
NGX_MAX_ERROR_STR + sizeof("<255>Jan 01 00:00:00 ") - 1 \
|
||||
+ (NGX_MAXHOSTNAMELEN - 1) + 1 /* space */ \
|
||||
+ 32 /* tag */ + 2 /* colon, space */
|
||||
|
||||
|
||||
static char *ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer);
|
||||
static ngx_int_t ngx_syslog_init_peer(ngx_syslog_peer_t *peer);
|
||||
static void ngx_syslog_cleanup(void *data);
|
||||
|
||||
|
||||
static char *facilities[] = {
|
||||
"kern", "user", "mail", "daemon", "auth", "intern", "lpr", "news", "uucp",
|
||||
"clock", "authpriv", "ftp", "ntp", "audit", "alert", "cron", "local0",
|
||||
"local1", "local2", "local3", "local4", "local5", "local6", "local7",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* note 'error/warn' like in nginx.conf, not 'err/warning' */
|
||||
static char *severities[] = {
|
||||
"emerg", "alert", "crit", "error", "warn", "notice", "info", "debug", NULL
|
||||
};
|
||||
|
||||
static ngx_log_t ngx_syslog_dummy_log;
|
||||
static ngx_event_t ngx_syslog_dummy_event;
|
||||
|
||||
|
||||
char *
|
||||
ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer)
|
||||
{
|
||||
peer->pool = cf->pool;
|
||||
peer->facility = NGX_CONF_UNSET_UINT;
|
||||
peer->severity = NGX_CONF_UNSET_UINT;
|
||||
|
||||
if (ngx_syslog_parse_args(cf, peer) != NGX_CONF_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (peer->server.sockaddr == NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"no syslog server specified");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (peer->facility == NGX_CONF_UNSET_UINT) {
|
||||
peer->facility = 23; /* local7 */
|
||||
}
|
||||
|
||||
if (peer->severity == NGX_CONF_UNSET_UINT) {
|
||||
peer->severity = 6; /* info */
|
||||
}
|
||||
|
||||
if (peer->tag.data == NULL) {
|
||||
ngx_str_set(&peer->tag, "nginx");
|
||||
}
|
||||
|
||||
peer->conn.fd = (ngx_socket_t) -1;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer)
|
||||
{
|
||||
u_char *p, *comma, c;
|
||||
size_t len;
|
||||
ngx_str_t *value;
|
||||
ngx_url_t u;
|
||||
ngx_uint_t i;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
p = value[1].data + sizeof("syslog:") - 1;
|
||||
|
||||
for ( ;; ) {
|
||||
comma = (u_char *) ngx_strchr(p, ',');
|
||||
|
||||
if (comma != NULL) {
|
||||
len = comma - p;
|
||||
*comma = '\0';
|
||||
|
||||
} else {
|
||||
len = value[1].data + value[1].len - p;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(p, "server=", 7) == 0) {
|
||||
|
||||
if (peer->server.sockaddr != NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"duplicate syslog \"server\"");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
|
||||
u.url.data = p + 7;
|
||||
u.url.len = len - 7;
|
||||
u.default_port = 514;
|
||||
|
||||
if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in syslog server \"%V\"",
|
||||
u.err, &u.url);
|
||||
}
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
peer->server = u.addrs[0];
|
||||
|
||||
} else if (ngx_strncmp(p, "facility=", 9) == 0) {
|
||||
|
||||
if (peer->facility != NGX_CONF_UNSET_UINT) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"duplicate syslog \"facility\"");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; facilities[i] != NULL; i++) {
|
||||
|
||||
if (ngx_strcmp(p + 9, facilities[i]) == 0) {
|
||||
peer->facility = i;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unknown syslog facility \"%s\"", p + 9);
|
||||
return NGX_CONF_ERROR;
|
||||
|
||||
} else if (ngx_strncmp(p, "severity=", 9) == 0) {
|
||||
|
||||
if (peer->severity != NGX_CONF_UNSET_UINT) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"duplicate syslog \"severity\"");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; severities[i] != NULL; i++) {
|
||||
|
||||
if (ngx_strcmp(p + 9, severities[i]) == 0) {
|
||||
peer->severity = i;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unknown syslog severity \"%s\"", p + 9);
|
||||
return NGX_CONF_ERROR;
|
||||
|
||||
} else if (ngx_strncmp(p, "tag=", 4) == 0) {
|
||||
|
||||
if (peer->tag.data != NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"duplicate syslog \"tag\"");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 3164: the TAG is a string of ABNF alphanumeric characters
|
||||
* that MUST NOT exceed 32 characters.
|
||||
*/
|
||||
if (len - 4 > 32) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"syslog tag length exceeds 32");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 4; i < len; i++) {
|
||||
c = ngx_tolower(p[i]);
|
||||
|
||||
if (c < '0' || (c > '9' && c < 'a') || c > 'z') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"syslog \"tag\" only allows "
|
||||
"alphanumeric characters");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
peer->tag.data = p + 4;
|
||||
peer->tag.len = len - 4;
|
||||
|
||||
} else {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unknown syslog parameter \"%s\"", p);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
next:
|
||||
|
||||
if (comma == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
p = comma + 1;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
u_char *
|
||||
ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf)
|
||||
{
|
||||
ngx_uint_t pri;
|
||||
|
||||
pri = peer->facility * 8 + peer->severity;
|
||||
|
||||
return ngx_sprintf(buf, "<%ui>%V %V %V: ", pri, &ngx_cached_syslog_time,
|
||||
&ngx_cycle->hostname, &peer->tag);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf,
|
||||
size_t len)
|
||||
{
|
||||
u_char *p, msg[NGX_SYSLOG_MAX_STR];
|
||||
ngx_uint_t head_len;
|
||||
ngx_syslog_peer_t *peer;
|
||||
|
||||
peer = log->wdata;
|
||||
|
||||
if (peer->processing) {
|
||||
return;
|
||||
}
|
||||
|
||||
peer->processing = 1;
|
||||
peer->severity = level - 1;
|
||||
|
||||
p = ngx_syslog_add_header(peer, msg);
|
||||
head_len = p - msg;
|
||||
|
||||
len -= NGX_LINEFEED_SIZE;
|
||||
|
||||
if (len > NGX_SYSLOG_MAX_STR - head_len) {
|
||||
len = NGX_SYSLOG_MAX_STR - head_len;
|
||||
}
|
||||
|
||||
p = ngx_snprintf(p, len, "%s", buf);
|
||||
|
||||
(void) ngx_syslog_send(peer, msg, p - msg);
|
||||
|
||||
peer->processing = 0;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len)
|
||||
{
|
||||
if (peer->conn.fd == (ngx_socket_t) -1) {
|
||||
if (ngx_syslog_init_peer(peer) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_send) {
|
||||
return ngx_send(&peer->conn, buf, len);
|
||||
|
||||
} else {
|
||||
/* event module has not yet set ngx_io */
|
||||
return ngx_os_io.send(&peer->conn, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_syslog_init_peer(ngx_syslog_peer_t *peer)
|
||||
{
|
||||
ngx_socket_t fd;
|
||||
ngx_pool_cleanup_t *cln;
|
||||
|
||||
peer->conn.read = &ngx_syslog_dummy_event;
|
||||
peer->conn.write = &ngx_syslog_dummy_event;
|
||||
peer->conn.log = &ngx_syslog_dummy_log;
|
||||
|
||||
ngx_syslog_dummy_event.log = &ngx_syslog_dummy_log;
|
||||
|
||||
cln = ngx_pool_cleanup_add(peer->pool, 0);
|
||||
if (cln == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cln->data = peer;
|
||||
cln->handler = ngx_syslog_cleanup;
|
||||
|
||||
fd = ngx_socket(peer->server.sockaddr->sa_family, SOCK_DGRAM, 0);
|
||||
if (fd == (ngx_socket_t) -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
|
||||
ngx_socket_n " failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_nonblocking(fd) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
|
||||
ngx_nonblocking_n " failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (connect(fd, peer->server.sockaddr, peer->server.socklen) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
|
||||
"connect() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
peer->conn.fd = fd;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_syslog_cleanup(void *data)
|
||||
{
|
||||
ngx_syslog_peer_t *peer = data;
|
||||
|
||||
if (peer->conn.fd != (ngx_socket_t) -1) {
|
||||
(void) ngx_close_socket(peer->conn.fd);
|
||||
}
|
||||
}
|
30
src/core/ngx_syslog.h
Normal file
30
src/core/ngx_syslog.h
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Nginx, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_SYSLOG_H_INCLUDED_
|
||||
#define _NGX_SYSLOG_H_INCLUDED_
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_pool_t *pool;
|
||||
ngx_uint_t facility;
|
||||
ngx_uint_t severity;
|
||||
ngx_str_t tag;
|
||||
|
||||
ngx_addr_t server;
|
||||
ngx_connection_t conn;
|
||||
ngx_uint_t processing; /* unsigned processing:1; */
|
||||
} ngx_syslog_peer_t;
|
||||
|
||||
|
||||
char *ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer);
|
||||
u_char *ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf);
|
||||
void ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf,
|
||||
size_t len);
|
||||
ssize_t ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len);
|
||||
|
||||
|
||||
#endif /* _NGX_SYSLOG_H_INCLUDED_ */
|
@ -29,6 +29,7 @@ volatile ngx_str_t ngx_cached_err_log_time;
|
||||
volatile ngx_str_t ngx_cached_http_time;
|
||||
volatile ngx_str_t ngx_cached_http_log_time;
|
||||
volatile ngx_str_t ngx_cached_http_log_iso8601;
|
||||
volatile ngx_str_t ngx_cached_syslog_time;
|
||||
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
@ -50,6 +51,8 @@ static u_char cached_http_log_time[NGX_TIME_SLOTS]
|
||||
[sizeof("28/Sep/1970:12:00:00 +0600")];
|
||||
static u_char cached_http_log_iso8601[NGX_TIME_SLOTS]
|
||||
[sizeof("1970-09-28T12:00:00+06:00")];
|
||||
static u_char cached_syslog_time[NGX_TIME_SLOTS]
|
||||
[sizeof("Sep 28 12:00:00")];
|
||||
|
||||
|
||||
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
@ -63,6 +66,7 @@ ngx_time_init(void)
|
||||
ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1;
|
||||
ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1;
|
||||
ngx_cached_http_log_iso8601.len = sizeof("1970-09-28T12:00:00+06:00") - 1;
|
||||
ngx_cached_syslog_time.len = sizeof("Sep 28 12:00:00") - 1;
|
||||
|
||||
ngx_cached_time = &cached_time[0];
|
||||
|
||||
@ -73,7 +77,7 @@ ngx_time_init(void)
|
||||
void
|
||||
ngx_time_update(void)
|
||||
{
|
||||
u_char *p0, *p1, *p2, *p3;
|
||||
u_char *p0, *p1, *p2, *p3, *p4;
|
||||
ngx_tm_t tm, gmt;
|
||||
time_t sec;
|
||||
ngx_uint_t msec;
|
||||
@ -166,6 +170,11 @@ ngx_time_update(void)
|
||||
tp->gmtoff < 0 ? '-' : '+',
|
||||
ngx_abs(tp->gmtoff / 60), ngx_abs(tp->gmtoff % 60));
|
||||
|
||||
p4 = &cached_syslog_time[slot][0];
|
||||
|
||||
(void) ngx_sprintf(p4, "%s %2d %02d:%02d:%02d",
|
||||
months[tm.ngx_tm_mon - 1], tm.ngx_tm_mday,
|
||||
tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec);
|
||||
|
||||
ngx_memory_barrier();
|
||||
|
||||
@ -174,6 +183,7 @@ ngx_time_update(void)
|
||||
ngx_cached_err_log_time.data = p1;
|
||||
ngx_cached_http_log_time.data = p2;
|
||||
ngx_cached_http_log_iso8601.data = p3;
|
||||
ngx_cached_syslog_time.data = p4;
|
||||
|
||||
ngx_unlock(&ngx_time_lock);
|
||||
}
|
||||
@ -184,7 +194,7 @@ ngx_time_update(void)
|
||||
void
|
||||
ngx_time_sigsafe_update(void)
|
||||
{
|
||||
u_char *p;
|
||||
u_char *p, *p2;
|
||||
ngx_tm_t tm;
|
||||
time_t sec;
|
||||
ngx_time_t *tp;
|
||||
@ -224,9 +234,16 @@ ngx_time_sigsafe_update(void)
|
||||
tm.ngx_tm_mday, tm.ngx_tm_hour,
|
||||
tm.ngx_tm_min, tm.ngx_tm_sec);
|
||||
|
||||
p2 = &cached_syslog_time[slot][0];
|
||||
|
||||
(void) ngx_sprintf(p2, "%s %2d %02d:%02d:%02d",
|
||||
months[tm.ngx_tm_mon - 1], tm.ngx_tm_mday,
|
||||
tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec);
|
||||
|
||||
ngx_memory_barrier();
|
||||
|
||||
ngx_cached_err_log_time.data = p;
|
||||
ngx_cached_syslog_time.data = p2;
|
||||
|
||||
ngx_unlock(&ngx_time_lock);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ extern volatile ngx_str_t ngx_cached_err_log_time;
|
||||
extern volatile ngx_str_t ngx_cached_http_time;
|
||||
extern volatile ngx_str_t ngx_cached_http_log_time;
|
||||
extern volatile ngx_str_t ngx_cached_http_log_iso8601;
|
||||
extern volatile ngx_str_t ngx_cached_syslog_time;
|
||||
|
||||
/*
|
||||
* milliseconds elapsed since epoch and truncated to ngx_msec_t,
|
||||
|
@ -66,6 +66,7 @@ typedef struct {
|
||||
ngx_http_log_script_t *script;
|
||||
time_t disk_full_time;
|
||||
time_t error_log_time;
|
||||
ngx_syslog_peer_t *syslog_peer;
|
||||
ngx_http_log_fmt_t *format;
|
||||
ngx_http_complex_value_t *filter;
|
||||
} ngx_http_log_t;
|
||||
@ -240,7 +241,8 @@ static ngx_int_t
|
||||
ngx_http_log_handler(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *line, *p;
|
||||
size_t len;
|
||||
size_t len, size;
|
||||
ssize_t n;
|
||||
ngx_str_t val;
|
||||
ngx_uint_t i, l;
|
||||
ngx_http_log_t *log;
|
||||
@ -294,6 +296,16 @@ ngx_http_log_handler(ngx_http_request_t *r)
|
||||
}
|
||||
}
|
||||
|
||||
if (log[l].syslog_peer) {
|
||||
|
||||
/* length of syslog's PRI and HEADER message parts */
|
||||
len += sizeof("<255>Jan 01 00:00:00 ") - 1
|
||||
+ ngx_cycle->hostname.len + 1
|
||||
+ log[l].syslog_peer->tag.len + 2;
|
||||
|
||||
goto alloc_line;
|
||||
}
|
||||
|
||||
len += NGX_LINEFEED_SIZE;
|
||||
|
||||
buffer = log[l].file ? log[l].file->data : NULL;
|
||||
@ -332,6 +344,8 @@ ngx_http_log_handler(ngx_http_request_t *r)
|
||||
}
|
||||
}
|
||||
|
||||
alloc_line:
|
||||
|
||||
line = ngx_pnalloc(r->pool, len);
|
||||
if (line == NULL) {
|
||||
return NGX_ERROR;
|
||||
@ -339,10 +353,33 @@ ngx_http_log_handler(ngx_http_request_t *r)
|
||||
|
||||
p = line;
|
||||
|
||||
if (log[l].syslog_peer) {
|
||||
p = ngx_syslog_add_header(log[l].syslog_peer, line);
|
||||
}
|
||||
|
||||
for (i = 0; i < log[l].format->ops->nelts; i++) {
|
||||
p = op[i].run(r, p, &op[i]);
|
||||
}
|
||||
|
||||
if (log[l].syslog_peer) {
|
||||
|
||||
size = p - line;
|
||||
|
||||
n = ngx_syslog_send(log[l].syslog_peer, line, size);
|
||||
|
||||
if (n < 0) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"send() to syslog failed");
|
||||
|
||||
} else if ((size_t) n != size) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"send() to syslog has written only %z of %uz",
|
||||
n, size);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_linefeed(p);
|
||||
|
||||
ngx_http_log_write(r, &log[l], line, p - line);
|
||||
@ -1080,6 +1117,7 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
log->script = NULL;
|
||||
log->disk_full_time = 0;
|
||||
log->error_log_time = 0;
|
||||
log->syslog_peer = NULL;
|
||||
|
||||
lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
|
||||
fmt = lmcf->formats.elts;
|
||||
@ -1103,6 +1141,7 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_msec_t flush;
|
||||
ngx_str_t *value, name, s, filter;
|
||||
ngx_http_log_t *log;
|
||||
ngx_syslog_peer_t *peer;
|
||||
ngx_http_log_buf_t *buffer;
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
@ -1138,6 +1177,23 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
ngx_memzero(log, sizeof(ngx_http_log_t));
|
||||
|
||||
|
||||
if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) {
|
||||
|
||||
peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t));
|
||||
if (peer == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
log->syslog_peer = peer;
|
||||
|
||||
goto process_formats;
|
||||
}
|
||||
|
||||
n = ngx_http_script_variables_count(&value[1]);
|
||||
|
||||
if (n == 0) {
|
||||
@ -1171,6 +1227,8 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
}
|
||||
|
||||
process_formats:
|
||||
|
||||
if (cf->args->nelts >= 3) {
|
||||
name = value[2];
|
||||
|
||||
@ -1199,6 +1257,17 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (log->syslog_peer != NULL) {
|
||||
if (cf->args->nelts > 3) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"parameter \"%V\" is not supported by syslog",
|
||||
&value[3]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
flush = 0;
|
||||
gzip = 0;
|
||||
|
@ -587,6 +587,8 @@ extern ngx_http_header_out_t ngx_http_headers_out[];
|
||||
\
|
||||
c->log->file = l->file; \
|
||||
c->log->next = l->next; \
|
||||
c->log->writer = l->writer; \
|
||||
c->log->wdata = l->wdata; \
|
||||
if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { \
|
||||
c->log->log_level = l->log_level; \
|
||||
}
|
||||
|
@ -710,11 +710,13 @@ ngx_master_process_exit(ngx_cycle_t *cycle)
|
||||
* ngx_cycle->pool is already destroyed.
|
||||
*/
|
||||
|
||||
ngx_exit_log_file.fd = ngx_cycle->log->file->fd;
|
||||
|
||||
ngx_exit_log = *ngx_cycle->log;
|
||||
ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log);
|
||||
|
||||
ngx_exit_log_file.fd = ngx_exit_log.file->fd;
|
||||
ngx_exit_log.file = &ngx_exit_log_file;
|
||||
ngx_exit_log.next = NULL;
|
||||
ngx_exit_log.writer = NULL;
|
||||
|
||||
ngx_exit_cycle.log = &ngx_exit_log;
|
||||
ngx_exit_cycle.files = ngx_cycle->files;
|
||||
@ -1065,11 +1067,12 @@ ngx_worker_process_exit(ngx_cycle_t *cycle)
|
||||
* ngx_cycle->pool is already destroyed.
|
||||
*/
|
||||
|
||||
ngx_exit_log_file.fd = ngx_cycle->log->file->fd;
|
||||
ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log);
|
||||
|
||||
ngx_exit_log = *ngx_cycle->log;
|
||||
ngx_exit_log_file.fd = ngx_exit_log.file->fd;
|
||||
ngx_exit_log.file = &ngx_exit_log_file;
|
||||
ngx_exit_log.next = NULL;
|
||||
ngx_exit_log.writer = NULL;
|
||||
|
||||
ngx_exit_cycle.log = &ngx_exit_log;
|
||||
ngx_exit_cycle.files = ngx_cycle->files;
|
||||
|
Loading…
Reference in New Issue
Block a user