ClickHouse/libs/libdaemon/include/daemon/OwnPatternFormatter.h
Pavel Kartavyy b61bd0b96b Merge commit '84e4fb00bd0373058bfc091d2d19a8034df7cc93' into update-clickhouse
Conflicts:
	metrica/src/ClickHouse/libs/libdaemon/src/BaseDaemon.cpp
2017-02-06 17:57:47 +03:00

81 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <Poco/PatternFormatter.h>
#include <Poco/Ext/ThreadNumber.h>
#include <DB/IO/WriteBufferFromString.h>
#include <DB/IO/WriteHelpers.h>
#include <daemon/BaseDaemon.h>
/** Форматирует по своему.
* Некоторые детали невозможно получить, используя только Poco::PatternFormatter.
*
* Во-первых, используется номер потока не среди потоков Poco::Thread,
* а среди всех потоков, для которых был получен номер (см. ThreadNumber.h)
*
* Во-вторых, корректно выводится локальная дата и время.
* Poco::PatternFormatter плохо работает с локальным временем,
* в ситуациях, когда в ближайшем будущем намечается отмена или введение daylight saving time.
* - см. исходники Poco и http://thread.gmane.org/gmane.comp.time.tz/8883
*
* Также сделан чуть более эффективным (что имеет мало значения).
*/
class OwnPatternFormatter : public Poco::PatternFormatter
{
public:
enum Options
{
ADD_NOTHING = 0,
ADD_LAYER_TAG = 1 << 0
};
OwnPatternFormatter(const BaseDaemon & daemon_, Options options_ = ADD_NOTHING) : Poco::PatternFormatter(""), daemon(daemon_), options(options_) {}
void format(const Message & msg, std::string & text) override
{
DB::WriteBufferFromString wb(text);
/// For syslog: tag must be before message and first whitespace.
if (options & ADD_LAYER_TAG)
{
auto layer = daemon.getLayer();
if (layer)
{
writeCString("layer[", wb);
DB::writeIntText(*layer, wb);
writeCString("]: ", wb);
}
}
/// Output time with microsecond resolution.
timeval tv;
if (0 != gettimeofday(&tv, nullptr))
DB::throwFromErrno("Cannot gettimeofday");
/// Change delimiters in date for compatibility with old logs.
DB::writeDateTimeText<'.', ':'>(tv.tv_sec, wb);
DB::writeChar('.', wb);
DB::writeChar('0' + ((tv.tv_usec / 100000) % 10), wb);
DB::writeChar('0' + ((tv.tv_usec / 10000) % 10), wb);
DB::writeChar('0' + ((tv.tv_usec / 1000) % 10), wb);
DB::writeChar('0' + ((tv.tv_usec / 100) % 10), wb);
DB::writeChar('0' + ((tv.tv_usec / 10) % 10), wb);
DB::writeChar('0' + ((tv.tv_usec / 1) % 10), wb);
writeCString(" [ ", wb);
DB::writeIntText(Poco::ThreadNumber::get(), wb);
writeCString(" ] <", wb);
DB::writeString(getPriorityName(static_cast<int>(msg.getPriority())), wb);
writeCString("> ", wb);
DB::writeString(msg.getSource(), wb);
writeCString(": ", wb);
DB::writeString(msg.getText(), wb);
}
private:
const BaseDaemon & daemon;
Options options;
};