/* * @(#)Log.cpp * * This file is part of webCDwriter - Network CD/DVD Writing. * * Copyright (C) 1999-2006 Jörg P. M. Haeger * * webCDwriter is free software. See CDWserver.cpp for details. */ #include #include #include #include #include #include "Config.h" #include "Log.h" #include "Thread.h" Log::Log() { pthread_mutex_init(&mutex, NULL); counter = 0; lastLine = ""; lastTime = 0; outStream = NULL; buf = new StringBuffer(8 * 1024, 8 * 1024); mark0 = mark1 = mark2 = linesCounter = 0; initMark = 2411; thread = NULL; } void Log::debug(const char *tag, const char *format, ...) { if (config.getLogLevel() < 9 && config.getDebug().indexOf(tag) < 0) return; char str[1024]; va_list ap; va_start(ap, format); vsnprintf(str, sizeof str, format, ap); va_end(ap); writeLine(config.getLogLevel(), S.e + tag + " " + str); } void Log::debug(const char *tag, String &message) { if (config.getLogLevel() < 9 && config.getDebug().indexOf(tag) < 0) { delete &message; return; } writeLine(config.getLogLevel(), S.e + tag + " " + message); delete &message; } void Log::error(String &message) { put(1, message); pthread_mutex_lock(&mutex); buf.append("--> error\n"); // mark1 = mark2 = buf.length(); // if (linesCounter > 200) // linesCounter = 200; pthread_mutex_unlock(&mutex); } String *Log::getSupportLog() { pthread_mutex_lock(&mutex); String *str = new String(buf); buf.delete_(mark0, buf.length()); pthread_mutex_unlock(&mutex); return str; } void Log::put(int level, const char *message) { put(level, S.e + message); } void Log::put(int level, String &message) { writeLine(level, message); } void Log::put(const char *format, ...) { char line[1024]; va_list ap; va_start(ap, format); vsnprintf(line, sizeof line, format, ap); va_end(ap); writeLine(3, S.e + line); } void Log::putv(const char *format, ...) { char line[1024]; va_list ap; va_start(ap, format); vsnprintf(line, sizeof line, format, ap); va_end(ap); writeLine(4, S.e + line); } void Log::restart() { if (outStream == NULL || outStream == stdout) return; File logFile = new File(config.getLogDir(), "log"); pthread_mutex_lock(&mutex); fclose(outStream); outStream = fopen(logFile.getPath().getBytes(), "a"); pthread_mutex_unlock(&mutex); } void Log::start(int toStdOut) { if (toStdOut) outStream = stdout; else { File logFile = new File(config.getLogDir(), "log"); outStream = fopen(logFile.getPath().getBytes(), "a"); } } void Log::writeLine(int level, String &line) { if (initMark != 2411) // object not initialized yet return; if ((!config.getSupportForm() || level > 5) && level > config.getLogLevel()) { delete &line; return; } if (Thread::currentThread() == thread) { // probably a recursive StringBuffer call delete &line; return; } StringBuffer workBuf = new StringBuffer(120, 40); for (int i = 0; i < line.length(); i++) { int ch = line.charAt(i); if (ch == '\n') workBuf.append("
"); else if (ch < 32) workBuf.append("_"); else workBuf.append((char) ch); } delete &line; workBuf.append("\n"); String line2 = new String(workBuf); if (outStream == NULL) return; if (pthread_mutex_lock(&mutex) != 0) return; try { thread = Thread::currentThread(); if (line2.equals(lastLine)) counter++; else { if (counter > 0) { String str = "repeated "; str = str + counter + " times\n"; if (lastLineLevel <= config.getLogLevel()) fwrite(str.getBytes(), str.length(), 1, outStream); counter = 0; } time_t t; time(&t); t -= 24 * 60 * 60; struct tm *tm = localtime(&t); if (config.getLogLevel() > 1 && tm->tm_hour < lastTime && outStream != NULL && outStream != stdout) { StringBuffer workBuf = new StringBuffer(40); File logFile = new File(config.getLogDir(), "log"); workBuf.append(logFile.getPath().getBytes()); workBuf.append("-"); appendFormatted(workBuf, 1900 + tm->tm_year, 4, '0'); appendFormatted(workBuf, tm->tm_mon + 1, 2, '0'); appendFormatted(workBuf, tm->tm_mday, 2, '0'); workBuf.append(".txt"); String newName = new String(workBuf); String msg = "End of "; msg = msg + newName + "\n"; fwrite(msg.getBytes(), msg.length(), 1, outStream); fclose(outStream); outStream = NULL; File newFile = new File(newName); for (int i = 2; newFile.exists() && i < 1000; i++) { String str = newName.substring(0, newName.length() - 4); str = str + "_" + i + ".txt"; newFile = new File(str); } logFile.renameTo(newFile); outStream = fopen(logFile.getPath().getBytes(), "a"); } lastTime = tm->tm_hour; StringBuffer workBuf = new StringBuffer(40); appendFormatted(workBuf, tm->tm_hour, 2, '0'); appendFormatted(workBuf, tm->tm_min, 2, '0'); appendFormatted(workBuf, tm->tm_sec, 2, '0'); workBuf.append(" T"); int threadID = 0; if (thread != NULL) threadID = thread->ID(); appendFormatted(workBuf, threadID, 5, '0'); workBuf.append(" L"); workBuf.append(level); workBuf.append(" "); String prefix = new String(workBuf); prefix = prefix + line2; if (level <= config.getLogLevel()) fwrite(prefix.getBytes(), prefix.length(), 1, outStream); if (config.getSupportForm()) { buf.append(prefix.getBytes()); linesCounter++; if (linesCounter <= 200) { mark0 = mark1 = mark2 = buf.length(); if (line2.startsWith("waiting for request...")) linesCounter = 200; } else if (linesCounter == 600) mark2 = buf.length(); else if (linesCounter == 1000) { buf.delete_(mark1, mark2); buf.insert(mark1, "<-- cut -->\n"); mark2 = buf.length(); linesCounter = 600; } } } lastLine = line2; lastLineLevel = level; } catch (Exception *e) { delete e; } thread = NULL; pthread_mutex_unlock(&mutex); fflush(outStream); }