diff options
Diffstat (limited to 'cmd/zed/zed_log.c')
-rw-r--r-- | cmd/zed/zed_log.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/cmd/zed/zed_log.c b/cmd/zed/zed_log.c new file mode 100644 index 000000000..bc432bc21 --- /dev/null +++ b/cmd/zed/zed_log.c @@ -0,0 +1,171 @@ +/* + * 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 <http://opensource.org/licenses/CDDL-1.0>. + * 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 <assert.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#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); +} |