Support terminal colors for logger.

master
Chunting Gu 6 years ago
parent 6f7acfc442
commit 0ad277322f

@ -9,6 +9,7 @@ endif()
project(webcc) project(webcc)
option(WEBCC_ENABLE_SOAP "Enable SOAP support (need pugixml)?" ON) option(WEBCC_ENABLE_SOAP "Enable SOAP support (need pugixml)?" ON)
option(WEBCC_ENABLE_TEST "Build test?" ON)
option(WEBCC_ENABLE_UNITTEST "Build unit test?" ON) option(WEBCC_ENABLE_UNITTEST "Build unit test?" ON)
option(WEBCC_ENABLE_EXAMPLES "Build examples?" ON) option(WEBCC_ENABLE_EXAMPLES "Build examples?" ON)
@ -140,6 +141,10 @@ if(WEBCC_ENABLE_EXAMPLES)
add_subdirectory(examples) add_subdirectory(examples)
endif() endif()
if(WEBCC_ENABLE_TEST)
add_subdirectory(test)
endif()
if(WEBCC_ENABLE_UNITTEST) if(WEBCC_ENABLE_UNITTEST)
add_subdirectory(${THIRD_PARTY_DIR}/src/gtest) add_subdirectory(${THIRD_PARTY_DIR}/src/gtest)
add_subdirectory(unittest) add_subdirectory(unittest)

@ -20,7 +20,7 @@ AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true BinPackArguments: true
BinPackParameters: true BinPackParameters: true
BraceWrapping: BraceWrapping:
AfterClass: false AfterClass: false
AfterControlStatement: false AfterControlStatement: false
AfterEnum: false AfterEnum: false
@ -56,12 +56,12 @@ DerivePointerAlignment: false
DisableFormat: false DisableFormat: false
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true FixNamespaceComments: true
ForEachMacros: ForEachMacros:
- foreach - foreach
- Q_FOREACH - Q_FOREACH
- BOOST_FOREACH - BOOST_FOREACH
IncludeBlocks: Preserve IncludeBlocks: Preserve
IncludeCategories: IncludeCategories:
- Regex: '^<ext/.*\.h>' - Regex: '^<ext/.*\.h>'
Priority: 2 Priority: 2
- Regex: '^<.*\.h>' - Regex: '^<.*\.h>'
@ -95,9 +95,9 @@ PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000 PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200 PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left PointerAlignment: Left
RawStringFormats: RawStringFormats:
- Language: Cpp - Language: Cpp
Delimiters: Delimiters:
- cc - cc
- CC - CC
- cpp - cpp
@ -108,12 +108,12 @@ RawStringFormats:
CanonicalDelimiter: '' CanonicalDelimiter: ''
BasedOnStyle: google BasedOnStyle: google
- Language: TextProto - Language: TextProto
Delimiters: Delimiters:
- pb - pb
- PB - PB
- proto - proto
- PROTO - PROTO
EnclosingFunctions: EnclosingFunctions:
- EqualsProto - EqualsProto
- EquivToProto - EquivToProto
- PARSE_PARTIAL_TEXT_PROTO - PARSE_PARTIAL_TEXT_PROTO

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

@ -0,0 +1,19 @@
# Tests
# Common libraries to link.
set(TEST_COMMON_LIBS webcc ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES}
"${CMAKE_THREAD_LIBS_INIT}")
if(WIN32)
set(TEST_COMMON_LIBS ${TEST_COMMON_LIBS} zlibstatic crypt32)
else()
set(TEST_COMMON_LIBS ${TEST_COMMON_LIBS} ${ZLIB_LIBRARIES})
endif()
if(UNIX)
# Add `-ldl` for Linux to avoid "undefined reference to `dlopen'".
set(TEST_COMMON_LIBS ${TEST_COMMON_LIBS} ${CMAKE_DL_LIBS})
endif()
add_executable(test_logger test_logger.cc)
target_link_libraries(test_logger ${TEST_COMMON_LIBS})

@ -0,0 +1,15 @@
#include "webcc/logger.h"
int main() {
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);
LOG_INFO("info");
LOG_WARN("warn");
LOG_ERRO("erro");
LOG_VERB("verb");
LOG_FATA("fata");
LOG_INFO("info");
return 0;
}

@ -43,7 +43,7 @@ HttpRequestPtr HttpRequestBuilder::Build() {
std::string data; std::string data;
CreateFormData(&data, boundary); CreateFormData(&data, boundary);
// Ingore gzip since most servers don't support it. // Ingore gzip since most servers don't support it.
request->SetContent(std::move(data), true); request->SetContent(std::move(data), true);
} }

@ -24,6 +24,16 @@
namespace webcc { namespace webcc {
// -----------------------------------------------------------------------------
static std::string g_main_thread_id;
static const char* kLevelNames[] = {
"VERB", "INFO", "WARN", "ERRO", "FATA"
};
// -----------------------------------------------------------------------------
struct Logger { struct Logger {
Logger() : file(nullptr), modes(0) { Logger() : file(nullptr), modes(0) {
} }
@ -56,11 +66,96 @@ struct Logger {
// Global logger. // Global logger.
static Logger g_logger; static Logger g_logger;
static std::string g_main_thread_id; // -----------------------------------------------------------------------------
static const char* kLevelNames[] = { // The colors related code was adapted from Loguru. See:
"VERB", "INFO", "WARN", "ERRO", "FATA" // https://github.com/emilk/loguru/blob/master/loguru.cpp
}; // Thanks to Loguru!
bool g_colorlogtostderr = true;
static const bool g_terminal_has_color = []() {
#if (defined(WIN32) || defined(_WIN64))
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
if (houtput != INVALID_HANDLE_VALUE) {
DWORD mode = 0;
GetConsoleMode(houtput, &mode);
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
return SetConsoleMode(houtput, mode) != 0;
}
return false;
#else
const char* term = getenv("TERM");
if (term == nullptr) {
return false;
}
return strcmp(term, "cygwin") == 0 || strcmp(term, "linux") == 0 ||
strcmp(term, "rxvt-unicode-256color") == 0 ||
strcmp(term, "screen") == 0 || strcmp(term, "screen-256color") == 0 ||
strcmp(term, "tmux-256color") == 0 || strcmp(term, "xterm") == 0 ||
strcmp(term, "xterm-256color") == 0 ||
strcmp(term, "xterm-termite") == 0 || strcmp(term, "xterm-color") == 0;
#endif
}();
// Colors
#ifdef _WIN32
#define VTSEQ(ID) ("\x1b[1;" #ID "m")
#else
#define VTSEQ(ID) ("\x1b[" #ID "m")
#endif
const char* TerminalBlack() {
return g_terminal_has_color ? VTSEQ(30) : "";
}
const char* TerminalRed() {
return g_terminal_has_color ? VTSEQ(31) : "";
}
const char* TerminalGreen() {
return g_terminal_has_color ? VTSEQ(32) : "";
}
const char* TerminalYellow() {
return g_terminal_has_color ? VTSEQ(33) : "";
}
const char* TerminalBlue() {
return g_terminal_has_color ? VTSEQ(34) : "";
}
const char* TerminalPurple() {
return g_terminal_has_color ? VTSEQ(35) : "";
}
const char* TerminalCyan() {
return g_terminal_has_color ? VTSEQ(36) : "";
}
const char* TerminalLightGray() {
return g_terminal_has_color ? VTSEQ(37) : "";
}
const char* TerminalWhite() {
return g_terminal_has_color ? VTSEQ(37) : "";
}
const char* TerminalLightRed() {
return g_terminal_has_color ? VTSEQ(91) : "";
}
const char* TerminalDim() {
return g_terminal_has_color ? VTSEQ(2) : "";
}
// Formating
const char* TerminalBold() {
return g_terminal_has_color ? VTSEQ(1) : "";
}
const char* TerminalUnderline() {
return g_terminal_has_color ? VTSEQ(4) : "";
}
// You should end each line with this!
const char* TerminalReset() {
return g_terminal_has_color ? VTSEQ(0) : "";
}
namespace bfs = boost::filesystem; namespace bfs = boost::filesystem;
@ -123,8 +218,8 @@ static std::string GetTimestamp() {
ss << std::put_time(std::localtime(&t), "%Y-%m-%d %H:%M:%S"); ss << std::put_time(std::localtime(&t), "%Y-%m-%d %H:%M:%S");
std::chrono::milliseconds milli_seconds = std::chrono::milliseconds milli_seconds =
std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()); now.time_since_epoch());
std::string micro_seconds_str = std::to_string(milli_seconds.count() % 1000); std::string micro_seconds_str = std::to_string(milli_seconds.count() % 1000);
while (micro_seconds_str.size() < 3) { while (micro_seconds_str.size() < 3) {
micro_seconds_str = "0" + micro_seconds_str; micro_seconds_str = "0" + micro_seconds_str;
@ -168,13 +263,33 @@ void LogWrite(int level, const char* file, int line, const char* format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
fprintf(stderr, "%s, %s, %7s, %25s, %4d, ", if (g_colorlogtostderr && g_terminal_has_color) {
timestamp.c_str(), kLevelNames[level], thread_id.c_str(), if (level < WEBCC_WARN) {
file, line); fprintf(stderr, "%s%s%s, %s, %7s, %25s, %4d, %s",
TerminalReset(), TerminalDim(),
timestamp.c_str(), kLevelNames[level], thread_id.c_str(),
file, line,
level == WEBCC_INFO ? TerminalReset() : ""); // un-dim for INFO
} else {
fprintf(stderr, "%s%s%s, %s, %7s, %25s, %4d, ",
TerminalReset(),
level == WEBCC_WARN ? TerminalYellow() : TerminalRed(),
timestamp.c_str(), kLevelNames[level], thread_id.c_str(),
file, line);
}
vfprintf(stderr, format, args); vfprintf(stderr, format, args);
fprintf(stderr, "\n"); fprintf(stderr, "%s\n", TerminalReset());
} else {
fprintf(stderr, "%s, %s, %7s, %25s, %4d, ",
timestamp.c_str(), kLevelNames[level], thread_id.c_str(),
file, line);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
}
if ((g_logger.modes & LOG_FLUSH) != 0) { if ((g_logger.modes & LOG_FLUSH) != 0) {
fflush(stderr); fflush(stderr);

Loading…
Cancel
Save