99 lines
2.5 KiB
C++
99 lines
2.5 KiB
C++
#include "DebugLog.h"
|
|
|
|
#include <android/log.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/syscall.h>
|
|
#include <unistd.h>
|
|
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
#include <ctime>
|
|
#include <mutex>
|
|
|
|
namespace {
|
|
|
|
std::mutex g_mtx;
|
|
FILE* g_fp = nullptr;
|
|
std::string g_path;
|
|
constexpr size_t kMaxSize = 2 * 1024 * 1024; // 2 MB before rotation
|
|
|
|
pid_t currentTid() {
|
|
return static_cast<pid_t>(syscall(SYS_gettid));
|
|
}
|
|
|
|
} // namespace
|
|
|
|
namespace DebugLog {
|
|
|
|
void init(const char* internalDataPath) {
|
|
std::lock_guard<std::mutex> lk(g_mtx);
|
|
if (g_fp) {
|
|
return; // already initialized
|
|
}
|
|
|
|
const char* base = (internalDataPath && *internalDataPath) ? internalDataPath : "/data/local/tmp";
|
|
g_path = std::string(base) + "/face_sdk_debug.log";
|
|
|
|
// Rotate once if current file is too large.
|
|
struct stat st{};
|
|
if (stat(g_path.c_str(), &st) == 0 && static_cast<size_t>(st.st_size) > kMaxSize) {
|
|
std::string backup = g_path + ".old";
|
|
std::remove(backup.c_str());
|
|
std::rename(g_path.c_str(), backup.c_str());
|
|
}
|
|
|
|
g_fp = std::fopen(g_path.c_str(), "a");
|
|
if (g_fp) {
|
|
time_t now = time(nullptr);
|
|
struct tm tm_info{};
|
|
localtime_r(&now, &tm_info);
|
|
char tbuf[64];
|
|
strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S", &tm_info);
|
|
std::fprintf(g_fp,
|
|
"\n========== DebugLog opened @ %s (pid=%d) ==========\n",
|
|
tbuf, getpid());
|
|
std::fflush(g_fp);
|
|
}
|
|
|
|
__android_log_print(ANDROID_LOG_INFO, "FACE_DBG",
|
|
"DebugLog file path: %s", g_path.c_str());
|
|
}
|
|
|
|
void log(const char* fmt, ...) {
|
|
char buf[1024];
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
int n = std::vsnprintf(buf, sizeof(buf), fmt, ap);
|
|
va_end(ap);
|
|
if (n < 0) return;
|
|
|
|
pid_t tid = currentTid();
|
|
|
|
timespec ts{};
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
struct tm tm_info{};
|
|
localtime_r(&ts.tv_sec, &tm_info);
|
|
char timebuf[32];
|
|
strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm_info);
|
|
|
|
std::lock_guard<std::mutex> lk(g_mtx);
|
|
if (g_fp) {
|
|
std::fprintf(g_fp, "[%s.%03ld][tid=%d] %s\n",
|
|
timebuf, ts.tv_nsec / 1000000, tid, buf);
|
|
std::fflush(g_fp);
|
|
}
|
|
__android_log_print(ANDROID_LOG_INFO, "FACE_DBG", "[tid=%d] %s", tid, buf);
|
|
}
|
|
|
|
void flush() {
|
|
std::lock_guard<std::mutex> lk(g_mtx);
|
|
if (g_fp) std::fflush(g_fp);
|
|
}
|
|
|
|
std::string getLogPath() {
|
|
std::lock_guard<std::mutex> lk(g_mtx);
|
|
return g_path;
|
|
}
|
|
|
|
} // namespace DebugLog
|