Belle II Software light-2406-ragdoll
LogConnectionConsole.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <framework/logging/LogConnectionConsole.h>
10#include <framework/logging/LogMessage.h>
11#include <boost/python.hpp>
12#include <boost/algorithm/string.hpp>
13#include <sstream>
14#include <cstring> // strerror()
15#include <unistd.h> // isatty(), dup()
16#include <cstdlib> // getenv()
17
18using namespace Belle2;
19
22
24 m_fd(dup(outputFD)), m_color(color)
25{
26 // check fd
27 if (m_fd < 0) throw std::runtime_error(std::string("Error duplicating file descriptor: ") + std::strerror(errno));
28}
29
31{
32 if (m_fd > 0) close(m_fd);
33}
34
36{
37 return s_pythonLoggingEnabled || m_fd >= 0;
38}
39
41{
42 //enable color for TTYs with color support (list taken from gtest)
43 const bool isTTY = isatty(fileDescriptor);
44 const std::string termName = getenv("TERM") ? getenv("TERM") : "";
45 const bool useColor = isTTY and
46 (termName == "xterm" or termName == "xterm-color" or termName == "xterm-256color" or
47 termName == "sceen" or termName == "screen-256color" or termName == "tmux" or
48 termName == "tmux-256color" or termName == "rxvt-unicode" or
49 termName == "rxvt-unicode-256color" or termName == "linux" or termName == "cygwin");
50 return useColor;
51}
52
53void LogConnectionConsole::write(const std::string& message)
54{
56 auto pymessage = boost::python::import("sys").attr("stdout");
57 pymessage.attr("write")(message);
58 pymessage.attr("flush")();
59 } else {
60 ::write(m_fd, message.data(), message.size());
61 }
62}
63
65{
66 if (!isConnected()) return false;
67 // format message
68 std::stringstream stream;
69 if (m_color) {
70 const std::string color_str[] = {
71 "\x1b[32m", // Debug : green
72 "", // Info : terminal default
73 "\x1b[34m", // Result : blue
74 "\x1b[33m", // Warning: yellow
75 "\x1b[31m", // Error : red
76 "\x1b[07m\x1b[31m" // Fatal : red reversed
77 };
78 const std::string& c{color_str[message.getLogLevel()]};
79 stream << c;
80 }
81 stream << message;
82 std::string messagestr = stream.str();
84 // remove trailing whitespace
85 boost::trim_right_if(messagestr, boost::is_any_of(" \t\n\r"));
86 // escape all remaining newlines
87 boost::replace_all(messagestr, "\n", "\\n");
88 // and make sure we end in an actual newline
89 messagestr += "\n";
90 }
91 if (m_color) {
92 messagestr += "\x1b[m";
93 }
94 write(messagestr);
95 return true;
96}
97
99{
100 // If python logging is enabled we need to give jupyter some time to flush
101 // the output as this happens only in the output thread. Seems flushing again is fine :D
103 boost::python::import("sys").attr("stdout").attr("flush")();
104 }
105}
bool m_color
Flag for color output.
static bool getPythonLoggingEnabled()
Check whether console logging via python is enabled.
static bool s_escapeNewlinesEnabled
Flag to indicate whether newlines should be replaced by ' ' in the output.
~LogConnectionConsole() override
Destructor.
LogConnectionConsole(int outputFD, bool color)
Constructor.
static bool terminalSupportsColors(int fileDescriptor)
Returns true if the given file descriptor is a tty and supports colors.
static bool s_pythonLoggingEnabled
Flag to indicate whether log messages should be sent to python sys.stdout.
bool isConnected() override
Returns true if the connection to the io stream could be established.
bool sendMessage(const LogMessage &message) override
Sends a log message.
int m_fd
The output stream used for sending the log message.
void finalizeOnAbort() override
Make sure output is flushed on abort.
void write(const std::string &message)
Send a preformatted string message to the connected output.
The LogMessage class.
Definition: LogMessage.h:29
Abstract base class for different kinds of events.
Definition: ClusterUtils.h:24