40 void streambuffdestructor(
void* v){
41 logger_impl::streambuff_tls_entry* t =
42 reinterpret_cast<logger_impl::streambuff_tls_entry*
>(v);
46 const char* messages[] = {
"DEBUG: ",
56 log_to_console =
true;
58 pthread_mutex_init(&mut, NULL);
59 pthread_key_create(&streambuffkey, streambuffdestructor);
62 file_logger::~file_logger() {
68 pthread_mutex_destroy(&mut);
79 if (file.length() > 0) {
80 fout.open(file.c_str());
81 if (fout.fail())
return false;
106 void textcolor(FILE* handle,
int attr,
int fg)
110 sprintf(command,
"%c[%d;%dm", 0x1B, attr, fg + 30);
111 fprintf(handle,
"%s", command);
114 void reset_color(FILE* handle)
118 sprintf(command,
"%c[0m", 0x1B);
119 fprintf(handle,
"%s", command);
125 int line,
const char* fmt, va_list ap ){
127 if (lineloglevel >= 0 && lineloglevel >= log_level){
130 file = ((strrchr(file,
'/') ? : file- 1) + 1);
135 int byteswritten = snprintf(str,1024,
"%s%s(%s:%d): ",
136 messages[lineloglevel],file,
function,line);
139 byteswritten += vsnprintf(str + byteswritten,1024 - byteswritten,fmt,ap);
141 str[byteswritten] =
'\n';
142 str[byteswritten+1] = 0;
145 pthread_mutex_lock(&mut);
147 pthread_mutex_unlock(&mut);
149 if (log_to_console) {
152 textcolor(stderr, BRIGHT, RED);
155 textcolor(stderr, BRIGHT, RED);
158 textcolor(stderr, BRIGHT, MAGENTA);
160 else if (lineloglevel ==
LOG_EMPH) {
161 textcolor(stderr, BRIGHT, GREEN);
174 void file_logger::_logbuf(
int lineloglevel,
const char* file,
const char*
function,
175 int line,
const char* buf,
int len) {
177 if (lineloglevel >= 0 && lineloglevel <= 3 && lineloglevel >= log_level){
180 file = ((strrchr(file,
'/') ? : file- 1) + 1);
183 size_t headerlen = snprintf(NULL,0,
"%s%s(%s:%d): ",
184 messages[lineloglevel],file,
function,line);
186 if (headerlen> 2047) {
187 std::cerr <<
"Header length exceed buffer length!";
191 const char *newline=
"\n";
193 int byteswritten = snprintf(str,2047,
"%s%s(%s:%d): ",
194 messages[lineloglevel],file,
function,line);
195 _lograw(lineloglevel,str, byteswritten);
196 _lograw(lineloglevel,buf, len);
197 _lograw(lineloglevel,newline, (
int)strlen(newline));
202 void file_logger::_lograw(
int lineloglevel,
const char* buf,
int len) {
204 pthread_mutex_lock(&mut);
206 pthread_mutex_unlock(&mut);
208 if (log_to_console) {
211 textcolor(stderr, BRIGHT, RED);
214 textcolor(stderr, BRIGHT, RED);
217 textcolor(stderr, BRIGHT, MAGENTA);
220 textcolor(stderr, BRIGHT, YELLOW);
222 else if (lineloglevel ==
LOG_EMPH) {
223 textcolor(stderr, BRIGHT, GREEN);
226 std::cerr.write(buf,len);
233 file_logger& file_logger::start_stream(
int lineloglevel,
const char* file,
234 const char*
function,
int line,
bool do_start) {
236 logger_impl::streambuff_tls_entry* streambufentry =
237 reinterpret_cast<logger_impl::streambuff_tls_entry*
>(
238 pthread_getspecific(streambuffkey));
240 if (streambufentry == NULL) {
241 streambufentry =
new logger_impl::streambuff_tls_entry;
242 pthread_setspecific(streambuffkey, streambufentry);
244 std::stringstream& streambuffer = streambufentry->streambuffer;
245 bool& streamactive = streambufentry->streamactive;
248 if (do_start ==
false) {
249 streamactive =
false;
253 file = ((strrchr(file,
'/') ? : file- 1) + 1);
255 if (lineloglevel >= log_level){
256 if (streambuffer.str().length() == 0) {
257 streambuffer << messages[lineloglevel] << file
258 <<
"(" <<
function <<
":" <<line<<
"): ";
261 streamloglevel = lineloglevel;
264 streamactive =
false;