#include "log_action.h" #include #include #include #include #include #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 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("level", "info"); include_detections_ = config.ValueOr("include_detections", true); LogInfo("[LogAction] initialized, level=" + level_); return true; } void LogAction::Execute(AlarmEvent& event, std::shared_ptr /*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") << " 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(det.bbox.x) << "," << static_cast(det.bbox.y) << "," << static_cast(det.bbox.w) << "," << static_cast(det.bbox.h) << ")}"; } 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