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