Drizzled Public API Documentation

CSLog.cc

00001 /* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
00002  *
00003  * PrimeBase Media Stream for MySQL
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00018  *
00019  * Original author: Paul McCullagh (H&G2JCtL)
00020  * Continued development: Barry Leslie
00021  *
00022  * 2007-05-21
00023  *
00024  * General logging class
00025  *
00026  */
00027 
00028 #include "CSConfig.h"
00029 
00030 #include <string.h>
00031 #include <time.h>
00032 #include <stdarg.h>
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 
00036 #include "CSLog.h"
00037 #include "CSMemory.h"
00038 #include "CSUTF8.h"
00039 #include "CSStrUtil.h"
00040 #include "CSThread.h"
00041 #include "CSGlobal.h"
00042 
00043 
00044 //#ifdef DEBUG
00045 //#define DEFAULT_LOG_BUFFER_SIZE     10
00046 //#else
00047 #define DEFAULT_LOG_BUFFER_SIZE     2000
00048 //#endif
00049 
00050 /*
00051  * The global logging object.
00052  */
00053 CSLog CSL(stdout, CSLog::Warning);
00054 
00055 void CSLog::getNow(char *buffer, size_t len)
00056 {
00057   time_t    ticks;
00058   struct tm ltime;
00059 
00060   ticks = time(NULL);
00061   if (ticks == (time_t) -1) {
00062     int err = errno;
00063 
00064     fprintf(iStream, "*** ERROR (%d): While getting time\n", err);
00065     cs_strcpy(len, buffer, "-- TIME? --");
00066     return;
00067   }
00068   localtime_r(&ticks, &ltime);
00069   strftime(buffer, len, "%y%m%d %H:%M:%S", &ltime);
00070 }
00071 
00072 void CSLog::header(CSThread *self, const char *func, const char *file, int line, int level)
00073 {
00074   char buffer[300];
00075 
00076   getNow(buffer, 300);
00077   
00078   fprintf(iStream, "%s", buffer);
00079 
00080   switch (level) {
00081     case CSLog::Error:
00082       fprintf(iStream, " [Error] ");
00083       break;
00084     case CSLog::Warning:
00085       fprintf(iStream, " [Warning] ");
00086       break;
00087     case CSLog::Trace:
00088       fprintf(iStream, " [Trace] ");
00089       break;
00090     case CSLog::Protocol:
00091     default:
00092       fprintf(iStream, " [Note] ");
00093       break;
00094   }
00095 
00096   if (self && self->threadName && self->threadName->length() > 0)
00097     fprintf(iStream, "%s: ", self->threadName->getCString());
00098 
00099   cs_format_context(300, buffer, func, file, line);
00100   if (*buffer) {
00101     cs_strcat(300, buffer, " ");
00102     fprintf(iStream, "%s", buffer);
00103   }
00104 }
00105 
00106 void CSLog::log(CSThread *self, const char *func, const char *file, int line, int level, const char* buffer)
00107 {
00108   const char  *end_ptr;
00109   size_t    len;
00110   size_t ret;
00111 
00112   if (level > iLogLevel)
00113     return;
00114 
00115   lock();
00116   while (*buffer) {
00117     if (iHeaderPending) {
00118       iHeaderPending = false;
00119       header(self, func, file, line, level);
00120     }
00121     /* Write until the next \n... */
00122     if ((end_ptr = strchr((char*)buffer, '\n'))) {
00123       len = end_ptr - buffer;
00124       ret= fwrite(buffer, len, 1, iStream);
00125       fprintf(iStream, "\n");
00126       fflush(iStream);
00127       iHeaderPending = true;
00128       len++;
00129     }
00130     else {
00131       len = strlen(buffer);
00132                         ret = fwrite(buffer, len, 1, iStream);
00133 
00134     }
00135     buffer += len;
00136   }
00137   unlock();
00138         (void)ret;
00139 }
00140 
00141 void CSLog::log(CSThread *self, int level, const char *buffer)
00142 {
00143   log(self, NULL, NULL, 0, level, buffer);
00144 }
00145 
00146 void CSLog::log(CSThread *self, int level, CSString& wstr)
00147 {
00148   log(self, level, wstr.getCString());
00149 }
00150 
00151 void CSLog::log(CSThread *self, int level, CSString* wstr)
00152 {
00153   log(self, level, wstr->getCString());
00154 }
00155 
00156 void CSLog::log(CSThread *self, int level, int v)
00157 {
00158   char buffer[100];
00159 
00160   snprintf(buffer, 100, "%d", v);
00161   log(self, level, buffer);
00162 }
00163 
00164 void CSLog::eol(CSThread *self, int level)
00165 {
00166   log(self, level, "\n");
00167 }
00168 
00169 void CSLog::logLine(CSThread *self, int level, const char *buffer)
00170 {
00171   lock();
00172   log(self, level, buffer);
00173   eol(self, level);
00174   unlock();
00175 }
00176 
00177 void CSLog::log_va(CSThread *self, int level, const char *func, const char *file, int line, const char *fmt, va_list ap)
00178 {
00179   char buffer[DEFAULT_LOG_BUFFER_SIZE];
00180   char *log_string = NULL;
00181 
00182   lock();
00183 
00184 #if !defined(va_copy) || defined(OS_SOLARIS)
00185   int len;
00186 
00187   len = vsnprintf(buffer, DEFAULT_LOG_BUFFER_SIZE-1, fmt, ap);
00188   if (len > DEFAULT_LOG_BUFFER_SIZE-1)
00189     len = DEFAULT_LOG_BUFFER_SIZE-1;
00190   buffer[len] = 0;
00191   log_string = buffer;
00192 #else
00193   /* Use the buffer, unless it is too small */
00194   va_list ap2;
00195 
00196   va_copy(ap2, ap);
00197   if (vsnprintf(buffer, DEFAULT_LOG_BUFFER_SIZE, fmt, ap) >= DEFAULT_LOG_BUFFER_SIZE) {
00198     if (vasprintf(&log_string, fmt, ap2) == -1)
00199       log_string = NULL;
00200   }
00201   else
00202     log_string = buffer;
00203 #endif
00204 
00205   if (log_string) {
00206     log(self, func, file, line, level, log_string);
00207 
00208     if (log_string != buffer)
00209       free(log_string);
00210   }
00211 
00212   unlock();
00213 }
00214 
00215 void CSLog::logf(CSThread *self, int level, const char *fmt, ...)
00216 {
00217   va_list ap;
00218 
00219   va_start(ap, fmt);
00220   log_va(self, level, NULL, NULL, 0, fmt, ap);
00221   va_end(ap);
00222 }
00223 
00224 void CSLog::logf(CSThread *self, int level, const char *func, const char *file, int line, const char *fmt, ...)
00225 {
00226   va_list ap;
00227 
00228   va_start(ap, fmt);
00229   log_va(self, level, func, file, line, fmt, ap);
00230   va_end(ap);
00231 }
00232