172 lines
3.2 KiB
C
172 lines
3.2 KiB
C
|
/*
|
||
|
* 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);
|
||
|
}
|