allow sending fd to log on to the logger process

the logger process now can receive a file descriptor to write logs
to.  At the moment the logic is simple, if it receives a file it logs
there, otherwise it logs to syslog.  This will allow to log on custom
log files.
This commit is contained in:
Omar Polo 2021-06-15 08:06:10 +00:00
parent 0f2124e291
commit e952c5052a
4 changed files with 53 additions and 16 deletions

9
gmid.c
View File

@ -508,7 +508,11 @@ setup_configless(int argc, char **argv, const char *cgi)
loc = xcalloc(1, sizeof(*loc));
TAILQ_INSERT_HEAD(&host->locations, loc, locations);
imsg_compose(&logibuf, IMSG_LOG_TYPE, 0, 0, 2, NULL, 0);
imsg_flush(&logibuf);
serve(argc, argv, NULL);
imsg_compose(&logibuf, IMSG_QUIT, 0, 0, -1, NULL, 0);
imsg_flush(&logibuf);
}
@ -623,6 +627,11 @@ main(int argc, char **argv)
return 0;
}
if (conf.foreground) {
imsg_compose(&logibuf, IMSG_LOG_TYPE, 0, 0, 2, NULL, 0);
imsg_flush(&logibuf);
}
pidfd = write_pidfile(pidfile);
/* Linux seems to call the event handlers even when we're

1
gmid.h
View File

@ -296,6 +296,7 @@ enum imsg_type {
IMSG_FCGI_REQ,
IMSG_FCGI_FD,
IMSG_LOG,
IMSG_LOG_TYPE,
IMSG_QUIT,
};

57
log.c
View File

@ -32,17 +32,21 @@
static struct event imsgev;
static FILE *log;
static void handle_imsg_quit(struct imsgbuf*, struct imsg*, size_t);
static void handle_imsg_log(struct imsgbuf*, struct imsg*, size_t);
static void handle_imsg_log_type(struct imsgbuf*, struct imsg*, size_t);
static void handle_dispatch_imsg(int, short, void*);
static imsg_handlerfn *handlers[] = {
[IMSG_QUIT] = handle_imsg_quit,
[IMSG_LOG] = handle_imsg_log,
[IMSG_LOG_TYPE] = handle_imsg_log_type,
};
static inline void
print_date(void)
print_date(FILE *f)
{
struct tm tminfo;
time_t t;
@ -51,7 +55,7 @@ print_date(void)
time(&t);
strftime(buf, sizeof(buf), "%F %T",
localtime_r(&t, &tminfo));
fprintf(stderr, "[%s] ", buf);
fprintf(f, "[%s] ", buf);
}
static inline int
@ -254,6 +258,26 @@ log_request(struct client *c, char *meta, size_t l)
static void
do_log(int priority, const char *msg)
{
int quit = 0;
if (priority == LOG_CRIT) {
quit = 1;
priority = LOG_ERR;
}
if (log != NULL) {
print_date(log);
fprintf(log, "%s\n", msg);
} else
syslog(LOG_DAEMON | priority, "%s", msg);
if (quit)
exit(1);
}
static void
handle_imsg_quit(struct imsgbuf *ibuf, struct imsg *imsg, size_t datalen)
{
@ -268,23 +292,26 @@ handle_imsg_log(struct imsgbuf *ibuf, struct imsg *imsg, size_t datalen)
msg = imsg->data;
msg[datalen-1] = '\0';
priority = imsg->hdr.peerid;
do_log(priority, msg);
}
quit = 0;
if (priority == LOG_CRIT) {
quit = 1;
priority = LOG_ERR;
static void
handle_imsg_log_type(struct imsgbuf *ibuf, struct imsg *imsg, size_t datalen)
{
if (log != NULL) {
fflush(log);
fclose(log);
log = NULL;
}
if (conf.foreground) {
print_date();
fprintf(stderr, "%s\n", msg);
} else
syslog(LOG_DAEMON | priority, "%s", msg);
if (quit)
exit(1);
if (imsg->fd != -1) {
if ((log = fdopen(imsg->fd, "a")) == NULL) {
syslog(LOG_DAEMON | LOG_ERR, "fdopen: %s",
strerror(errno));
exit(1);
}
}
}
static void

View File

@ -344,7 +344,7 @@ sandbox_executor_process(void)
void
sandbox_logger_process(void)
{
if (pledge("stdio", NULL) == -1)
if (pledge("stdio recvfd", NULL) == -1)
err(1, "pledge");
}