summaryrefslogtreecommitdiffstats
path: root/cmd/zed/zed_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/zed/zed_log.c')
-rw-r--r--cmd/zed/zed_log.c171
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);
+}