/* * Copyright (c) 2021 Joris Vink * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include "kore.h" struct kore_wlog { int prio; u_int16_t wid; size_t loglen; char logmsg[]; }; static void log_from_worker(struct kore_msg *, const void *); void kore_log_init(void) { #if defined(KORE_SINGLE_BINARY) extern const char *__progname; const char *name = kore_strdup(__progname); #else const char *name = "kore"; #endif if (!kore_foreground) openlog(name, LOG_NDELAY | LOG_PID, LOG_DAEMON); kore_msg_register(KORE_MSG_WORKER_LOG, log_from_worker); } void kore_log(int prio, const char *fmt, ...) { va_list args; const char *str; struct kore_wlog wlog; struct kore_buf buf, pkt; kore_buf_init(&buf, 128); va_start(args, fmt); kore_buf_appendv(&buf, fmt, args); va_end(args); if (worker != NULL) { kore_buf_init(&pkt, sizeof(wlog) + buf.offset); memset(&wlog, 0, sizeof(wlog)); wlog.prio = prio; wlog.wid = worker->id; wlog.loglen = buf.offset; kore_buf_append(&pkt, &wlog, sizeof(wlog)); kore_buf_append(&pkt, buf.data, buf.offset); kore_msg_send(KORE_MSG_PARENT, KORE_MSG_WORKER_LOG, pkt.data, pkt.offset); kore_buf_cleanup(&pkt); } else { str = kore_buf_stringify(&buf, NULL); if (kore_foreground) printf("[parent]: %s\n", str); else syslog(prio, "[parent]: %s", str); } kore_buf_cleanup(&buf); } static void log_from_worker(struct kore_msg *msg, const void *data) { const char *name; const struct kore_wlog *wlog; if (msg->length < sizeof(*wlog)) { kore_log(LOG_NOTICE, "too short worker log received (%zu < %zu)", msg->length, sizeof(*wlog)); return; } wlog = data; name = kore_worker_name(wlog->wid); if (kore_foreground) { printf("%s: %.*s\n", name, (int)wlog->loglen, wlog->logmsg); fflush(stdout); } else { syslog(wlog->prio, "%s: %.*s", name, (int)wlog->loglen, wlog->logmsg); } }