00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00045
00046
00047 #define DEFAULT_LOG_BUFFER_SIZE 2000
00048
00049
00050
00051
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, <ime);
00069 strftime(buffer, len, "%y%m%d %H:%M:%S", <ime);
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
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
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