summaryrefslogtreecommitdiff
path: root/src/Logger.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-11-20 08:21:36 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-11-20 08:21:36 +0000
commit580098eb4929a3bdbf424af18da361259ef2efe5 (patch)
treec6ff77fa55fcbdcdd0ca21ec2105db14a8c050d3 /src/Logger.cc
parent3940da75624b194cdd5036f9fe330fcecc725964 (diff)
2010-11-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewritten Logger interface. Logger now writes source file name and line number in log file.
Diffstat (limited to 'src/Logger.cc')
-rw-r--r--src/Logger.cc237
1 files changed, 124 insertions, 113 deletions
diff --git a/src/Logger.cc b/src/Logger.cc
index de60f246..c931faef 100644
--- a/src/Logger.cc
+++ b/src/Logger.cc
@@ -2,7 +2,7 @@
/*
* aria2 - The high speed download utility
*
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ * Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,176 +35,187 @@
#include "Logger.h"
#include <cstring>
+#include <iostream>
#include "DlAbortEx.h"
-#include "StringFormat.h"
+#include "fmt.h"
#include "message.h"
-#include "LogFormatter.h"
+#include "A2STR.h"
+#include "a2time.h"
namespace aria2 {
-const std::string Logger::DEBUG_LABEL("DEBUG");
+namespace {
+static const std::string DEBUG_LABEL("DEBUG");
-const std::string Logger::NOTICE_LABEL("NOTICE");
+static const std::string INFO_LABEL("INFO");
-const std::string Logger::WARN_LABEL("WARN");
+static const std::string NOTICE_LABEL("NOTICE");
-const std::string Logger::ERROR_LABEL("ERROR");
+static const std::string WARN_LABEL("WARN");
-const std::string Logger::INFO_LABEL("INFO");
+static const std::string ERROR_LABEL("ERROR");
+} // namespace
-Logger::Logger():
- logFormatter_(0), logLevel_(Logger::A2_DEBUG), stdoutField_(0) {}
+Logger::Logger()
+ : logLevel_(Logger::A2_DEBUG),
+ stdoutField_(0)
+{}
Logger::~Logger()
{
closeFile();
- delete logFormatter_;
}
void Logger::openFile(const std::string& filename)
{
file_.open(filename.c_str(), std::ios::app|std::ios::binary);
if(!file_) {
- throw DL_ABORT_EX
- (StringFormat(EX_FILE_OPEN, filename.c_str(), "n/a").str());
+ throw DL_ABORT_EX(fmt(EX_FILE_OPEN, filename.c_str(), "n/a"));
}
}
void Logger::closeFile()
{
+ std::cerr << "Closing log file" << std::endl;
+ // TODO Do we need file_.is_open()?
if(file_.is_open()) {
file_.close();
}
}
-#define WRITE_LOG(LEVEL, LEVEL_LABEL, MSG) \
- if(LEVEL >= logLevel_ && file_.is_open()) { \
- va_list ap; \
- va_start(ap, MSG); \
- writeLog(file_, LEVEL, LEVEL_LABEL, MSG, ap); \
- va_end(ap); \
- file_ << std::flush; \
- } \
- if(stdoutField_&LEVEL) { \
- std::cout << "\n"; \
- va_list ap; \
- va_start(ap, MSG); \
- writeLog(std::cout, LEVEL, LEVEL_LABEL, MSG, ap); \
- va_end(ap); \
- std::cout << std::flush; \
- } \
-
-#define WRITE_LOG_EX(LEVEL, LEVEL_LABEL, MSG, EX) \
- if(LEVEL >= logLevel_ && file_.is_open()) { \
- va_list ap; \
- va_start(ap, EX); \
- writeLog(file_, LEVEL, LEVEL_LABEL, MSG, ap); \
- va_end(ap); \
- writeStackTrace(file_, LEVEL, LEVEL_LABEL, EX); \
- file_ << std::flush; \
- } \
- if(stdoutField_&LEVEL) { \
- std::cout << "\n"; \
- va_list ap; \
- va_start(ap, EX); \
- writeLog(std::cout, LEVEL, LEVEL_LABEL, MSG, ap); \
- va_end(ap); \
- writeStackTrace(std::cout, LEVEL, LEVEL_LABEL, EX); \
- std::cout << std::flush; \
- } \
-
-void Logger::debug(const char* msg, ...)
-{
- WRITE_LOG(A2_DEBUG, DEBUG_LABEL, msg);
-}
-
-void Logger::debug(const char* msg, const Exception& ex, ...)
-{
- WRITE_LOG_EX(A2_DEBUG, DEBUG_LABEL, msg, ex);
-}
-
-void Logger::info(const char* msg, ...)
-{
- WRITE_LOG(A2_INFO, INFO_LABEL, msg);
-}
-
-void Logger::info(const char* msg, const Exception& ex, ...)
-{
- WRITE_LOG_EX(A2_INFO, INFO_LABEL, msg, ex);
-}
-
-void Logger::notice(const char* msg, ...)
-{
- WRITE_LOG(A2_NOTICE, NOTICE_LABEL, msg);
-}
-
-void Logger::notice(const char* msg, const Exception& ex, ...)
-{
- WRITE_LOG_EX(A2_NOTICE, NOTICE_LABEL, msg, ex);
-}
-
-void Logger::warn(const char* msg, ...)
+void Logger::setStdoutLogLevel(Logger::LEVEL level, bool enabled)
{
- WRITE_LOG(A2_WARN, WARN_LABEL, msg);
+ if(enabled) {
+ stdoutField_ |= level;
+ } else {
+ stdoutField_ &= ~level;
+ }
}
-void Logger::warn(const char* msg, const Exception& ex, ...)
+bool Logger::levelEnabled(LEVEL level)
{
- WRITE_LOG_EX(A2_WARN, WARN_LABEL, msg, ex);
+ return (level >= logLevel_ && file_.is_open()) || stdoutField_&level;
}
-void Logger::error(const char* msg, ...)
+namespace {
+const std::string& levelToString(Logger::LEVEL level)
{
- WRITE_LOG(A2_ERROR, ERROR_LABEL, msg);
+ switch(level) {
+ case Logger::A2_DEBUG:
+ return DEBUG_LABEL;
+ case Logger::A2_INFO:
+ return INFO_LABEL;
+ case Logger::A2_NOTICE:
+ return NOTICE_LABEL;
+ case Logger::A2_WARN:
+ return WARN_LABEL;
+ case Logger::A2_ERROR:
+ return ERROR_LABEL;
+ default:
+ return A2STR::NIL;
+ }
}
-
-void Logger::error(const char* msg, const Exception& ex, ...)
-{
- WRITE_LOG_EX(A2_ERROR, ERROR_LABEL, msg, ex);
+} // namespace
+
+namespace {
+void writeHeader
+(std::ostream& o, Logger::LEVEL level, const char* sourceFile, int lineNum)
+{
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ char datestr[27]; // 'YYYY-MM-DD hh:mm:ss.uuuuuu'+'\0' = 27 bytes
+ struct tm tm;
+ //tv.tv_sec may not be of type time_t.
+ time_t timesec = tv.tv_sec;
+ localtime_r(&timesec, &tm);
+ size_t dateLength =
+ strftime(datestr, sizeof(datestr), "%Y-%m-%d %H:%M:%S", &tm);
+ assert(dateLength <= (size_t)20);
+ snprintf(datestr+dateLength,
+ sizeof(datestr)-dateLength,
+ ".%06ld", tv.tv_usec);
+ o << datestr << " " << levelToString(level) << " - ";
+ if(sourceFile) {
+ o << "[" << sourceFile << ":" << lineNum << "] ";
+ }
}
+} // namespace
-void Logger::setLogFormatter(LogFormatter* logFormatter)
+namespace {
+void writeStackTrace(std::ostream& o, const std::string& stackTrace)
{
- delete logFormatter_;
- logFormatter_ = logFormatter;
+ o << stackTrace;
}
+} // namespace
-void Logger::setStdoutLogLevel(Logger::LEVEL level, bool enabled)
+namespace {
+void writeLog
+(std::ostream& o,
+ Logger::LEVEL level,
+ const char* sourceFile,
+ int lineNum,
+ const char* msg,
+ const std::string& trace,
+ bool toStream,
+ bool toConsole)
{
- if(enabled) {
- stdoutField_ |= level;
- } else {
- stdoutField_ &= ~level;
+ if(toStream) {
+ writeHeader(o, level, sourceFile, lineNum);
+ o << msg << "\n";
+ writeStackTrace(o, trace);
+ o << std::flush;
+ }
+ if(toConsole) {
+ std::cout << "\n";
+ writeHeader(std::cout, level, 0, 0);
+ std::cout << msg << "\n";
+ writeStackTrace(std::cout, trace);
+ std::cout << std::flush;
}
}
+} // namespace
-void Logger::writeLog
-(std::ostream& o, LEVEL logLevel, const std::string& logLevelLabel,
- const char* msg, va_list ap)
+void Logger::log
+(LEVEL level,
+ const char* sourceFile,
+ int lineNum,
+ const char* msg)
{
- if(logFormatter_) {
- logFormatter_->writeLog(o, logLevel, logLevelLabel, msg, ap);
- }
+ writeLog(file_, level, sourceFile, lineNum, msg, A2STR::NIL,
+ level >= logLevel_ && file_.is_open(),
+ stdoutField_&level);
}
-void Logger::writeStackTrace
-(std::ostream& o, LEVEL logLevel, const std::string& logLevelLabel,
- const Exception& ex)
+void Logger::log
+(LEVEL level,
+ const char* sourceFile,
+ int lineNum,
+ const std::string& msg)
{
- if(logFormatter_) {
- logFormatter_->writeStackTrace(o, logLevel, logLevelLabel, ex);
- }
+ log(level, sourceFile, lineNum, msg.c_str());
}
-bool Logger::debug()
+void Logger::log
+(LEVEL level,
+ const char* sourceFile,
+ int lineNum,
+ const char* msg,
+ const Exception& ex)
{
- return levelEnabled(A2_DEBUG);
+ writeLog(file_, level, sourceFile, lineNum, msg, ex.stackTrace(),
+ level >= logLevel_ && file_.is_open(),
+ stdoutField_&level);
}
-bool Logger::info()
+void Logger::log
+(LEVEL level,
+ const char* sourceFile,
+ int lineNum,
+ const std::string& msg,
+ const Exception& ex)
{
- return levelEnabled(A2_INFO);
+ log(level, sourceFile, lineNum, msg.c_str(), ex);
}
} // namespace aria2