From 800dbaba99a81e250a6a1cd17c22ceaace2c1bd4 Mon Sep 17 00:00:00 2001
From: Olivier Dion <olivier.dion@savoirfairelinux.com>
Date: Mon, 1 Nov 2021 21:05:24 -0400
Subject: [PATCH] logger: Add custom timestamp format

Using JAMI_TIMESTAMP_FMT, developers can now format the log's timestamp
according to their needs and taste.  The formatting is the same as strftime(3).

Change-Id: Ibea56852b2efc37f66aeeeda857e307130099720
---
 src/logger.cpp | 58 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 45 insertions(+), 13 deletions(-)

diff --git a/src/logger.cpp b/src/logger.cpp
index 5799f9734d..f3bc407830 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -103,28 +103,60 @@ stripDirName(const char* path)
 static std::string
 contextHeader(const char* const file, int line)
 {
+    static char* timestamp_fmt = getenv("JAMI_TIMESTAMP_FMT");
+
 #ifdef __linux__
     auto tid = syscall(__NR_gettid) & 0xffff;
 #else
     auto tid = std::this_thread::get_id();
 #endif // __linux__
+
+    std::ostringstream out;
+
+    out << '[';
+
     // Timestamp
-    unsigned int secs, milli;
-    struct timeval tv;
+    if (timestamp_fmt) {
+
+        time_t t;
+        struct tm tm;
+        char buf[128];
+
+        time(&t);
+
+#ifdef _WIN32
+        /* NOTE!  localtime(3) is MT-Safe on win32 */
+        tm = *localtime(&t);
+#else
+        localtime_r(&t, &tm);
+#endif
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+        strftime(buf, sizeof(buf), timestamp_fmt, &tm);
+#pragma GCC diagnostic pop
+
+        out << buf;
 
-    if (!gettimeofday(&tv, NULL)) {
-        secs = tv.tv_sec;
-        milli = tv.tv_usec / 1000; // suppose that milli < 1000
     } else {
-        secs = time(NULL);
-        milli = 0;
-    }
 
-    std::ostringstream out;
-    const auto prev_fill = out.fill();
-    out << '[' << secs << '.' << std::right << std::setw(3) << std::setfill('0') << milli
-        << std::left << '|' << std::right << std::setw(5) << std::setfill(' ') << tid << std::left;
-    out.fill(prev_fill);
+        unsigned int secs, milli;
+        struct timeval tv;
+
+        if (!gettimeofday(&tv, NULL)) {
+            secs = tv.tv_sec;
+            milli = tv.tv_usec / 1000; // suppose that milli < 1000
+        } else {
+            secs = time(NULL);
+            milli = 0;
+        }
+
+        const auto prev_fill = out.fill();
+
+        out << secs << '.' << std::right << std::setw(3) << std::setfill('0') << milli
+            << std::left << '|' << std::right << std::setw(5) << std::setfill(' ') << tid << std::left;
+        out.fill(prev_fill);
+    }
 
     // Context
     if (file) {
-- 
GitLab