diff --git a/CMakeLists.txt b/CMakeLists.txt index e6d0776..031542f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ target_sources( src/synchronization/mutex.cc src/synchronization/sequence_checker_internal.cc src/synchronization/thread_local.cc + src/system/location.cc src/system/thread.cc src/task_queue/pending_task_safety_flag.cc src/task_queue/task_queue_base.cc diff --git a/include/sled/log/log.h b/include/sled/log/log.h index f31641c..46efac1 100644 --- a/include/sled/log/log.h +++ b/include/sled/log/log.h @@ -6,6 +6,7 @@ #ifndef LOG_H #define LOG_H +#include "sled/system/location.h" #include namespace sled { @@ -32,8 +33,16 @@ void Log(LogLevel level, // sled::Log(level, tag, fmt, __FILE__, __FUNCTION__, __VA_ARGS__) #define _SLOG(level, tag, fmt_str, ...) \ - sled::Log(level, tag, fmt::format(fmt_str, ##__VA_ARGS__).c_str(), \ - __FILE__, __LINE__, __FUNCTION__) + do { \ + std::string __fmt_str; \ + try { \ + __fmt_str = fmt::format(fmt_str, ##__VA_ARGS__); \ + } catch (const std::exception &e) { \ + __fmt_str = " fmt error: " + std::string(e.what()); \ + } \ + sled::Log(level, tag, __fmt_str.c_str(), __FILE__, __LINE__, \ + __FUNCTION__); \ + } while (0) #define SLOG(level, tag, fmt, ...) _SLOG(level, tag, fmt, ##__VA_ARGS__) #define SLOG_TRACE(tag, fmt, ...) \ diff --git a/include/sled/reflect/reflect.h b/include/sled/reflect/reflect.h new file mode 100644 index 0000000..b11f23e --- /dev/null +++ b/include/sled/reflect/reflect.h @@ -0,0 +1,24 @@ +/** + * @file : reflect + * @created : ζ˜ŸζœŸδΈ€ 2 26, 2024 09:55:19 CST + * @license : MIT + **/ + +#ifndef SLED_REFLECT_REFLECT_H +#define SLED_REFLECT_REFLECT_H + +#if !defined(__NO_META_PARSER__) && !defined(__META_PARSER__) +#define __META_PARSER__ +#endif + +#if defined(__META_PARSER__) +#define REFLECT_CLASS __attribute__((annotate("reflect-class"))) +#define PROPERTY() __attribute__((annotate("reflect-property"))) +#define METHOD() __attribute__((annotate("reflect-method"))) +#else +#define REFLECT_CLASS +#define PROPERTY() +#define METHOD() +#endif + +#endif// SLED_REFLECT_REFLECT_H diff --git a/include/sled/system/location.h b/include/sled/system/location.h index 96dafc4..ca2360c 100644 --- a/include/sled/system/location.h +++ b/include/sled/system/location.h @@ -7,13 +7,30 @@ #ifndef LOCATION_H #define LOCATION_H +#include + namespace sled { -class Location { +class Location final { public: - static Location Current() { return Location(); } + Location() = delete; + + static Location Current(const char *file_name = __builtin_FILE(), + int file_line = __builtin_LINE(), + const char *function = __builtin_FUNCTION()); + + std::string ToString() const; + +private: + Location(const char *file_name, int file_line, const char *function); + + const char *file_name; + int file_line; + const char *function; }; }// namespace sled +#define SLED_FROM_HERE sled::Location::Current(); + #endif// LOCATION_H diff --git a/include/sled/time_utils.h b/include/sled/time_utils.h index 3e56107..4378291 100644 --- a/include/sled/time_utils.h +++ b/include/sled/time_utils.h @@ -13,9 +13,12 @@ namespace sled { static const int64_t kNumMillisecsPerSec = 1000; static const int64_t kNumMicrosecsPerSec = 1000000; static const int64_t kNumNanosecsPerSec = 1000000000; -static const int64_t kNumMicrosecsPerMillisec = kNumMicrosecsPerSec / kNumMillisecsPerSec; -static const int64_t kNumNanosecsPerMillisec = kNumNanosecsPerSec / kNumMillisecsPerSec; -static const int64_t kNumNanosecsPerMicrosec = kNumNanosecsPerSec / kNumMicrosecsPerSec; +static const int64_t kNumMicrosecsPerMillisec = + kNumMicrosecsPerSec / kNumMillisecsPerSec; +static const int64_t kNumNanosecsPerMillisec = + kNumNanosecsPerSec / kNumMillisecsPerSec; +static const int64_t kNumNanosecsPerMicrosec = + kNumNanosecsPerSec / kNumMicrosecsPerSec; constexpr int64_t kNtpJan1970Millisecs = 2208988800 * kNumMillisecsPerSec; class ClockInterface { diff --git a/src/log/log.cc b/src/log/log.cc index f050167..c9bae1f 100644 --- a/src/log/log.cc +++ b/src/log/log.cc @@ -1,4 +1,6 @@ #include "sled/log/log.h" +#include "sled/time_utils.h" +#include #include #include @@ -18,6 +20,34 @@ 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(now % kNumNanosecsPerSec) + / kNumNanosecsPerMillisec); +#else + return result + "Z"; +#endif + return result; +} + void Log(LogLevel level, const char *tag, @@ -32,8 +62,8 @@ Log(LogLevel level, int len = file_name ? strlen(file_name) : 0; while (len > 0 && file_name[len - 1] != '/') { len--; } - auto msg = fmt::format("{}:{}@{} {} {}", file_name + len, line, func_name, - tag, fmt); + auto msg = fmt::format("{} {}:{}@{} {} {}", GetCurrentUTCTime(), + file_name + len, line, func_name, tag, fmt); std::cout << msg << std::endl; } diff --git a/src/system/location.cc b/src/system/location.cc new file mode 100644 index 0000000..65ab064 --- /dev/null +++ b/src/system/location.cc @@ -0,0 +1,23 @@ +#include "sled/system/location.h" + +namespace sled { + +Location +Location::Current(const char *file_name, int file_line, const char *function) +{ + return Location(file_name, file_line, function); +} + +Location::Location(const char *file_name, int file_line, const char *function) + : file_name(file_name), + file_line(file_line), + function(function) +{} + +std::string +Location::ToString() const +{ + return std::string(file_name) + ":" + std::to_string(file_line) + " " + + function; +} +}// namespace sled diff --git a/src/system_time.cc b/src/system_time.cc index 9f71a49..99b57ea 100644 --- a/src/system_time.cc +++ b/src/system_time.cc @@ -8,7 +8,8 @@ SystemTimeNanos() int64_t ticks; struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - ticks = kNumNanosecsPerSec * static_cast(ts.tv_sec) + static_cast(ts.tv_nsec); + ticks = kNumNanosecsPerSec * static_cast(ts.tv_sec) + + static_cast(ts.tv_nsec); return ticks; } }// namespace sled diff --git a/src/time_utils.cc b/src/time_utils.cc index 98b46bd..e0ef69b 100644 --- a/src/time_utils.cc +++ b/src/time_utils.cc @@ -51,49 +51,10 @@ TimeDiff(int32_t later, int32_t earlier) } int64_t -TmToSeconds(const tm &tm) +TmToSeconds(const tm &tm_val) { - static short int mdays[12] = {31, 28, 31, 30, 31, 30, - 31, 31, 30, 31, 30, 31}; - static short int cumul_mdays[12] = {0, 31, 59, 90, 120, 151, - 181, 212, 243, 273, 304, 334}; - int year = tm.tm_year + 1900; - int month = tm.tm_mon; - int day = tm.tm_mday - 1;// Make 0-based like the rest. - int hour = tm.tm_hour; - int min = tm.tm_min; - int sec = tm.tm_sec; - - bool expiry_in_leap_year = - (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); - - if (year < 1970) return -1; - if (month < 0 || month > 11) return -1; - if (day < 0 - || day >= mdays[month] + (expiry_in_leap_year && month == 2 - 1)) - return -1; - if (hour < 0 || hour > 23) return -1; - if (min < 0 || min > 59) return -1; - if (sec < 0 || sec > 59) return -1; - - day += cumul_mdays[month]; - - // Add number of leap days between 1970 and the expiration year, inclusive. - day += ((year / 4 - 1970 / 4) - (year / 100 - 1970 / 100) - + (year / 400 - 1970 / 400)); - - // We will have added one day too much above if expiration is during a leap - // year, and expiration is in January or February. - if (expiry_in_leap_year && month <= 2 - 1)// `month` is zero based. - day -= 1; - - // Combine all variables into seconds from 1970-01-01 00:00 (except `month` - // which was accumulated into `day` above). - return (((static_cast(year - 1970) * 365 + day) * 24 + hour) * 60 - + min) - * 60 - + sec; - return -1; + struct tm *ptm = const_cast(&tm_val); + return ::timegm(ptm); } int64_t @@ -118,11 +79,9 @@ int64_t TimeUTCNanos() { if (g_clock) { return g_clock->TimeNanos() / kNumNanosecsPerMicrosec; } - struct timeval time; - gettimeofday(&time, nullptr); - int64_t nanosecs = - static_cast(time.tv_sec) * kNumNanosecsPerSec + time.tv_usec; - return nanosecs; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return ts.tv_nsec + ts.tv_sec * kNumNanosecsPerSec; } }// namespace sled