Console color output

Log level and download result string is now colored.
pull/36/head
Tatsuhiro Tsujikawa 2012-12-08 21:48:18 +09:00
parent 9a5fff0de0
commit e86fd44dc5
9 changed files with 104 additions and 11 deletions

View File

@ -54,11 +54,12 @@ BufferedFile::BufferedFile(const char* filename, const char* mode)
#else // !__MINGW32__ #else // !__MINGW32__
fp_(a2fopen(filename, mode)), fp_(a2fopen(filename, mode)),
#endif // !__MINGW32__ #endif // !__MINGW32__
open_(fp_) open_(fp_),
supportsColor_(isatty(fileno(fp_)))
{} {}
BufferedFile::BufferedFile(FILE* fp) BufferedFile::BufferedFile(FILE* fp)
: fp_(fp), open_(true) : fp_(fp), open_(true), supportsColor_(isatty(fileno(fp)))
{} {}
BufferedFile::~BufferedFile() BufferedFile::~BufferedFile()
@ -169,4 +170,9 @@ int BufferedFile::flush()
return fflush(fp_); return fflush(fp_);
} }
bool BufferedFile::supportsColor()
{
return supportsColor_;
}
} // namespace aria2 } // namespace aria2

View File

@ -77,6 +77,7 @@ public:
virtual int printf(const char* format, ...); virtual int printf(const char* format, ...);
// wrapper for fflush // wrapper for fflush
virtual int flush(); virtual int flush();
virtual bool supportsColor();
// Mode for reading // Mode for reading
static const char READ[]; static const char READ[];
// Mode for writing // Mode for writing
@ -91,6 +92,7 @@ private:
FILE* fp_; FILE* fp_;
// true when file has been opened. // true when file has been opened.
bool open_; bool open_;
bool supportsColor_;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -34,6 +34,7 @@
/* copyright --> */ /* copyright --> */
#include "Logger.h" #include "Logger.h"
#include <unistd.h>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
@ -50,7 +51,14 @@ namespace aria2 {
Logger::Logger() Logger::Logger()
: logLevel_(Logger::A2_DEBUG), : logLevel_(Logger::A2_DEBUG),
stdoutField_(0) stdoutField_(0),
#ifdef __MINGW32__
// Windows DOS prompt does not handle ANSI color code, so make
// this false.
useColor_(false)
#else // !__MINGW32__
useColor_(isatty(STDOUT_FILENO) == 1)
#endif // !__MINGW32__
{} {}
Logger::~Logger() Logger::~Logger()
@ -132,10 +140,34 @@ void writeHeader
} // namespace } // namespace
namespace { namespace {
template<typename Output> const char* levelColor(Logger::LEVEL level)
void writeHeaderConsole(Output& fp, Logger::LEVEL level)
{ {
fp.printf("[%s] ", levelToString(level)); switch(level) {
case Logger::A2_DEBUG:
case Logger::A2_INFO:
// We don't print these levels in console
return "";
case Logger::A2_NOTICE:
return "\033[1;32m";
case Logger::A2_WARN:
return "\033[1;33m";
case Logger::A2_ERROR:
return "\033[1;31m";
default:
return "";
}
}
} // namespace
namespace {
template<typename Output>
void writeHeaderConsole(Output& fp, Logger::LEVEL level, bool useColor)
{
if(useColor) {
fp.printf("[%s%s\033[0m] ", levelColor(level), levelToString(level));
} else {
fp.printf("[%s] ", levelToString(level));
}
} }
} // namespace } // namespace
@ -164,7 +196,7 @@ void Logger::writeLog
} }
if(toConsole) { if(toConsole) {
global::cout()->printf("\n"); global::cout()->printf("\n");
writeHeaderConsole(*global::cout(), level); writeHeaderConsole(*global::cout(), level, useColor_);
global::cout()->printf("%s\n", msg); global::cout()->printf("%s\n", msg);
writeStackTrace(*global::cout(), trace); writeStackTrace(*global::cout(), trace);
global::cout()->flush(); global::cout()->flush();

View File

@ -59,6 +59,7 @@ private:
LEVEL logLevel_; LEVEL logLevel_;
SharedHandle<OutputFile> fpp_; SharedHandle<OutputFile> fpp_;
int stdoutField_; int stdoutField_;
bool useColor_;
// Don't allow copying // Don't allow copying
Logger(const Logger&); Logger(const Logger&);
Logger& operator=(const Logger&); Logger& operator=(const Logger&);

View File

@ -45,6 +45,7 @@ public:
virtual size_t write(const char* str) { return 0; } virtual size_t write(const char* str) { return 0; }
virtual int printf(const char* format, ...) { return 0; } virtual int printf(const char* format, ...) { return 0; }
virtual int flush() { return 0; } virtual int flush() { return 0; }
virtual bool supportsColor() { return false; }
}; };
} // namespace aria2 } // namespace aria2

View File

@ -47,6 +47,8 @@ public:
virtual size_t write(const char* str) = 0; virtual size_t write(const char* str) = 0;
virtual int printf(const char* format, ...) = 0; virtual int printf(const char* format, ...) = 0;
virtual int flush() = 0; virtual int flush() = 0;
// Returns true if the output medium supports ANSI color codes.
virtual bool supportsColor() = 0;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -716,6 +716,48 @@ RequestGroupMan::DownloadStat RequestGroupMan::getDownloadStat() const
lastError); lastError);
} }
enum DownloadStatus {
A2_STATUS_OK,
A2_STATUS_INPR,
A2_STATUS_RM,
A2_STATUS_ERR
};
namespace {
const char* getStatusStr(DownloadStatus status, bool useColor)
{
// status string is formatted in 4 characters wide.
switch(status) {
case(A2_STATUS_OK):
if(useColor) {
return "\033[1;32mOK\033[0m ";
} else {
return "OK ";
}
case(A2_STATUS_INPR):
if(useColor) {
return "\033[1;34mINPR\033[0m";
} else {
return "INPR";
}
case(A2_STATUS_RM):
if(useColor) {
return "\033[1mRM\033[0m ";
} else {
return "RM ";
}
case(A2_STATUS_ERR):
if(useColor) {
return "\033[1;31mERR\033[0m ";
} else {
return "ERR ";
}
default:
return "";
}
}
} // namespace
void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
{ {
#ifdef __MINGW32__ #ifdef __MINGW32__
@ -739,6 +781,7 @@ void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
} }
std::string line(pathRowSize, '='); std::string line(pathRowSize, '=');
o.printf("%s\n", line.c_str()); o.printf("%s\n", line.c_str());
bool useColor = o.supportsColor();
int ok = 0; int ok = 0;
int err = 0; int err = 0;
int inpr = 0; int inpr = 0;
@ -751,16 +794,16 @@ void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
} }
const char* status; const char* status;
if((*itr)->result == error_code::FINISHED) { if((*itr)->result == error_code::FINISHED) {
status = "OK"; status = getStatusStr(A2_STATUS_OK, useColor);
++ok; ++ok;
} else if((*itr)->result == error_code::IN_PROGRESS) { } else if((*itr)->result == error_code::IN_PROGRESS) {
status = "INPR"; status = getStatusStr(A2_STATUS_INPR, useColor);
++inpr; ++inpr;
} else if((*itr)->result == error_code::REMOVED) { } else if((*itr)->result == error_code::REMOVED) {
status = "RM"; status = getStatusStr(A2_STATUS_RM, useColor);
++rm; ++rm;
} else { } else {
status = "ERR"; status = getStatusStr(A2_STATUS_ERR, useColor);
++err; ++err;
} }
if(full) { if(full) {

View File

@ -103,4 +103,9 @@ int WinConsoleFile::flush()
return 0; return 0;
} }
bool WinConsoleFile::supportsColor()
{
return false;
}
} // namespace aria2 } // namespace aria2

View File

@ -47,6 +47,7 @@ public:
virtual size_t write(const char* str); virtual size_t write(const char* str);
virtual int printf(const char* format, ...); virtual int printf(const char* format, ...);
virtual int flush(); virtual int flush();
virtual bool supportsColor();
private: private:
DWORD stdHandle_; DWORD stdHandle_;
// Don't allow copying // Don't allow copying