aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/logging/plain_text_formatter/formatter.cpp
diff options
context:
space:
mode:
authormax42 <max42@yandex-team.com>2023-07-29 00:02:16 +0300
committermax42 <max42@yandex-team.com>2023-07-29 00:02:16 +0300
commit73b89de71748a21e102d27b9f3ed1bf658766cb5 (patch)
tree188bbd2d622fa91cdcbb1b6d6d77fbc84a0646f5 /library/cpp/yt/logging/plain_text_formatter/formatter.cpp
parent528e321bcc2a2b67b53aeba58c3bd88305a141ee (diff)
downloadydb-73b89de71748a21e102d27b9f3ed1bf658766cb5.tar.gz
YT-19210: expose YQL shared library for YT.
After this, a new target libyqlplugin.so appears. in open-source cmake build. Diff in open-source YDB repo looks like the following: https://paste.yandex-team.ru/f302bdb4-7ef2-4362-91c7-6ca45f329264
Diffstat (limited to 'library/cpp/yt/logging/plain_text_formatter/formatter.cpp')
-rw-r--r--library/cpp/yt/logging/plain_text_formatter/formatter.cpp226
1 files changed, 226 insertions, 0 deletions
diff --git a/library/cpp/yt/logging/plain_text_formatter/formatter.cpp b/library/cpp/yt/logging/plain_text_formatter/formatter.cpp
new file mode 100644
index 0000000000..ab2181113d
--- /dev/null
+++ b/library/cpp/yt/logging/plain_text_formatter/formatter.cpp
@@ -0,0 +1,226 @@
+#include "formatter.h"
+
+#include <library/cpp/yt/cpu_clock/clock.h>
+
+#include <library/cpp/yt/misc/port.h>
+
+#ifdef YT_USE_SSE42
+ #include <emmintrin.h>
+ #include <pmmintrin.h>
+#endif
+
+namespace NYT::NLogging {
+
+constexpr int MessageBufferWatermarkSize = 256;
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+// Ultra-fast specialized versions of AppendNumber.
+void AppendDigit(TBaseFormatter* out, ui32 value)
+{
+ out->AppendChar('0' + value);
+}
+
+void AppendNumber2(TBaseFormatter* out, ui32 value)
+{
+ AppendDigit(out, value / 10);
+ AppendDigit(out, value % 10);
+}
+
+void AppendNumber3(TBaseFormatter* out, ui32 value)
+{
+ AppendDigit(out, value / 100);
+ AppendDigit(out, (value / 10) % 10);
+ AppendDigit(out, value % 10);
+}
+
+void AppendNumber4(TBaseFormatter* out, ui32 value)
+{
+ AppendDigit(out, value / 1000);
+ AppendDigit(out, (value / 100) % 10);
+ AppendDigit(out, (value / 10) % 10);
+ AppendDigit(out, value % 10);
+}
+
+void AppendNumber6(TBaseFormatter* out, ui32 value)
+{
+ AppendDigit(out, value / 100000);
+ AppendDigit(out, (value / 10000) % 10);
+ AppendDigit(out, (value / 1000) % 10);
+ AppendDigit(out, (value / 100) % 10);
+ AppendDigit(out, (value / 10) % 10);
+ AppendDigit(out, value % 10);
+}
+
+} // namespace
+
+void FormatDateTime(TBaseFormatter* out, TInstant dateTime)
+{
+ tm localTime;
+ dateTime.LocalTime(&localTime);
+ AppendNumber4(out, localTime.tm_year + 1900);
+ out->AppendChar('-');
+ AppendNumber2(out, localTime.tm_mon + 1);
+ out->AppendChar('-');
+ AppendNumber2(out, localTime.tm_mday);
+ out->AppendChar(' ');
+ AppendNumber2(out, localTime.tm_hour);
+ out->AppendChar(':');
+ AppendNumber2(out, localTime.tm_min);
+ out->AppendChar(':');
+ AppendNumber2(out, localTime.tm_sec);
+}
+
+void FormatMilliseconds(TBaseFormatter* out, TInstant dateTime)
+{
+ AppendNumber3(out, dateTime.MilliSecondsOfSecond());
+}
+
+void FormatMicroseconds(TBaseFormatter* out, TInstant dateTime)
+{
+ AppendNumber6(out, dateTime.MicroSecondsOfSecond());
+}
+
+void FormatLevel(TBaseFormatter* out, ELogLevel level)
+{
+ static char chars[] = "?TDIWEAF?";
+ out->AppendChar(chars[static_cast<int>(level)]);
+}
+
+void FormatMessage(TBaseFormatter* out, TStringBuf message)
+{
+ auto current = message.begin();
+
+#ifdef YT_USE_SSE42
+ auto vectorLow = _mm_set1_epi8(PrintableASCIILow);
+ auto vectorHigh = _mm_set1_epi8(PrintableASCIIHigh);
+#endif
+
+ auto appendChar = [&] {
+ char ch = *current;
+ if (ch == '\n') {
+ out->AppendString("\\n");
+ } else if (ch == '\t') {
+ out->AppendString("\\t");
+ } else if (ch < PrintableASCIILow || ch > PrintableASCIIHigh) {
+ unsigned char unsignedCh = ch;
+ out->AppendString("\\x");
+ out->AppendChar(IntToHexLowercase[unsignedCh >> 4]);
+ out->AppendChar(IntToHexLowercase[unsignedCh & 15]);
+ } else {
+ out->AppendChar(ch);
+ }
+ ++current;
+ };
+
+ while (current < message.end()) {
+ if (out->GetBytesRemaining() < MessageBufferWatermarkSize) {
+ out->AppendString(TStringBuf("...<message truncated>"));
+ break;
+ }
+#ifdef YT_USE_SSE42
+ // Use SSE for optimization.
+ if (current + 16 > message.end()) {
+ appendChar();
+ } else {
+ const void* inPtr = &(*current);
+ void* outPtr = out->GetCursor();
+ auto value = _mm_lddqu_si128(static_cast<const __m128i*>(inPtr));
+ if (_mm_movemask_epi8(_mm_cmplt_epi8(value, vectorLow)) ||
+ _mm_movemask_epi8(_mm_cmpgt_epi8(value, vectorHigh))) {
+ for (int index = 0; index < 16; ++index) {
+ appendChar();
+ }
+ } else {
+ _mm_storeu_si128(static_cast<__m128i*>(outPtr), value);
+ out->Advance(16);
+ current += 16;
+ }
+ }
+#else
+ // Unoptimized version.
+ appendChar();
+#endif
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TCachingDateFormatter::Format(TBaseFormatter* buffer, TInstant dateTime, bool printMicroseconds)
+{
+ auto currentSecond = dateTime.Seconds();
+ if (CachedSecond_ != currentSecond) {
+ Cached_.Reset();
+ FormatDateTime(&Cached_, dateTime);
+ CachedSecond_ = currentSecond;
+ }
+
+ buffer->AppendString(Cached_.GetBuffer());
+ buffer->AppendChar(',');
+ if (printMicroseconds) {
+ FormatMicroseconds(buffer, dateTime);
+ } else {
+ FormatMilliseconds(buffer, dateTime);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TPlainTextEventFormatter::TPlainTextEventFormatter(bool enableSourceLocation)
+ : EnableSourceLocation_(enableSourceLocation)
+{ }
+
+void TPlainTextEventFormatter::Format(TBaseFormatter* buffer, const TLogEvent& event)
+{
+ CachingDateFormatter_.Format(buffer, CpuInstantToInstant(event.Instant), true);
+
+ buffer->AppendChar('\t');
+
+ FormatLevel(buffer, event.Level);
+
+ buffer->AppendChar('\t');
+
+ buffer->AppendString(event.Category->Name);
+
+ buffer->AppendChar('\t');
+
+ FormatMessage(buffer, event.MessageRef.ToStringBuf());
+
+ buffer->AppendChar('\t');
+
+ if (event.ThreadName.Length > 0) {
+ buffer->AppendString(TStringBuf(event.ThreadName.Buffer.data(), event.ThreadName.Length));
+ } else if (event.ThreadId != TThreadId()) {
+ buffer->AppendNumber(event.ThreadId, 16);
+ }
+
+ buffer->AppendChar('\t');
+
+ if (event.FiberId != TFiberId()) {
+ buffer->AppendNumber(event.FiberId, 16);
+ }
+
+ buffer->AppendChar('\t');
+
+ if (event.TraceId != TTraceId()) {
+ buffer->AppendGuid(event.TraceId);
+ }
+
+ if (EnableSourceLocation_) {
+ buffer->AppendChar('\t');
+ if (event.SourceFile) {
+ auto sourceFile = event.SourceFile;
+ buffer->AppendString(sourceFile.RNextTok(LOCSLASH_C));
+ buffer->AppendChar(':');
+ buffer->AppendNumber(event.SourceLine);
+ }
+ }
+
+ buffer->AppendChar('\n');
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NLogging