Skip to content

Commit

Permalink
Update ColorCoutSink for WIN32 (#132)
Browse files Browse the repository at this point in the history
* Update ColorCoutSink for WIN32
* Separate sinks between Linux and Windows
  • Loading branch information
lakor64 authored Nov 30, 2022
1 parent e1c343d commit aee2a63
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 53 deletions.
22 changes: 9 additions & 13 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,15 @@ if(CHOICE_SINK_SYSLOG)
endif()

if(CHOICE_SINK_SNIPPETS)

# ColoredCout is currently only implemented for UNIX/Linux terminals
if(UNIX)
# Log with color formatting to std::cout
include_directories(${g3sinks_SOURCE_DIR}/sink_snippets/src
${G3LOG_INCLUDE_DIR})
add_executable(example_coloredcout snippet_coloredcout_main.cpp)
target_link_libraries(
example_coloredcout
PRIVATE gtest_main
PRIVATE ${G3LOG_LIBRARY})
target_compile_options(example_coloredcout PRIVATE)
endif()
# Log with color formatting to std::cout
include_directories(${g3sinks_SOURCE_DIR}/sink_snippets/src
${G3LOG_INCLUDE_DIR})
add_executable(example_coloredcout snippet_coloredcout_main.cpp)
target_link_libraries(
example_coloredcout
PRIVATE gtest_main
PRIVATE ${G3LOG_LIBRARY})
target_compile_options(example_coloredcout PRIVATE)

# shared memory, file descriptor sink.
verifyfilelogdependencies(FILE_LOG_SINK_ERROR)
Expand Down
14 changes: 8 additions & 6 deletions examples/snippet_coloredcout_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ int main() {
LOG(INFO) << "An INFO message in white";
LOG(WARNING) << "A WARNING message will be in yellow";
#if 0
LOG(FATAL) << "This call will exit the example. A failed CHECK call, \n"
<< "a LOG(FATAL) or a fatal crash (seg fault or similar) will show up in RED\n"
<< "\n\nThis call will also be DUPLICATED. One FATAL LOG message will be shown through the \n"
<< "the crash handler and sent to cout, the LOG call will asynchronously send the LOG output to cout.\n"
<< "Depending on when the crash handler sends the cout message the duplicate message will show up in \n"
<< "ANY of the defined colors and might be INTERLEAVED with the other messages. Interleaving is to be expected by asynchronously calls"
LOG(FATAL)
<< "This call will exit the example. A failed CHECK call, \n"
<< "a LOG(FATAL) or a fatal crash (seg fault or similar) will show up in RED\n"
<< "\n\nThis call will also be DUPLICATED. One FATAL LOG message will be shown through the \n"
<< "the crash handler and sent to cout, the LOG call will asynchronously send the LOG output to cout.\n"
<< "Depending on when the crash handler sends the cout message the duplicate message will show up in \n"
<< "ANY of the defined colors and might be INTERLEAVED with the other messages. Interleaving is to be "
"expected by asynchronously calls";
#endif
} // at this point all enqueued LOGs will have gone through in FIFO order and the logger is shutdown.

Expand Down
39 changes: 5 additions & 34 deletions sink_snippets/src/g3sinks/ColorCoutSink.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,11 @@
#include <iostream>
#include <g3log/logmessage.hpp>

// NOTE: This works only on Linux/OSX
// TODO KjellKod: For Windows terminals you can tweak this easily: https://stackoverflow.com/a/4053879/1066879
struct ColorCoutSink {
// Linux xterm color
// http://stackoverflow.com/questions/2616906/how-do-i-output-coloured-text-to-a-linux-terminal
enum FG_Color {YELLOW = 33, RED = 31, GREEN = 32, WHITE = 37};

FG_Color GetColor(const LEVELS level) const {
if (level.value == WARNING.value) { return YELLOW; }
if (level.value == G3LOG_DEBUG.value) { return GREEN; }
if (g3::internal::wasFatal(level)) { return RED; }

return WHITE;
}

void reset() {
std::ostringstream oss;
oss << "\033[" << WHITE << "m" << " " << "\033[m" << std::endl;
std::cout << oss.str();
}

void ReceiveLogMessage(g3::LogMessageMover logEntry) {
auto level = logEntry.get()._level;
auto color = GetColor(level);

reset();
std::ostringstream oss;
oss << "\033[" << color << "m"
<< logEntry.get().toString() << "\033[m" << std::endl;
std::cout << oss.str();
reset();
}
};

#ifdef _WIN32
#include "ColorCoutSinkWindows.h"
#else
#include "ColorCoutSinkLinux.h"
#endif

/* Example usage from snippet_coloredcout_main.cpp
#include <g3log/g3log.hpp>
Expand Down
35 changes: 35 additions & 0 deletions sink_snippets/src/g3sinks/ColorCoutSinkLinux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

struct ColorCoutSink {
// Linux xterm color
// http://stackoverflow.com/questions/2616906/how-do-i-output-coloured-text-to-a-linux-terminal
enum FG_Color {YELLOW = 33, RED = 31, GREEN = 32, WHITE = 37};


FG_Color GetColor(const LEVELS level) const {
if (level.value == WARNING.value) { return YELLOW; }
if (level.value == G3LOG_DEBUG.value) { return GREEN; }
if (g3::internal::wasFatal(level)) { return RED; }

return WHITE;
}

void reset() {
std::ostringstream oss;
oss << "\033[" << WHITE << "m" << " " << "\033[m" << std::endl;
std::cout << oss.str();
}

void ReceiveLogMessage(g3::LogMessageMover logEntry) {
auto level = logEntry.get()._level;
auto color = GetColor(level);

reset();

std::ostringstream oss;
oss << "\033[" << color << "m"
<< logEntry.get().toString() << "\033[m" << std::endl;
std::cout << oss.str();
reset();
}
};
45 changes: 45 additions & 0 deletions sink_snippets/src/g3sinks/ColorCoutSinkWindows.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif

#include <Windows.h>

struct ColorCoutSink {
ColorCoutSink() : hHandle_(GetStdHandle(STD_OUTPUT_HANDLE)) {}

// Windows colors
// https://docs.microsoft.com/en-us/windows/console/console-screen-buffers#character-attributes
enum FG_Color { YELLOW = FOREGROUND_RED | FOREGROUND_GREEN, RED = FOREGROUND_RED, GREEN = FOREGROUND_GREEN, WHITE = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED };


FG_Color GetColor(const LEVELS level) const {
if (level.value == WARNING.value) { return YELLOW; }
if (level.value == G3LOG_DEBUG.value) { return GREEN; }
if (g3::internal::wasFatal(level)) { return RED; }

return WHITE;
}

void reset() {
SetConsoleTextAttribute(hHandle_, WHITE);
}

void ReceiveLogMessage(g3::LogMessageMover logEntry) {
auto level = logEntry.get()._level;
auto color = GetColor(level);

reset();

auto str = logEntry.get().toString();
SetConsoleTextAttribute(hHandle_, (WORD)color);

std::cout << str;

reset();
}

private:
HANDLE hHandle_;
};

0 comments on commit aee2a63

Please sign in to comment.