/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license from the top-level * OPENSOLARIS.LICENSE or . * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each file * and include the License file from the top-level OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049). * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC. */ #include #include #include #include #include #include #include "zed_log.h" #define ZED_LOG_MAX_ID_LEN 64 #define ZED_LOG_MAX_LOG_LEN 1024 static struct { unsigned do_stderr:1; unsigned do_syslog:1; int level; char id[ZED_LOG_MAX_ID_LEN]; } _ctx; void zed_log_init(const char *identity) { const char *p; if (identity) { p = (p = strrchr(identity, '/')) ? p + 1 : identity; strlcpy(_ctx.id, p, sizeof (_ctx.id)); } else { _ctx.id[0] = '\0'; } } void zed_log_fini() { if (_ctx.do_syslog) { closelog(); } } void zed_log_stderr_open(int level) { _ctx.do_stderr = 1; _ctx.level = level; } void zed_log_stderr_close(void) { _ctx.do_stderr = 0; } void zed_log_syslog_open(int facility) { const char *identity; _ctx.do_syslog = 1; identity = (_ctx.id[0] == '\0') ? NULL : _ctx.id; openlog(identity, LOG_NDELAY, facility); } void zed_log_syslog_close(void) { _ctx.do_syslog = 0; closelog(); } static void _zed_log_aux(int priority, const char *fmt, va_list vargs) { char buf[ZED_LOG_MAX_LOG_LEN]; char *syslogp; char *p; int len; int n; assert(fmt != NULL); syslogp = NULL; p = buf; len = sizeof (buf); if (_ctx.id[0] != '\0') { n = snprintf(p, len, "%s: ", _ctx.id); if ((n < 0) || (n >= len)) { p += len - 1; len = 0; } else { p += n; len -= n; } } if ((len > 0) && fmt) { syslogp = p; n = vsnprintf(p, len, fmt, vargs); if ((n < 0) || (n >= len)) { p += len - 1; len = 0; } else { p += n; len -= n; } } *p = '\0'; if (_ctx.do_syslog && syslogp) syslog(priority, "%s", syslogp); if (_ctx.do_stderr && priority <= _ctx.level) fprintf(stderr, "%s\n", buf); } /* * Log a message at the given [priority] level specified by the printf-style * format string [fmt]. */ void zed_log_msg(int priority, const char *fmt, ...) { va_list vargs; if (fmt) { va_start(vargs, fmt); _zed_log_aux(priority, fmt, vargs); va_end(vargs); } } /* * Log a fatal error message specified by the printf-style format string [fmt]. */ void zed_log_die(const char *fmt, ...) { va_list vargs; if (fmt) { va_start(vargs, fmt); _zed_log_aux(LOG_ERR, fmt, vargs); va_end(vargs); } exit(EXIT_FAILURE); }