[Libreoffice-commits] online.git: common/Log.cpp common/Log.hpp
Ashod Nakashian (via logerrit)
logerrit at kemper.freedesktop.org
Thu May 21 22:40:59 UTC 2020
common/Log.cpp | 155 +++++++++++++++++++++++++++++++++++++++++++++++++--------
common/Log.hpp | 20 ++++---
2 files changed, 148 insertions(+), 27 deletions(-)
New commits:
commit 287b70a50408d260f3c6c0d5306c081a40eea280
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Sat Apr 25 13:03:32 2020 -0400
Commit: Ashod Nakashian <ashnakash at gmail.com>
CommitDate: Fri May 22 00:40:37 2020 +0200
wsd: logging cleanup and improvements
We now don't need to call snprintf (which is best
for signal-safetly), and are much faster thanks
to a custom replacement.
Change-Id: Iae5861e42e8e335967499f93b71b39b0b4b09bf6
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/94146
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Tested-by: Jenkins
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/common/Log.cpp b/common/Log.cpp
index f9d0b5578..6cb376c9e 100644
--- a/common/Log.cpp
+++ b/common/Log.cpp
@@ -70,7 +70,7 @@ namespace Log
const std::string& getName() const { return _name; }
void setLogger(Poco::Logger* logger) { _logger = logger; };
- Poco::Logger* getLogger() { return _logger; }
+ Poco::Logger* getLogger() const { return _logger; }
};
static StaticNameHelper Source;
bool IsShutdown = false;
@@ -112,38 +112,153 @@ namespace Log
signalLog(buf + i + 1);
}
- char* prefix(char* buffer, const std::size_t len, const char* level)
+ /// Convert an unsigned number to ascii with 0 padding.
+ template <int Width> void to_ascii_fixed(char* buf, size_t num)
{
- const char *threadName = Util::getThreadName();
- Poco::DateTime time;
+ buf[Width - 1] = '0' + num % 10; // Units.
+
+ if (Width > 1)
+ {
+ num /= 10;
+ buf[Width - 2] = '0' + num % 10; // Tens.
+ }
+
+ if (Width > 2)
+ {
+ num /= 10;
+ buf[Width - 3] = '0' + num % 10; // Hundreds.
+ }
+
+ if (Width > 3)
+ {
+ num /= 10;
+ buf[Width - 4] = '0' + num % 10; // Thousands.
+ }
+
+ if (Width > 4)
+ {
+ num /= 10;
+ buf[Width - 5] = '0' + num % 10; // Ten-Thousands.
+ }
+
+ if (Width > 5)
+ {
+ num /= 10;
+ buf[Width - 6] = '0' + num % 10; // Hundred-Thousands.
+ }
+
+ static_assert(Width >= 1 && Width <= 6, "Width is invalid.");
+ }
+
+ /// Copy a null-terminated string into another.
+ /// Expects the destination to be large enough.
+ /// Note: unlike strcpy, this returns the *new* out
+ /// (destination) pointer, which saves a strlen call.
+ char* strcopy(const char* in, char* out)
+ {
+ while (*in)
+ *out++ = *in++;
+ return out;
+ }
+
+ /// Convert unsigned long num to base-10 ascii in place.
+ /// Returns the *end* position.
+ char* to_ascii(char* buf, size_t num)
+ {
+ int i = 0;
+ do
+ {
+ buf[i++] = '0' + num % 10;
+ num /= 10;
+ } while (num > 0);
+
+ // Reverse.
+ for (char *front = buf, *back = buf + i - 1; back > front; ++front, --back)
+ {
+ const char t = *front;
+ *front = *back;
+ *back = t;
+ }
+
+ return buf + i;
+ }
+
+ char* prefix(const Poco::DateTime& time, char* buffer, const char* level)
+ {
+ // Note that snprintf is deemed signal-safe in most common implementations.
+ char* pos = strcopy((Source.getInited() ? Source.getId().c_str() : "<shutdown>"), buffer);
+ *pos++ = '-';
+
+ // Thread ID.
#ifdef __linux
const long osTid = Util::getThreadId();
- // Note that snprintf is deemed signal-safe in most common implementations.
- snprintf(buffer, len, "%s-%.05lu %.4u-%.2u-%.2u %.2u:%.2u:%.2u.%.6u [ %s ] %s ",
- (Source.getInited() ? Source.getId().c_str() : "<shutdown>"),
- osTid,
- time.year(), time.month(), time.day(),
- time.hour(), time.minute(), time.second(),
- time.millisecond() * 1000 + time.microsecond(),
- threadName, level);
+ if (osTid > 99999)
+ {
+ if (osTid > 999999)
+ pos = to_ascii(pos, osTid);
+ else
+ {
+ to_ascii_fixed<6>(pos, osTid);
+ pos += 6;
+ }
+ }
+ else
+ {
+ to_ascii_fixed<5>(pos, osTid);
+ pos += 5;
+ }
#elif defined IOS
uint64_t osTid;
pthread_threadid_np(nullptr, &osTid);
- snprintf(buffer, len, "%s-%#.05llx %.4u-%.2u-%.2u %.2u:%.2u:%.2u.%.6u [ %s ] %s ",
- (Source.getInited() ? Source.getId().c_str() : "<shutdown>"),
- osTid,
- time.year(), time.month(), time.day(),
- time.hour(), time.minute(), time.second(),
- time.millisecond() * 1000 + time.microsecond(),
- threadName, level);
+ snprintf(pos, 32, "%#.05llx", osTid);
+ while (*pos++); // Skip to end.
#endif
+
+ // YYYY-MM-DD.
+ *pos++ = ' ';
+ to_ascii_fixed<4>(pos, time.year());
+ pos[4] = '-';
+ pos += 5;
+ to_ascii_fixed<2>(pos, time.month());
+ pos[2] = '-';
+ pos += 3;
+ to_ascii_fixed<2>(pos, time.day());
+ pos[2] = ' ';
+ pos += 3;
+
+ // HH:MM:SS.uS
+ to_ascii_fixed<2>(pos, time.hour());
+ pos[2] = ':';
+ pos += 3;
+ to_ascii_fixed<2>(pos, time.minute());
+ pos[2] = ':';
+ pos += 3;
+ to_ascii_fixed<2>(pos, time.second());
+ pos[2] = '.';
+ pos += 3;
+ to_ascii_fixed<6>(pos, time.millisecond() * 1000 + time.microsecond());
+ pos[6] = ' ';
+ pos[7] = '[';
+ pos[8] = ' ';
+ pos += 9;
+
+ pos = strcopy(Util::getThreadName(), pos);
+ pos[0] = ' ';
+ pos[1] = ']';
+ pos[2] = ' ';
+ pos += 3;
+ pos = strcopy(level, pos);
+ pos[0] = ' ';
+ pos[1] = ' ';
+ pos[2] = '\0';
+
return buffer;
}
void signalLogPrefix()
{
char buffer[1024];
- prefix(buffer, sizeof(buffer) - 1, "SIG");
+ prefix<sizeof(buffer) - 1>(buffer, "SIG");
signalLog(buffer);
}
diff --git a/common/Log.hpp b/common/Log.hpp
index bc96035e9..604c66ac7 100644
--- a/common/Log.hpp
+++ b/common/Log.hpp
@@ -67,7 +67,15 @@ namespace Log
constexpr bool isShutdownCalled() { return false; }
#endif
- char* prefix(char* buffer, std::size_t len, const char* level);
+ /// Generates log entry prefix. Example follows (without the pipes).
+ /// |wsd-07272-07298 2020-04-25 17:29:28.928697 [ websrv_poll ] TRC |
+ /// This is fully signal-safe. Buffer must be at least 128 bytes.
+ char* prefix(const Poco::DateTime& time, char* buffer, const char* level);
+ template <int Size> inline char* prefix(char buffer[Size], const char* level)
+ {
+ static_assert(Size >= 128, "Buffer size must be at least 128 bytes.");
+ return prefix(Poco::DateTime(), buffer, level);
+ }
inline bool traceEnabled() { return logger().trace(); }
inline bool debugEnabled() { return logger().debug(); }
@@ -109,7 +117,7 @@ namespace Log
_enabled(true)
{
char buffer[1024];
- _stream << prefix(buffer, sizeof(buffer) - 1, level);
+ _stream << prefix<sizeof(buffer) - 1>(buffer, level);
}
StreamLogger(StreamLogger&& sl) noexcept
@@ -274,7 +282,7 @@ namespace Log
#define LOG_BODY_(LOG, PRIO, LVL, X, FILEP) \
char b_[1024]; \
- std::ostringstream oss_(Log::prefix(b_, sizeof(b_) - 1, LVL), std::ostringstream::ate); \
+ std::ostringstream oss_(Log::prefix<sizeof(b_) - 1>(b_, LVL), std::ostringstream::ate); \
oss_ << std::boolalpha << X; \
LOG_END(oss_, FILEP); \
((void)__android_log_print(ANDROID_LOG_DEBUG, "loolwsd", "%s %s", LVL, oss_.str().c_str()))
@@ -282,13 +290,11 @@ namespace Log
#else
#define LOG_BODY_(LOG, PRIO, LVL, X, FILEP) \
- Poco::Message m_(LOG.name(), "", Poco::Message::PRIO_##PRIO); \
char b_[1024]; \
- std::ostringstream oss_(Log::prefix(b_, sizeof(b_) - 1, LVL), std::ostringstream::ate); \
+ std::ostringstream oss_(Log::prefix<sizeof(b_) - 1>(b_, LVL), std::ostringstream::ate); \
oss_ << std::boolalpha << X; \
LOG_END(oss_, FILEP); \
- m_.setText(oss_.str()); \
- LOG.log(m_);
+ LOG.log(Poco::Message(LOG.name(), oss_.str(), Poco::Message::PRIO_##PRIO));
#endif
More information about the Libreoffice-commits
mailing list