#include "base/scriptvariable.hpp"
#include "base/context.hpp"
#include "base/clicommand.hpp"
+#include "base/console.hpp"
#include "config.h"
#include <boost/program_options.hpp>
#include <boost/tuple/tuple.hpp>
visibleDesc.add_options()
("help", "show this help message")
("version,V", "show version information")
+#ifndef _WIN32
+ ("color", "use VT100 color codes even when stdout is not a terminal")
+#endif /* _WIN32 */
("define,D", po::value<std::vector<std::string> >(), "define a constant")
("library,l", po::value<std::vector<std::string> >(), "load a library")
("include,I", po::value<std::vector<std::string> >(), "add include search directory")
ConfigCompiler::CompileFile(initconfig);
}
+#ifndef _WIN32
+ if (vm.count("color")) {
+ Console::SetType(std::cout, Console_VT100);
+ Console::SetType(std::cerr, Console_VT100);
+ }
+#endif /* _WIN32 */
+
if (vm.count("define")) {
BOOST_FOREACH(const String& define, vm["define"].as<std::vector<std::string> >()) {
String key, value;
mkclass_target(sysloglogger.ti sysloglogger.thpp)
set(base_SOURCES
- application.cpp application.thpp array.cpp clicommand.cpp configerror.cpp context.cpp
+ application.cpp application.thpp array.cpp clicommand.cpp configerror.cpp console.cpp context.cpp
convert.cpp debuginfo.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
exception.cpp fifo.cpp filelogger.cpp filelogger.thpp logger.cpp logger.thpp
netstring.cpp networkstream.cpp object.cpp objectlock.cpp process.cpp
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#include "base/console.hpp"
+#include "base/initialize.hpp"
+
+using namespace icinga;
+
+INITIALIZE_ONCE(&Console::DetectType);
+
+static ConsoleType l_ConsoleType = Console_Dumb;
+
+ConsoleColorTag::ConsoleColorTag(int color)
+ : m_Color(color)
+{ }
+
+std::ostream& icinga::operator<<(std::ostream& fp, const ConsoleColorTag& cct)
+{
+ fp.flush();
+
+#ifndef _WIN32
+ if (l_ConsoleType == Console_VT100)
+ Console::PrintVT100ColorCode(fp, cct.m_Color);
+#else /* _WIN32 */
+ if (l_ConsoleType == Console_Windows) {
+ fp.flush();
+ Console::SetWindowsConsoleColor(fp, cct.m_Color);
+ }
+#endif /* _WIN32 */
+
+ return fp;
+}
+
+void Console::DetectType(void)
+{
+ l_ConsoleType = Console_Dumb;
+
+#ifndef _WIN32
+ if (isatty(1))
+ l_ConsoleType = Console_VT100;
+#else /* _WIN32 */
+ l_ConsoleType = Console_Windows;
+#endif /* _WIN32 */
+}
+
+void Console::SetType(std::ostream& fp, ConsoleType type)
+{
+ if (&fp == &std::cout || &fp == &std::cerr)
+ l_ConsoleType = type;
+}
+
+ConsoleType Console::GetType(std::ostream& fp)
+{
+ if (&fp == &std::cout || &fp == &std::cerr)
+ return l_ConsoleType;
+ else
+ return Console_Dumb;
+}
+
+#ifndef _WIN32
+void Console::PrintVT100ColorCode(std::ostream& fp, int color)
+{
+ if (color == Console_Normal) {
+ fp << "\33[0m";
+ return;
+ }
+
+ switch (color & 0xff) {
+ case Console_ForegroundBlack:
+ fp << "\33[30m";
+ break;
+ case Console_ForegroundRed:
+ fp << "\33[31m";
+ break;
+ case Console_ForegroundGreen:
+ fp << "\33[32m";
+ break;
+ case Console_ForegroundYellow:
+ fp << "\33[33m";
+ break;
+ case Console_ForegroundBlue:
+ fp << "\33[34m";
+ break;
+ case Console_ForegroundMagenta:
+ fp << "\33[35m";
+ break;
+ case Console_ForegroundCyan:
+ fp << "\33[36m";
+ break;
+ case Console_ForegroundWhite:
+ fp << "\33[37m";
+ break;
+ }
+
+ switch (color & 0xff00) {
+ case Console_BackgroundBlack:
+ fp << "\33[40m";
+ break;
+ case Console_BackgroundRed:
+ fp << "\33[41m";
+ break;
+ case Console_BackgroundGreen:
+ fp << "\33[42m";
+ break;
+ case Console_BackgroundYellow:
+ fp << "\33[43m";
+ break;
+ case Console_BackgroundBlue:
+ fp << "\33[44m";
+ break;
+ case Console_BackgroundMagenta:
+ fp << "\33[45m";
+ break;
+ case Console_BackgroundCyan:
+ fp << "\33[46m";
+ break;
+ case Console_BackgroundWhite:
+ fp << "\33[47m";
+ break;
+ }
+
+ if (color & Console_Bold)
+ fp << "\33[1m";
+}
+#else /* _WIN32 */
+void Console::SetWindowsConsoleColor(std::ostream& fp, int color)
+{
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+ HANDLE hConsole;
+
+ if (&fp == &std::cout)
+ hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+ else if (&fp == &std::cerr)
+ hConsole = GetStdHandle(STD_ERROR_HANDLE);
+ else
+ return;
+
+ if (!GetConsoleScreenBufferInfo(hConsole, &consoleInfo))
+ return;
+
+ WORD attrs = 0;
+
+ if (color == Console_Normal)
+ attrs = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+
+ switch (color & 0xff) {
+ case Console_ForegroundBlack:
+ attrs |= 0;
+ break;
+ case Console_ForegroundRed:
+ attrs |= FOREGROUND_RED;
+ break;
+ case Console_ForegroundGreen:
+ attrs |= FOREGROUND_GREEN;
+ break;
+ case Console_ForegroundYellow:
+ attrs |= FOREGROUND_RED | FOREGROUND_GREEN;
+ break;
+ case Console_ForegroundBlue:
+ attrs |= FOREGROUND_BLUE;
+ break;
+ case Console_ForegroundMagenta:
+ attrs |= FOREGROUND_RED | FOREGROUND_BLUE;
+ break;
+ case Console_ForegroundCyan:
+ attrs |= FOREGROUND_GREEN | FOREGROUND_BLUE;
+ break;
+ case Console_ForegroundWhite:
+ attrs |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+ break;
+ }
+
+ switch (color & 0xff00) {
+ case Console_BackgroundBlack:
+ attrs |= 0;
+ break;
+ case Console_BackgroundRed:
+ attrs |= BACKGROUND_RED;
+ break;
+ case Console_BackgroundGreen:
+ attrs |= BACKGROUND_GREEN;
+ break;
+ case Console_BackgroundYellow:
+ attrs |= BACKGROUND_RED | BACKGROUND_GREEN;
+ break;
+ case Console_BackgroundBlue:
+ attrs |= BACKGROUND_BLUE;
+ break;
+ case Console_BackgroundMagenta:
+ attrs |= BACKGROUND_RED | BACKGROUND_BLUE;
+ break;
+ case Console_BackgroundCyan:
+ attrs |= BACKGROUND_GREEN | BACKGROUND_BLUE;
+ break;
+ case Console_BackgroundWhite:
+ attrs |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
+ break;
+ }
+
+ if (color & Console_Bold)
+ attrs |= FOREGROUND_INTENSITY;
+
+ SetConsoleTextAttribute(hConsole, attrs);
+}
+#endif /* _WIN32 */
\ No newline at end of file
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#ifndef CONSOLE_H
+#define CONSOLE_H
+
+#include "base/i2-base.hpp"
+#include <ostream>
+
+namespace icinga
+{
+
+enum ConsoleColor
+{
+ Console_Normal,
+
+ // bit 0-7: foreground
+ Console_ForegroundBlack = 1,
+ Console_ForegroundRed = 2,
+ Console_ForegroundGreen = 3,
+ Console_ForegroundYellow = 4,
+ Console_ForegroundBlue = 5,
+ Console_ForegroundMagenta = 6,
+ Console_ForegroundCyan = 7,
+ Console_ForegroundWhite = 8,
+
+ // bit 8-15: background
+ Console_BackgroundBlack = 256,
+ Console_BackgroundRed = 266,
+ Console_BackgroundGreen = 267,
+ Console_BackgroundYellow = 268,
+ Console_BackgroundBlue = 269,
+ Console_BackgroundMagenta = 270,
+ Console_BackgroundCyan = 271,
+ Console_BackgroundWhite = 272,
+
+ // bit 16-23: flags
+ Console_Bold = 65536
+};
+
+enum ConsoleType
+{
+ Console_Dumb,
+#ifndef _WIN32
+ Console_VT100,
+#else /* _WIN32 */
+ Console_Windows,
+#endif /* _WIN32 */
+};
+
+class I2_BASE_API ConsoleColorTag
+{
+public:
+ ConsoleColorTag(int color);
+
+ friend I2_BASE_API std::ostream& operator<<(std::ostream& fp, const ConsoleColorTag& cct);
+
+private:
+ int m_Color;
+};
+
+/**
+ * Console utilities.
+ *
+ * @ingroup base
+ */
+class I2_BASE_API Console
+{
+public:
+ static void DetectType(void);
+
+ static void SetType(std::ostream& fp, ConsoleType type);
+ static ConsoleType GetType(std::ostream& fp);
+
+#ifndef _WIN32
+ static void PrintVT100ColorCode(std::ostream& fp, int color);
+#else /* _WIN32 */
+ static void SetWindowsConsoleColor(std::ostream& fp, int color);
+#endif /* _WIN32 */
+
+private:
+ Console(void);
+};
+
+}
+
+#endif /* CONSOLE_H */
logger->ProcessLogEntry(entry);
}
- if (Logger::IsConsoleLogEnabled() && entry.Severity >= Logger::GetConsoleLogSeverity()) {
- static bool tty = StreamLogger::IsTty(std::cout);
-
- StreamLogger::ProcessLogEntry(std::cout, tty, entry);
- }
+ if (Logger::IsConsoleLogEnabled() && entry.Severity >= Logger::GetConsoleLogSeverity())
+ StreamLogger::ProcessLogEntry(std::cout, entry);
}
/**
#include "base/streamlogger.hpp"
#include "base/utility.hpp"
#include "base/objectlock.hpp"
+#include "base/console.hpp"
#include <iostream>
using namespace icinga;
m_Stream = stream;
m_OwnsStream = ownsStream;
- m_Tty = IsTty(*stream);
m_FlushLogTimer = make_shared<Timer>();
m_FlushLogTimer->SetInterval(1);
* Processes a log entry and outputs it to a stream.
*
* @param stream The output stream.
- * @param tty Whether the output stream is a TTY.
* @param entry The log entry.
*/
-void StreamLogger::ProcessLogEntry(std::ostream& stream, bool tty, const LogEntry& entry)
+void StreamLogger::ProcessLogEntry(std::ostream& stream, const LogEntry& entry)
{
String timestamp = Utility::FormatDateTime("%Y-%m-%d %H:%M:%S %z", entry.Timestamp);
stream << "[" << timestamp << "] ";
- if (tty) {
- switch (entry.Severity) {
- case LogNotice:
- stream << "\x1b[1;34m"; // blue
- break;
- case LogInformation:
- stream << "\x1b[1;32m"; // green
- break;
- case LogWarning:
- stream << "\x1b[1;33m"; // yellow;
- break;
- case LogCritical:
- stream << "\x1b[1;31m"; // red
- break;
- default:
- break;
- }
+ ConsoleColor color;
+
+ switch (entry.Severity) {
+ case LogNotice:
+ color = Console_ForegroundBlue;
+ break;
+ case LogInformation:
+ color = Console_ForegroundGreen;
+ break;
+ case LogWarning:
+ color = Console_ForegroundYellow;
+ break;
+ case LogCritical:
+ color = Console_ForegroundRed;
+ break;
+ default:
+ return;
}
- try {
- stream << Logger::SeverityToString(entry.Severity);
- } catch (const std::exception&) {
- /* bail early */
- return;
- }
-
- if (tty)
- stream << "\x1b[0m"; // clear colors
-
+ stream << ConsoleColorTag(color);
+ stream << Logger::SeverityToString(entry.Severity);
+ stream << ConsoleColorTag(Console_Normal);
stream << "/" << entry.Facility << ": " << entry.Message << "\n";
}
*/
void StreamLogger::ProcessLogEntry(const LogEntry& entry)
{
- ProcessLogEntry(*m_Stream, m_Tty, entry);
+ ProcessLogEntry(*m_Stream, entry);
}
-/**
- * Checks whether the specified stream is a terminal.
- *
- * @param stream The stream.
- * @returns true if the stream is a terminal, false otherwise.
- */
-bool StreamLogger::IsTty(std::ostream& stream)
-{
-#ifndef _WIN32
- /* Eww... */
- if (&stream == &std::cout)
- return isatty(fileno(stdout));
-
- if (&stream == &std::cerr)
- return isatty(fileno(stderr));
-#endif /*_ WIN32 */
-
- return false;
-}
void BindStream(std::ostream *stream, bool ownsStream);
- static void ProcessLogEntry(std::ostream& stream, bool tty, const LogEntry& entry);
- static bool IsTty(std::ostream& stream);
+ static void ProcessLogEntry(std::ostream& stream, const LogEntry& entry);
protected:
virtual void ProcessLogEntry(const LogEntry& entry);
#include "base/stdiostream.hpp"
#include "base/debug.hpp"
#include "base/objectlock.hpp"
+#include "base/console.hpp"
#include <boost/foreach.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp>
else
fp << "Object '";
- fp << "\x1b[1;34m" << internal_name << "\x1b[0m" << "'"; //blue
- fp << " of type '" << "\x1b[1;34m" << type << "\x1b[0m" << "':\n"; //blue
+ fp << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << internal_name << ConsoleColorTag(Console_Normal) << "'";
+ fp << " of type '" << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << type << ConsoleColorTag(Console_Normal) << "':\n";
PrintProperties(fp, properties, debug_hints, 2);
Value val = kv.second;
/* key & value */
- fp << std::setw(indent) << " " << "* " << "\x1b[1;32m" << key << "\x1b[0m"; //green
+ fp << std::setw(indent) << " " << "* " << ConsoleColorTag(Console_ForegroundGreen) << key << ConsoleColorTag(Console_Normal);
/* extract debug hints for key */
Dictionary::Ptr debug_hints_fwd;
void ObjectListCommand::PrintHint(std::ostream& fp, const Array::Ptr& msg, int indent)
{
- fp << std::setw(indent) << " " << "\x1b[1;36m" "% " << msg->Get(0) << " modified in '" << msg->Get(1) << "', lines "
- << msg->Get(2) << ":" << msg->Get(3) << "-" << msg->Get(4) << ":" << msg->Get(5) << "\x1b[0m" "\n"; //cyan
+ fp << std::setw(indent) << " " << ConsoleColorTag(Console_ForegroundCyan) << "% " << msg->Get(0) << " modified in '" << msg->Get(1) << "', lines "
+ << msg->Get(2) << ":" << msg->Get(3) << "-" << msg->Get(4) << ":" << msg->Get(5) << ConsoleColorTag(Console_Normal) << "\n";
}
void ObjectListCommand::PrintTypeCounts(std::ostream& fp, const std::map<String, int>& type_count)
persistentItem->Set("type", item->GetType());
persistentItem->Set("name", item->GetName());
persistentItem->Set("abstract", item->IsAbstract());
- persistentItem->Set("properties", item->GetProperties());
+ {
+ ObjectLock olock(item);
+ persistentItem->Set("properties", item->GetProperties());
+ }
persistentItem->Set("debug_hints", item->GetDebugHints());
String json = JsonSerialize(persistentItem);