static int noit_log_line(noit_log_stream_t ls, const char *timebuf, int timebuflen, const char *debugbuf, int debugbuflen, const char *buffer, size_t len) { int rv = 0; struct _noit_log_stream_outlet_list *node; if(ls->ops) { int iovcnt = 0; struct iovec iov[3]; if(ls->timestamps) { iov[iovcnt].iov_base = (void *)timebuf; iov[iovcnt].iov_len = timebuflen; iovcnt++; } if(ls->debug) { iov[iovcnt].iov_base = (void *)debugbuf; iov[iovcnt].iov_len = debugbuflen; iovcnt++; } iov[iovcnt].iov_base = (void *)buffer; iov[iovcnt].iov_len = len; iovcnt++; rv = noit_log_writev(ls, iov, iovcnt); } for(node = ls->outlets; node; node = node->next) { int srv = 0; debug_printf(" %s -> %s\n", ls->name, node->outlet->name); srv = noit_log_line(node->outlet, timebuf, timebuflen, debugbuf, debugbuflen, buffer, len); if(srv) rv = srv; } return rv; }
static int noit_log_line(noit_log_stream_t ls, noit_log_stream_t bitor, struct timeval *whence, const char *timebuf, int timebuflen, const char *debugbuf, int debugbuflen, const char *buffer, size_t len) { int rv = 0; struct _noit_log_stream_outlet_list *node; struct _noit_log_stream bitor_onstack; memcpy(&bitor_onstack, ls, sizeof(bitor_onstack)); if(bitor) { bitor_onstack.name = bitor->name; bitor_onstack.flags |= bitor->flags & NOIT_LOG_STREAM_FACILITY; } bitor = &bitor_onstack; if(ls->ops) { int iovcnt = 0; struct iovec iov[6]; if(IS_TIMESTAMPS_ON(bitor)) { iov[iovcnt].iov_base = (void *)timebuf; iov[iovcnt].iov_len = timebuflen; iovcnt++; } if(IS_FACILITY_ON(bitor)) { iov[iovcnt].iov_base = (void *)"["; iov[iovcnt].iov_len = 1; iovcnt++; iov[iovcnt].iov_base = (void *)bitor->name; iov[iovcnt].iov_len = strlen(bitor->name); iovcnt++; iov[iovcnt].iov_base = (void *)"] "; iov[iovcnt].iov_len = 2; iovcnt++; } if(IS_DEBUG_ON(bitor)) { iov[iovcnt].iov_base = (void *)debugbuf; iov[iovcnt].iov_len = debugbuflen; iovcnt++; } iov[iovcnt].iov_base = (void *)buffer; iov[iovcnt].iov_len = len; iovcnt++; rv = noit_log_writev(ls, whence, iov, iovcnt); } for(node = ls->outlets; node; node = node->next) { int srv = 0; debug_printf(" %s -> %s\n", ls->name, node->outlet->name); srv = noit_log_line(node->outlet, bitor, whence, timebuf, timebuflen, debugbuf, debugbuflen, buffer, len); if(srv) rv = srv; } return rv; }
int noit_vlog(noit_log_stream_t ls, struct timeval *now, const char *file, int line, const char *format, va_list arg) { int rv = 0, allocd = 0; char buffer[4096], *dynbuff = NULL; #ifdef va_copy va_list copy; #endif if(ls->enabled || NOIT_LOG_LOG_ENABLED()) { int len; char tbuf[48], dbuf[80]; int tbuflen = 0, dbuflen = 0; MATERIALIZE_DEPS(ls); if(ls->timestamps_below) { struct tm _tm, *tm; char tempbuf[32]; time_t s = (time_t)now->tv_sec; tm = localtime_r(&s, &_tm); strftime(tempbuf, sizeof(tempbuf), "%Y-%m-%d %H:%M:%S", tm); snprintf(tbuf, sizeof(tbuf), "[%s.%06d] ", tempbuf, (int)now->tv_usec); tbuflen = strlen(tbuf); } else tbuf[0] = '\0'; if(ls->debug_below) { snprintf(dbuf, sizeof(dbuf), "[%s:%d] ", file, line); dbuflen = strlen(dbuf); } else dbuf[0] = '\0'; #ifdef va_copy va_copy(copy, arg); len = vsnprintf(buffer, sizeof(buffer), format, copy); va_end(copy); #else len = vsnprintf(buffer, sizeof(buffer), format, arg); #endif if(len > sizeof(buffer)) { allocd = sizeof(buffer); while(len > allocd) { /* guaranteed true the first time */ while(len > allocd) allocd <<= 2; if(dynbuff) free(dynbuff); dynbuff = malloc(allocd); assert(dynbuff); #ifdef va_copy va_copy(copy, arg); len = vsnprintf(dynbuff, allocd, format, copy); va_end(copy); #else len = vsnprintf(dynbuff, allocd, format, arg); #endif } NOIT_LOG_LOG(ls->name, (char *)file, line, dynbuff); if(ls->enabled) rv = noit_log_line(ls, tbuf, tbuflen, dbuf, dbuflen, dynbuff, len); free(dynbuff); } else { NOIT_LOG_LOG(ls->name, (char *)file, line, buffer); if(ls->enabled) rv = noit_log_line(ls, tbuf, tbuflen, dbuf, dbuflen, buffer, len); } if(rv == len) return 0; return -1; } return 0; }