sled/src/log/log.cc
2024-02-28 15:43:32 +08:00

72 lines
1.7 KiB
C++

#include "sled/log/log.h"
#include "sled/time_utils.h"
#include <atomic>
#include <ctime>
#include <fmt/format.h>
#include <iostream>
namespace sled {
class ScopedAtomicWaiter {
public:
ScopedAtomicWaiter(std::atomic_bool &flag) : flag_(flag)
{
bool old = flag_.load();
while (!flag_.compare_exchange_weak(old, false)) { continue; }
}
~ScopedAtomicWaiter() { flag_.store(true); }
private:
std::atomic_bool &flag_;
};
static std::string
GetCurrentUTCTime()
{
#if true
// struct timespec tp;
// clock_gettime(CLOCK_REALTIME, &tp);
// int64_t now = tp.tv_sec * kNumNanosecsPerSec + tp.tv_nsec;
// std::time_t t = tp.tv_sec;
const int64_t now = TimeUTCNanos();
std::time_t t = now / kNumNanosecsPerSec;
#else
std::time_t t = std::time(nullptr);
#endif
std::tm tm = *std::gmtime(&t);
char buf[64];
std::strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tm);
std::string result(buf);
#if true
return result
+ fmt::format(".{:03d}Z",
static_cast<int>(now % kNumNanosecsPerSec)
/ kNumNanosecsPerMillisec);
#else
return result + "Z";
#endif
return result;
}
void
Log(LogLevel level,
const char *tag,
const char *fmt,
const char *file_name,
int line,
const char *func_name,
...)
{
static std::atomic_bool allow(true);
ScopedAtomicWaiter waiter(allow);
int len = file_name ? strlen(file_name) : 0;
while (len > 0 && file_name[len - 1] != '/') { len--; }
auto msg = fmt::format("{} {}:{}@{} {} {}", GetCurrentUTCTime(),
file_name + len, line, func_name, tag, fmt);
std::cout << msg << std::endl;
}
}// namespace sled