1*49bfb42bSAlexandre Chartre /* 2*49bfb42bSAlexandre Chartre * CDDL HEADER START 3*49bfb42bSAlexandre Chartre * 4*49bfb42bSAlexandre Chartre * The contents of this file are subject to the terms of the 5*49bfb42bSAlexandre Chartre * Common Development and Distribution License (the "License"). 6*49bfb42bSAlexandre Chartre * You may not use this file except in compliance with the License. 7*49bfb42bSAlexandre Chartre * 8*49bfb42bSAlexandre Chartre * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*49bfb42bSAlexandre Chartre * or http://www.opensolaris.org/os/licensing. 10*49bfb42bSAlexandre Chartre * See the License for the specific language governing permissions 11*49bfb42bSAlexandre Chartre * and limitations under the License. 12*49bfb42bSAlexandre Chartre * 13*49bfb42bSAlexandre Chartre * When distributing Covered Code, include this CDDL HEADER in each 14*49bfb42bSAlexandre Chartre * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*49bfb42bSAlexandre Chartre * If applicable, add the following below this CDDL HEADER, with the 16*49bfb42bSAlexandre Chartre * fields enclosed by brackets "[]" replaced with your own identifying 17*49bfb42bSAlexandre Chartre * information: Portions Copyright [yyyy] [name of copyright owner] 18*49bfb42bSAlexandre Chartre * 19*49bfb42bSAlexandre Chartre * CDDL HEADER END 20*49bfb42bSAlexandre Chartre */ 21*49bfb42bSAlexandre Chartre 22*49bfb42bSAlexandre Chartre /* 23*49bfb42bSAlexandre Chartre * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*49bfb42bSAlexandre Chartre * Use is subject to license terms. 25*49bfb42bSAlexandre Chartre */ 26*49bfb42bSAlexandre Chartre 27*49bfb42bSAlexandre Chartre /* 28*49bfb42bSAlexandre Chartre * Logging support for the LDoms Agent daemon 29*49bfb42bSAlexandre Chartre */ 30*49bfb42bSAlexandre Chartre 31*49bfb42bSAlexandre Chartre #include <errno.h> 32*49bfb42bSAlexandre Chartre #include <stdarg.h> 33*49bfb42bSAlexandre Chartre #include <stdio.h> 34*49bfb42bSAlexandre Chartre #include <string.h> 35*49bfb42bSAlexandre Chartre #include <syslog.h> 36*49bfb42bSAlexandre Chartre #include <sys/types.h> 37*49bfb42bSAlexandre Chartre 38*49bfb42bSAlexandre Chartre #define LDMA_MAX_MSG_LEN 512 39*49bfb42bSAlexandre Chartre #define LDMA_MAX_TIME_LEN 32 40*49bfb42bSAlexandre Chartre 41*49bfb42bSAlexandre Chartre extern boolean_t ldma_debug; 42*49bfb42bSAlexandre Chartre extern boolean_t ldma_daemon; 43*49bfb42bSAlexandre Chartre 44*49bfb42bSAlexandre Chartre static char *log_prio_str[] = { 45*49bfb42bSAlexandre Chartre "EMERG", /* LOG_EMERG */ 46*49bfb42bSAlexandre Chartre "ALERT", /* LOG_ALERT */ 47*49bfb42bSAlexandre Chartre "CRIT", /* LOG_CRIT */ 48*49bfb42bSAlexandre Chartre "ERROR", /* LOG_ERR */ 49*49bfb42bSAlexandre Chartre "WARNING", /* LOG_WARNING */ 50*49bfb42bSAlexandre Chartre "NOTICE", /* LOG_NOTICE */ 51*49bfb42bSAlexandre Chartre "INFO", /* LOG_INFO */ 52*49bfb42bSAlexandre Chartre "DEBUG" /* LOG_DEBUG */ 53*49bfb42bSAlexandre Chartre }; 54*49bfb42bSAlexandre Chartre 55*49bfb42bSAlexandre Chartre /* 56*49bfb42bSAlexandre Chartre * Generate a timestamp string in the provided buffer. 57*49bfb42bSAlexandre Chartre * If any errors are encountered, the function returns 58*49bfb42bSAlexandre Chartre * with the buffer containing an empty string. 59*49bfb42bSAlexandre Chartre */ 60*49bfb42bSAlexandre Chartre static void 61*49bfb42bSAlexandre Chartre ldma_timestamp(char *buf, size_t buflen) 62*49bfb42bSAlexandre Chartre { 63*49bfb42bSAlexandre Chartre struct tm ltime; 64*49bfb42bSAlexandre Chartre struct timeval now; 65*49bfb42bSAlexandre Chartre 66*49bfb42bSAlexandre Chartre if ((buf == NULL) || (buflen == 0)) 67*49bfb42bSAlexandre Chartre return; 68*49bfb42bSAlexandre Chartre 69*49bfb42bSAlexandre Chartre buf[0] = '\0'; 70*49bfb42bSAlexandre Chartre 71*49bfb42bSAlexandre Chartre if (gettimeofday(&now, NULL) != 0) { 72*49bfb42bSAlexandre Chartre (void) fprintf(stderr, "gettimeofday failed: %s\n", 73*49bfb42bSAlexandre Chartre strerror(errno)); 74*49bfb42bSAlexandre Chartre return; 75*49bfb42bSAlexandre Chartre } 76*49bfb42bSAlexandre Chartre 77*49bfb42bSAlexandre Chartre if (localtime_r(&now.tv_sec, <ime) == NULL) { 78*49bfb42bSAlexandre Chartre (void) fprintf(stderr, "localtime_r failed: %s\n", 79*49bfb42bSAlexandre Chartre strerror(errno)); 80*49bfb42bSAlexandre Chartre return; 81*49bfb42bSAlexandre Chartre } 82*49bfb42bSAlexandre Chartre 83*49bfb42bSAlexandre Chartre if (strftime(buf, buflen, "%b %e %T ", <ime) == 0) { 84*49bfb42bSAlexandre Chartre (void) fprintf(stderr, "strftime failed: buffer[%d] too " 85*49bfb42bSAlexandre Chartre "small\n", buflen); 86*49bfb42bSAlexandre Chartre /* 87*49bfb42bSAlexandre Chartre * On failure, the contents of the buffer 88*49bfb42bSAlexandre Chartre * are indeterminate. Restore it to a known 89*49bfb42bSAlexandre Chartre * state before returning. 90*49bfb42bSAlexandre Chartre */ 91*49bfb42bSAlexandre Chartre buf[0] = '\0'; 92*49bfb42bSAlexandre Chartre } 93*49bfb42bSAlexandre Chartre } 94*49bfb42bSAlexandre Chartre 95*49bfb42bSAlexandre Chartre static void 96*49bfb42bSAlexandre Chartre ldma_log_msg(int prio, char *module, char *fmt, va_list vap) 97*49bfb42bSAlexandre Chartre { 98*49bfb42bSAlexandre Chartre char msgbuf[LDMA_MAX_MSG_LEN]; 99*49bfb42bSAlexandre Chartre char timebuf[LDMA_MAX_TIME_LEN] = ""; 100*49bfb42bSAlexandre Chartre 101*49bfb42bSAlexandre Chartre /* generate a timestamp for the SMF log */ 102*49bfb42bSAlexandre Chartre ldma_timestamp(timebuf, sizeof (timebuf)); 103*49bfb42bSAlexandre Chartre 104*49bfb42bSAlexandre Chartre /* LINTED E_SEC_PRINTF_VAR_FMT */ 105*49bfb42bSAlexandre Chartre (void) vsnprintf(msgbuf, LDMA_MAX_MSG_LEN, fmt, vap); 106*49bfb42bSAlexandre Chartre 107*49bfb42bSAlexandre Chartre /* 108*49bfb42bSAlexandre Chartre * Print the message to stderr. In daemon mode, it 109*49bfb42bSAlexandre Chartre * will be sent to the SMF log. In standalone mode, 110*49bfb42bSAlexandre Chartre * it will be sent to the controlling terminal. 111*49bfb42bSAlexandre Chartre */ 112*49bfb42bSAlexandre Chartre (void) fprintf(stderr, "%s%s.%s: %s\n", timebuf, module, 113*49bfb42bSAlexandre Chartre log_prio_str[prio], msgbuf); 114*49bfb42bSAlexandre Chartre 115*49bfb42bSAlexandre Chartre if (ldma_daemon && prio != LOG_DEBUG) { 116*49bfb42bSAlexandre Chartre /* LINTED E_SEC_PRINTF_VAR_FMT */ 117*49bfb42bSAlexandre Chartre syslog(prio, msgbuf); 118*49bfb42bSAlexandre Chartre } 119*49bfb42bSAlexandre Chartre } 120*49bfb42bSAlexandre Chartre 121*49bfb42bSAlexandre Chartre void 122*49bfb42bSAlexandre Chartre ldma_err(char *module, char *fmt, ...) 123*49bfb42bSAlexandre Chartre { 124*49bfb42bSAlexandre Chartre va_list vap; 125*49bfb42bSAlexandre Chartre 126*49bfb42bSAlexandre Chartre va_start(vap, fmt); 127*49bfb42bSAlexandre Chartre ldma_log_msg(LOG_ERR, module, fmt, vap); 128*49bfb42bSAlexandre Chartre va_end(vap); 129*49bfb42bSAlexandre Chartre } 130*49bfb42bSAlexandre Chartre 131*49bfb42bSAlexandre Chartre void 132*49bfb42bSAlexandre Chartre ldma_info(char *module, char *fmt, ...) 133*49bfb42bSAlexandre Chartre { 134*49bfb42bSAlexandre Chartre va_list vap; 135*49bfb42bSAlexandre Chartre 136*49bfb42bSAlexandre Chartre va_start(vap, fmt); 137*49bfb42bSAlexandre Chartre ldma_log_msg(LOG_INFO, module, fmt, vap); 138*49bfb42bSAlexandre Chartre va_end(vap); 139*49bfb42bSAlexandre Chartre } 140*49bfb42bSAlexandre Chartre 141*49bfb42bSAlexandre Chartre void 142*49bfb42bSAlexandre Chartre ldma_dbg(char *module, char *fmt, ...) 143*49bfb42bSAlexandre Chartre { 144*49bfb42bSAlexandre Chartre va_list vap; 145*49bfb42bSAlexandre Chartre 146*49bfb42bSAlexandre Chartre if (!ldma_debug) { 147*49bfb42bSAlexandre Chartre /* not debugging */ 148*49bfb42bSAlexandre Chartre return; 149*49bfb42bSAlexandre Chartre } 150*49bfb42bSAlexandre Chartre 151*49bfb42bSAlexandre Chartre va_start(vap, fmt); 152*49bfb42bSAlexandre Chartre ldma_log_msg(LOG_DEBUG, module, fmt, vap); 153*49bfb42bSAlexandre Chartre va_end(vap); 154*49bfb42bSAlexandre Chartre } 155