diff --git a/ChangeLog b/ChangeLog index 9bd7e1fc..13d53811 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2010-06-23 Tatsuhiro Tsujikawa + + Made log and log-level option modifiable using + aria2.changeGlobalOption. This means you can dynamically start or + stop logging and change log file and log level. + * doc/aria2c.1.txt + * src/LogFactory.cc + * src/LogFactory.h + * src/LogFormatter.h + * src/Logger.cc + * src/Logger.h + * src/Makefile.am + * src/Makefile.in + * src/SimpleLogFormatter.cc + * src/SimpleLogFormatter.h + * src/SimpleLogger.cc: Removed + * src/SimpleLogger.h: Removed + * src/XmlRpcMethod.cc + * src/XmlRpcMethodImpl.cc + * src/main.cc + 2010-06-23 Tatsuhiro Tsujikawa Request ut_metadata in end-game mode(in other words, more diff --git a/doc/aria2c.1 b/doc/aria2c.1 index c3eb6efe..6d3737a1 100644 --- a/doc/aria2c.1 +++ b/doc/aria2c.1 @@ -2,12 +2,12 @@ .\" Title: aria2c .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 06/02/2010 +.\" Date: 06/23/2010 .\" Manual: Aria2 Manual .\" Source: Aria2 1.9.4 .\" Language: English .\" -.TH "ARIA2C" "1" "06/02/2010" "Aria2 1\&.9\&.4" "Aria2 Manual" +.TH "ARIA2C" "1" "06/23/2010" "Aria2 1\&.9\&.4" "Aria2 Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -60,7 +60,7 @@ subsection for details\&. .RS 4 The file name of the log file\&. If \fI\-\fR -is specified, log is written to stdout\&. +is specified, log is written to stdout\&. If empty string("") is specified, log is not written to file\&. .RE .PP \fB\-j\fR, \fB\-\-max\-concurrent\-downloads\fR=N @@ -2980,7 +2980,7 @@ This method returns global options\&. The response is of type struct\&. Its key .sp \fBaria2\&.changeGlobalOption\fR \fIoptions\fR .sp -This method changes global options dynamically\&. \fIoptions\fR is of type struct and the available options are \fBmax\-concurrent\-downloads\fR, \fBmax\-overall\-download\-limit\fR and \fBmax\-overall\-upload\-limit\fR\&. This method returns "OK" for success\&. +This method changes global options dynamically\&. \fIoptions\fR is of type struct and the available options are \fBmax\-concurrent\-downloads\fR, \fBmax\-overall\-download\-limit\fR, \fBmax\-overall\-upload\-limit\fR, \fBlog\-level\fR and \fBlog\fR\&. Using \fBlog\fR option, you can dynamically start logging or change log file\&. To stop logging, give empty string("") as a parameter value\&. Note that log file is always opened in append mode\&. This method returns "OK" for success\&. .sp \fBaria2\&.purgeDownloadResult\fR .sp diff --git a/doc/aria2c.1.html b/doc/aria2c.1.html index 703eb68d..7a2cc047 100644 --- a/doc/aria2c.1.html +++ b/doc/aria2c.1.html @@ -626,7 +626,7 @@ downloading a file like BitTorrent.

The file name of the log file. If - is specified, log is written to - stdout. + stdout. If empty string("") is specified, log is not written to file.

@@ -3657,8 +3657,11 @@ added download, the response contains keys returned by

aria2.changeGlobalOption options

This method changes global options dynamically. options is of type struct and the available options are max-concurrent-downloads, -max-overall-download-limit and max-overall-upload-limit. This -method returns "OK" for success.

+max-overall-download-limit, max-overall-upload-limit, log-level +and log. Using log option, you can dynamically start logging or +change log file. To stop logging, give empty string("") as a parameter +value. Note that log file is always opened in append mode. This method +returns "OK" for success.

aria2.purgeDownloadResult

This method purges completed/error/removed downloads to free memory. This method returns "OK".

@@ -4199,7 +4202,7 @@ files in the program, then also delete it here.


diff --git a/doc/aria2c.1.txt b/doc/aria2c.1.txt index 57902037..71e07e25 100644 --- a/doc/aria2c.1.txt +++ b/doc/aria2c.1.txt @@ -43,7 +43,7 @@ Basic Options *-l*, *--log*=LOG:: The file name of the log file. If '-' is specified, log is written to - stdout. + stdout. If empty string("") is specified, log is not written to file. *-j*, *--max-concurrent-downloads*=N:: Set maximum number of parallel downloads for every static (HTTP/FTP) URI, @@ -1766,8 +1766,11 @@ added download, the response contains keys returned by This method changes global options dynamically. 'options' is of type struct and the available options are *max-concurrent-downloads*, -*max-overall-download-limit* and *max-overall-upload-limit*. This -method returns "OK" for success. +*max-overall-download-limit*, *max-overall-upload-limit*, *log-level* +and *log*. Using *log* option, you can dynamically start logging or +change log file. To stop logging, give empty string("") as a parameter +value. Note that log file is always opened in append mode. This method +returns "OK" for success. *aria2.purgeDownloadResult* diff --git a/src/LogFactory.cc b/src/LogFactory.cc index a7b99889..d4008336 100644 --- a/src/LogFactory.cc +++ b/src/LogFactory.cc @@ -33,9 +33,10 @@ */ /* copyright --> */ #include "LogFactory.h" -#include "SimpleLogger.h" +#include "SimpleLogFormatter.h" #include "a2io.h" #include "prefs.h" +#include "RecoverableException.h" namespace aria2 { @@ -44,15 +45,39 @@ Logger* LogFactory::logger_ = 0; bool LogFactory::consoleOutput_ = true; Logger::LEVEL LogFactory::logLevel_ = Logger::A2_DEBUG; +void LogFactory::openLogger(Logger* logger) +{ + if(filename_ != DEV_NULL) { + // don't open file DEV_NULL for performance sake. + // This avoids costly unecessary message formatting and write. + logger->openFile(filename_); + } + logger->setLogLevel(logLevel_); +} + +void LogFactory::reconfigure() +{ + if(logger_) { + logger_->closeFile(); + try { + openLogger(logger_); + } catch(RecoverableException& e) { + logger_->closeFile(); + throw; + } + } +} + Logger* LogFactory::getInstance() { if(!logger_) { - SimpleLogger* slogger = new SimpleLogger(); - if(filename_ != DEV_NULL) { - // don't open file DEV_NULL for performance sake. - // This avoids costly unecessary message formatting and write. - slogger->openFile(filename_); + Logger* slogger = new Logger(); + slogger->setLogFormatter(new SimpleLogFormatter()); + try { + openLogger(slogger); + } catch(RecoverableException& e) { + delete slogger; + throw; } - slogger->setLogLevel(logLevel_); if(consoleOutput_) { slogger->setStdoutLogLevel(Logger::A2_NOTICE, true); slogger->setStdoutLogLevel(Logger::A2_WARN, true); @@ -63,6 +88,17 @@ Logger* LogFactory::getInstance() { return logger_; } +void LogFactory::setLogFile(const std::string& name) +{ + if(name == "-") { + filename_ = DEV_STDOUT; + } else if(name == "") { + filename_ = DEV_NULL; + } else { + filename_ = name; + } +} + void LogFactory::setLogLevel(Logger::LEVEL level) { logLevel_ = level; diff --git a/src/LogFactory.h b/src/LogFactory.h index fa3e3d28..02fc0f90 100644 --- a/src/LogFactory.h +++ b/src/LogFactory.h @@ -49,6 +49,8 @@ private: static Logger* logger_; static bool consoleOutput_; static Logger::LEVEL logLevel_; + + static void openLogger(Logger* logger); public: /** * Get logger instance. Returned logger is singleton. @@ -57,11 +59,10 @@ public: static Logger* getInstance(); /** - * Set a filename to write log. + * Set a filename to write log. If name is "-", log is written to + * stdout. If name is "", log is not written to file. */ - static void setLogFile(const std::string& name) { - filename_ = name; - } + static void setLogFile(const std::string& name); /** * Set flag whether the log is printed in console. @@ -71,7 +72,6 @@ public: consoleOutput_ = f; } - /** * Set log level to output. */ @@ -87,6 +87,8 @@ public: * Releases used resources */ static void release(); + + static void reconfigure(); }; } // namespace aria2 diff --git a/src/LogFormatter.h b/src/LogFormatter.h new file mode 100644 index 00000000..7f872298 --- /dev/null +++ b/src/LogFormatter.h @@ -0,0 +1,65 @@ +/* */ +#ifndef D_LOG_FORMATTER_H +#define D_LOG_FORMATTER_H + +#include "common.h" + +#include +#include +#include + +#include "Logger.h" + +namespace aria2 { + +class Exception; + +class LogFormatter { +public: + virtual ~LogFormatter() {} + + virtual void writeLog + (std::ostream& o, Logger::LEVEL logLevel, const std::string& logLevelLabel, + const char* msg, va_list ap) = 0; + + virtual void writeStackTrace + (std::ostream& o, Logger::LEVEL logLevel, const std::string& logLevelLabel, + const Exception& ex) = 0; +}; + +} // namespace aria2 + +#endif // D_LOG_FORMATTER_H diff --git a/src/Logger.cc b/src/Logger.cc index 09eb546f..6048f450 100644 --- a/src/Logger.cc +++ b/src/Logger.cc @@ -40,6 +40,7 @@ #include "DlAbortEx.h" #include "StringFormat.h" #include "message.h" +#include "LogFormatter.h" namespace aria2 { @@ -53,11 +54,13 @@ const std::string Logger::ERROR_LABEL("ERROR"); const std::string Logger::INFO_LABEL("INFO"); -Logger::Logger():logLevel_(Logger::A2_DEBUG), stdoutField_(0) {} +Logger::Logger(): + logFormatter_(0), logLevel_(Logger::A2_DEBUG), stdoutField_(0) {} Logger::~Logger() { closeFile(); + delete logFormatter_; } void Logger::openFile(const std::string& filename) @@ -162,6 +165,12 @@ void Logger::error(const char* msg, const Exception& ex, ...) WRITE_LOG_EX(A2_ERROR, ERROR_LABEL, msg, ex); } +void Logger::setLogFormatter(LogFormatter* logFormatter) +{ + delete logFormatter_; + logFormatter_ = logFormatter; +} + void Logger::setStdoutLogLevel(Logger::LEVEL level, bool enabled) { if(enabled) { @@ -171,4 +180,22 @@ void Logger::setStdoutLogLevel(Logger::LEVEL level, bool enabled) } } +void Logger::writeLog +(std::ostream& o, LEVEL logLevel, const std::string& logLevelLabel, + const char* msg, va_list ap) +{ + if(logFormatter_) { + logFormatter_->writeLog(o, logLevel, logLevelLabel, msg, ap); + } +} + +void Logger::writeStackTrace +(std::ostream& o, LEVEL logLevel, const std::string& logLevelLabel, + const Exception& ex) +{ + if(logFormatter_) { + logFormatter_->writeStackTrace(o, logLevel, logLevelLabel, ex); + } +} + } // namespace aria2 diff --git a/src/Logger.h b/src/Logger.h index 55d75185..4336175a 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -45,6 +45,7 @@ namespace aria2 { class Exception; +class LogFormatter; class Logger { public: @@ -66,6 +67,8 @@ public: static const std::string INFO_LABEL; private: + LogFormatter* logFormatter_; + LEVEL logLevel_; std::ofstream file_; @@ -76,14 +79,14 @@ private: { return (level >= logLevel_ && file_.is_open()) || stdoutField_&level; } -protected: - virtual void writeLog - (std::ostream& o, LEVEL logLevel, const std::string& logLevelLabel, - const char* msg, va_list ap) = 0; - virtual void writeStackTrace + void writeLog (std::ostream& o, LEVEL logLevel, const std::string& logLevelLabel, - const Exception& ex) = 0; + const char* msg, va_list ap); + + void writeStackTrace + (std::ostream& o, LEVEL logLevel, const std::string& logLevelLabel, + const Exception& ex); public: Logger(); @@ -113,6 +116,8 @@ public: void closeFile(); + void setLogFormatter(LogFormatter* logFormatter); + void setLogLevel(LEVEL level) { logLevel_ = level; diff --git a/src/Makefile.am b/src/Makefile.am index 2632de62..430af281 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,8 @@ SRCS = Socket.h\ DlRetryEx.cc DlRetryEx.h\ DownloadFailureException.cc DownloadFailureException.h\ Logger.cc Logger.h\ - SimpleLogger.cc SimpleLogger.h\ + LogFormatter.h\ + SimpleLogFormatter.cc SimpleLogFormatter.h\ DiskWriter.h\ DiskWriterFactory.h\ AbstractDiskWriter.cc AbstractDiskWriter.h\ diff --git a/src/Makefile.in b/src/Makefile.in index a49dd613..f77d3cd9 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -342,9 +342,9 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ FatalException.h RecoverableException.cc \ RecoverableException.h DlAbortEx.cc DlAbortEx.h DlRetryEx.cc \ DlRetryEx.h DownloadFailureException.cc \ - DownloadFailureException.h Logger.cc Logger.h SimpleLogger.cc \ - SimpleLogger.h DiskWriter.h DiskWriterFactory.h \ - AbstractDiskWriter.cc AbstractDiskWriter.h \ + DownloadFailureException.h Logger.cc Logger.h LogFormatter.h \ + SimpleLogFormatter.cc SimpleLogFormatter.h DiskWriter.h \ + DiskWriterFactory.h AbstractDiskWriter.cc AbstractDiskWriter.h \ DefaultDiskWriter.cc DefaultDiskWriter.h \ DefaultDiskWriterFactory.cc DefaultDiskWriterFactory.h File.cc \ File.h Option.cc Option.h Base64.cc Base64.h base32.cc \ @@ -815,7 +815,7 @@ am__objects_32 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ Request.$(OBJEXT) Exception.$(OBJEXT) FatalException.$(OBJEXT) \ RecoverableException.$(OBJEXT) DlAbortEx.$(OBJEXT) \ DlRetryEx.$(OBJEXT) DownloadFailureException.$(OBJEXT) \ - Logger.$(OBJEXT) SimpleLogger.$(OBJEXT) \ + Logger.$(OBJEXT) SimpleLogFormatter.$(OBJEXT) \ AbstractDiskWriter.$(OBJEXT) DefaultDiskWriter.$(OBJEXT) \ DefaultDiskWriterFactory.$(OBJEXT) File.$(OBJEXT) \ Option.$(OBJEXT) Base64.$(OBJEXT) base32.$(OBJEXT) \ @@ -1122,9 +1122,9 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \ FatalException.h RecoverableException.cc \ RecoverableException.h DlAbortEx.cc DlAbortEx.h DlRetryEx.cc \ DlRetryEx.h DownloadFailureException.cc \ - DownloadFailureException.h Logger.cc Logger.h SimpleLogger.cc \ - SimpleLogger.h DiskWriter.h DiskWriterFactory.h \ - AbstractDiskWriter.cc AbstractDiskWriter.h \ + DownloadFailureException.h Logger.cc Logger.h LogFormatter.h \ + SimpleLogFormatter.cc SimpleLogFormatter.h DiskWriter.h \ + DiskWriterFactory.h AbstractDiskWriter.cc AbstractDiskWriter.h \ DefaultDiskWriter.cc DefaultDiskWriter.h \ DefaultDiskWriterFactory.cc DefaultDiskWriterFactory.h File.cc \ File.h Option.cc Option.h Base64.cc Base64.h base32.cc \ @@ -1594,7 +1594,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SessionSerializer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Signature.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleBtMessage.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogger.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogFormatter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleRandomizer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingleFileAllocationIterator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SleepCommand.Po@am__quote@ diff --git a/src/SimpleLogger.cc b/src/SimpleLogFormatter.cc similarity index 91% rename from src/SimpleLogger.cc rename to src/SimpleLogFormatter.cc index 4b3382e5..fc7ee41e 100644 --- a/src/SimpleLogger.cc +++ b/src/SimpleLogFormatter.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 @@ -32,9 +32,10 @@ * files in the program, then also delete it here. */ /* copyright --> */ -#include "SimpleLogger.h" +#include "SimpleLogFormatter.h" #include +#include #include "util.h" #include "a2time.h" @@ -44,13 +45,17 @@ namespace aria2 { +SimpleLogFormatter::SimpleLogFormatter() {} + +SimpleLogFormatter::~SimpleLogFormatter() {} + static void writeHeader (std::ostream& o, const std::string& date, const std::string& logLevelLabel) { o << StringFormat("%s %s - ", date.c_str(), logLevelLabel.c_str()); } -void SimpleLogger::writeLog +void SimpleLogFormatter::writeLog (std::ostream& o, Logger::LEVEL level, const std::string& logLevelLabel, const char* msg, va_list ap) { @@ -79,7 +84,7 @@ void SimpleLogger::writeLog } } -void SimpleLogger::writeStackTrace +void SimpleLogFormatter::writeStackTrace (std::ostream& o, Logger::LEVEL level, const std::string& logLevelLabel, const Exception& e) { diff --git a/src/SimpleLogger.h b/src/SimpleLogFormatter.h similarity index 79% rename from src/SimpleLogger.h rename to src/SimpleLogFormatter.h index 603ddaa5..5819a500 100644 --- a/src/SimpleLogger.h +++ b/src/SimpleLogFormatter.h @@ -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 @@ -32,25 +32,28 @@ * files in the program, then also delete it here. */ /* copyright --> */ -#ifndef _D_SIMPLE_LOGGER_H_ -#define _D_SIMPLE_LOGGER_H_ +#ifndef D_SIMPLE_LOG_FORMATTER_H +#define D_SIMPLE_LOG_FORMATTER_H -#include "Logger.h" +#include "LogFormatter.h" namespace aria2 { -class SimpleLogger:public Logger { -protected: +class SimpleLogFormatter:public LogFormatter { +public: + SimpleLogFormatter(); + + virtual ~SimpleLogFormatter(); + virtual void writeLog - (std::ostream& out, Logger::LEVEL logLevel, const std::string& logLevelLabel, + (std::ostream& o, Logger::LEVEL logLevel, const std::string& logLevelLabel, const char* msg, va_list ap); virtual void writeStackTrace - (std::ostream& out, Logger::LEVEL logLevel, const std::string& logLevelLabel, + (std::ostream& o, Logger::LEVEL logLevel, const std::string& logLevelLabel, const Exception& e); }; } // namespace aria2 -#endif // _D_SIMPLE_LOGGER_H_ - +#endif // D_SIMPLE_LOG_FORMATTER_H diff --git a/src/XmlRpcMethod.cc b/src/XmlRpcMethod.cc index fc305fdf..56781374 100644 --- a/src/XmlRpcMethod.cc +++ b/src/XmlRpcMethod.cc @@ -186,6 +186,8 @@ const std::set& listChangeableGlobalOptions() PREF_MAX_OVERALL_UPLOAD_LIMIT, PREF_MAX_OVERALL_DOWNLOAD_LIMIT, PREF_MAX_CONCURRENT_DOWNLOADS, + PREF_LOG, + PREF_LOG_LEVEL }; static std::set options(vbegin(OPTIONS), vend(OPTIONS)); return options; diff --git a/src/XmlRpcMethodImpl.cc b/src/XmlRpcMethodImpl.cc index d310b372..4cb2e843 100644 --- a/src/XmlRpcMethodImpl.cc +++ b/src/XmlRpcMethodImpl.cc @@ -964,6 +964,18 @@ SharedHandle ChangeGlobalOptionXmlRpcMethod::process (option->getAsInt(PREF_MAX_CONCURRENT_DOWNLOADS)); e->getRequestGroupMan()->requestQueueCheck(); } + if(option->defined(PREF_LOG_LEVEL)) { + LogFactory::setLogLevel(option->get(PREF_LOG_LEVEL)); + } + if(option->defined(PREF_LOG)) { + LogFactory::setLogFile(option->get(PREF_LOG)); + try { + LogFactory::reconfigure(); + } catch(RecoverableException& e) { + // TODO no exception handling + } + } + return VLB_OK; } diff --git a/src/main.cc b/src/main.cc index e2fef629..4f91c3bf 100644 --- a/src/main.cc +++ b/src/main.cc @@ -175,13 +175,7 @@ downloadresultcode::RESULT main(int argc, char* argv[]) #ifdef ENABLE_BITTORRENT bittorrent::generateStaticPeerId(op->get(PREF_PEER_ID_PREFIX)); #endif // ENABLE_BITTORRENT - if(op->get(PREF_LOG) == "-") { - LogFactory::setLogFile(DEV_STDOUT); - } else if(op->blank(PREF_LOG)) { - LogFactory::setLogFile(DEV_NULL); - } else { - LogFactory::setLogFile(op->get(PREF_LOG)); - } + LogFactory::setLogFile(op->get(PREF_LOG)); LogFactory::setLogLevel(op->get(PREF_LOG_LEVEL)); if(op->getAsBool(PREF_QUIET)) { LogFactory::setConsoleOutput(false);