103 lines
3.3 KiB
C++
103 lines
3.3 KiB
C++
#include "log_action.h"
|
|
|
|
#include <chrono>
|
|
#include <ctime>
|
|
#include <iomanip>
|
|
#include <mutex>
|
|
#include <sstream>
|
|
|
|
#include "utils/logger.h"
|
|
|
|
namespace rk3588 {
|
|
|
|
namespace {
|
|
|
|
bool SafeLocalTime(std::time_t t, std::tm& out) {
|
|
#if defined(_WIN32)
|
|
return localtime_s(&out, &t) == 0;
|
|
#elif defined(__unix__) || defined(__APPLE__)
|
|
return localtime_r(&t, &out) != nullptr;
|
|
#else
|
|
static std::mutex mu;
|
|
std::lock_guard<std::mutex> lock(mu);
|
|
std::tm* p = std::localtime(&t);
|
|
if (!p) return false;
|
|
out = *p;
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
LogLevel LogLevelFromStringOrInfo(const std::string& s) {
|
|
LogLevel lvl = LogLevel::Info;
|
|
(void)ParseLogLevel(s, lvl);
|
|
return lvl;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
bool LogAction::Init(const SimpleJson& config) {
|
|
level_ = config.ValueOr<std::string>("level", "info");
|
|
include_detections_ = config.ValueOr<bool>("include_detections", true);
|
|
LogInfo("[LogAction] initialized, level=" + level_);
|
|
return true;
|
|
}
|
|
|
|
void LogAction::Execute(AlarmEvent& event, std::shared_ptr<Frame> /*frame*/) {
|
|
auto now = std::chrono::system_clock::now();
|
|
auto time_t_now = std::chrono::system_clock::to_time_t(now);
|
|
std::tm tm_now{};
|
|
(void)SafeLocalTime(time_t_now, tm_now);
|
|
|
|
std::ostringstream oss;
|
|
oss << "[ALARM][" << level_ << "] "
|
|
<< std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S")
|
|
<< " event_id=" << (event.event_id.empty() ? "-" : event.event_id)
|
|
<< " node=" << event.node_id
|
|
<< " rule=" << event.rule_name
|
|
<< " frame=" << event.frame_id;
|
|
|
|
if (include_detections_ && !event.detections.empty()) {
|
|
oss << " detections=[";
|
|
for (size_t i = 0; i < event.detections.size(); ++i) {
|
|
const auto& det = event.detections[i];
|
|
if (i > 0) oss << ", ";
|
|
oss << "{cls=" << det.cls_id
|
|
<< " score=" << std::fixed << std::setprecision(2) << det.score
|
|
<< " bbox=(" << static_cast<int>(det.bbox.x) << ","
|
|
<< static_cast<int>(det.bbox.y) << ","
|
|
<< static_cast<int>(det.bbox.w) << ","
|
|
<< static_cast<int>(det.bbox.h) << ")}";
|
|
}
|
|
oss << "]";
|
|
}
|
|
|
|
if (!event.face_matches.empty()) {
|
|
oss << " face_matches=[";
|
|
for (size_t i = 0; i < event.face_matches.size(); ++i) {
|
|
const auto& match = event.face_matches[i];
|
|
if (i > 0) oss << ", ";
|
|
const float sim_margin = match.best_sim - match.second_sim;
|
|
const std::string candidate = match.candidate_name.empty() ? "n/a" : match.candidate_name;
|
|
oss << "{status=" << FaceAlarmStatusName(match.status)
|
|
<< " candidate=" << candidate
|
|
<< " candidate_id=" << match.candidate_person_id
|
|
<< " best_sim=" << std::fixed << std::setprecision(2) << match.best_sim
|
|
<< " second_sim=" << std::fixed << std::setprecision(2) << match.second_sim
|
|
<< " sim_margin=" << std::fixed << std::setprecision(2) << sim_margin
|
|
<< "}";
|
|
}
|
|
oss << "]";
|
|
}
|
|
|
|
if (!event.snapshot_url.empty()) {
|
|
oss << " snapshot=" << event.snapshot_url;
|
|
}
|
|
if (!event.clip_url.empty()) {
|
|
oss << " clip=" << event.clip_url;
|
|
}
|
|
|
|
Logger::Instance().Log(LogLevelFromStringOrInfo(level_), oss.str());
|
|
}
|
|
|
|
} // namespace rk3588
|