Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ColorCoutSink for WIN32 #132

Merged
merged 4 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only formatting difference. It's only a snippet and the change doesn't have a big impact so I'm fine with the formatting changes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh ops the formatting wasn't supposed to be pushed, the code is that it has a missing ";" so that's why the line was modified. I can keep it that way if you want.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the observation and fix

<< "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_;
};