Commit 088477b4 authored by paopao's avatar paopao

添加日志文件

parent ac68b40f
...@@ -28,7 +28,7 @@ BarrierGateControl::BarrierGateControl(nlohmann::json& config,const std::map<int ...@@ -28,7 +28,7 @@ BarrierGateControl::BarrierGateControl(nlohmann::json& config,const std::map<int
, uart_name_(config["uart"]) , uart_name_(config["uart"])
, report_topic_(config["report_topic"]) , report_topic_(config["report_topic"])
, control_topic_(config["control_topic"]) , control_topic_(config["control_topic"])
,numbarrier_config_map(numbarrier_info_config_map) ,numbarrier_config_map(numbarrier_info_config_map),barrier_gate_Log("Launch.ini")
{ {
init(); init();
} }
...@@ -38,13 +38,27 @@ BarrierGateControl::BarrierGateControl(nlohmann::json& config,const std::map<int ...@@ -38,13 +38,27 @@ BarrierGateControl::BarrierGateControl(nlohmann::json& config,const std::map<int
, uart_name_(config["uart"]) , uart_name_(config["uart"])
, report_topic_(config["report_topic"]) , report_topic_(config["report_topic"])
, control_topic_(config["control_topic"]) , control_topic_(config["control_topic"])
, numbarrier_config_map(numbarrier_info_config_map) , numbarrier_config_map(numbarrier_info_config_map),barrier_gate_Log("Launch.ini")
, command_(command) , command_(command)
{ {
init(); init();
} }
void BarrierGateControl::RecordTimeLaunch()
{
barrier_gate_Log.set_log_file("RecordInfo.log");
if(!barrier_gate_Log.exists())
{
std::cout << "INI文件不存在,正在创建新文件...\n";
if (!barrier_gate_Log.create()) {
std::cerr << "创建INI文件失败\n";
return ;
}
}
}
void BarrierGateControl::exec() void BarrierGateControl::exec()
{ {
__m_running = true; __m_running = true;
...@@ -85,6 +99,7 @@ void BarrierGateControl::exec() ...@@ -85,6 +99,7 @@ void BarrierGateControl::exec()
buffer.resize(containts.size()); buffer.resize(containts.size());
std::copy(containts.begin(), containts.end(), buffer.begin()); std::copy(containts.begin(), containts.end(), buffer.begin());
std::cout << "publish traffic light states: " << containts << std::endl; std::cout << "publish traffic light states: " << containts << std::endl;
barrier_gate_Log.log("publish traffic light states: " + containts );
__m_status_puber->publish(buffer); __m_status_puber->publish(buffer);
} }
} }
...@@ -104,7 +119,7 @@ void BarrierGateControl::exec() ...@@ -104,7 +119,7 @@ void BarrierGateControl::exec()
if(crc[0] == buffer[len - 2] && crc[1] == buffer[len - 1]) if(crc[0] == buffer[len - 2] && crc[1] == buffer[len - 1])
{ {
std::cout << "crc check ok!" << std::endl; std::cout << "crc check ok!" << std::endl;
barrier_gate_Log.log("crc check ok!");
uint8_t func_code = buffer[1]; uint8_t func_code = buffer[1];
gate_code = (buffer[len - 4] << 8 | buffer[len - 3]); gate_code = (buffer[len - 4] << 8 | buffer[len - 3]);
if(func_code == 0x03) if(func_code == 0x03)
...@@ -121,6 +136,7 @@ void BarrierGateControl::exec() ...@@ -121,6 +136,7 @@ void BarrierGateControl::exec()
else else
{ {
std::cout << "unknown func code: " << (int)func_code << std::endl; std::cout << "unknown func code: " << (int)func_code << std::endl;
barrier_gate_Log.log("unknown func code:");
Exc_Barrier(0,gate_code);// 失败 Exc_Barrier(0,gate_code);// 失败
} }
} }
...@@ -159,6 +175,7 @@ void BarrierGateControl::init() ...@@ -159,6 +175,7 @@ void BarrierGateControl::init()
current_gate_= cvt_gate_status(command_); current_gate_= cvt_gate_status(command_);
gate_control(0, current_gate_); gate_control(0, current_gate_);
std::cerr << "init gate_control ..........."<<command_<<"current_gate_=" <<current_gate_ <<std::endl; std::cerr << "init gate_control ..........."<<command_<<"current_gate_=" <<current_gate_ <<std::endl;
barrier_gate_Log.log("init gate_control ..........."+ command_+"current_gate_=" + std::to_string(current_gate_));
} }
void BarrierGateControl::on_control_request(const mqtt_dataio::subscriber_basic::DataBuffer& msg) void BarrierGateControl::on_control_request(const mqtt_dataio::subscriber_basic::DataBuffer& msg)
...@@ -181,6 +198,7 @@ void BarrierGateControl::on_control_request(const mqtt_dataio::subscriber_basic: ...@@ -181,6 +198,7 @@ void BarrierGateControl::on_control_request(const mqtt_dataio::subscriber_basic:
gate_control(0, gate); gate_control(0, gate);
std::cout << "change traffic light status from: " << cvt_gate_status(current_gate_) << " to " << cvt_gate_status(gate) << std::endl; std::cout << "change traffic light status from: " << cvt_gate_status(current_gate_) << " to " << cvt_gate_status(gate) << std::endl;
barrier_gate_Log.log("change traffic light status from: "+ cvt_gate_status(current_gate_) + " to " + cvt_gate_status(gate));
current_gate_ = gate; current_gate_ = gate;
} }
...@@ -209,6 +227,7 @@ void BarrierGateControl::Exc_Barrier(int stateCode,uint16_t changeCode ) ...@@ -209,6 +227,7 @@ void BarrierGateControl::Exc_Barrier(int stateCode,uint16_t changeCode )
current_gate_=(GateState)changeCode; current_gate_=(GateState)changeCode;
std::string barrier_gate_status = cvt_gate_status(changeCode); std::string barrier_gate_status = cvt_gate_status(changeCode);
std::cout << "gate code: " << (int)changeCode << ", barrier gate status: " << barrier_gate_status << std::endl; std::cout << "gate code: " << (int)changeCode << ", barrier gate status: " << barrier_gate_status << std::endl;
barrier_gate_Log.log( "gate code: " + std::to_string((int)changeCode) + ", barrier gate status: " + barrier_gate_status );
return; return;
} }
//成功删除第一个值,取下一个值 //成功删除第一个值,取下一个值
......
...@@ -6,39 +6,8 @@ ...@@ -6,39 +6,8 @@
#include "uart/uart.hpp" #include "uart/uart.hpp"
#include "3th-part/json.hpp" #include "3th-part/json.hpp"
#include <queue> #include <queue>
#include"barrier_gate_log.h"
struct traffic_light_config
{
/* data */
uint16_t id;
std::string type;
std::vector<uint16_t> do_addr;
std::vector<std::string> color;
};
struct roadside_info_config
{
std::string id;
std::string topic;
double longitude;
double latitude;
double altitude;
uint32_t isLight;
};
struct traffic_light_status_config
{
/* data */
uint16_t id;
std::string color;
};
struct traffic_mode_config
{
uint16_t id;
std::vector<traffic_light_status_config> lights;
};
class BarrierGateControl class BarrierGateControl
...@@ -90,6 +59,8 @@ private: ...@@ -90,6 +59,8 @@ private:
void on_control_request(const mqtt_dataio::subscriber_basic::DataBuffer& msg); void on_control_request(const mqtt_dataio::subscriber_basic::DataBuffer& msg);
void RecordTimeLaunch();//记录日志
private: private:
bool __m_running; bool __m_running;
...@@ -97,4 +68,6 @@ private: ...@@ -97,4 +68,6 @@ private:
uint16_t __m_offset_do_addr; uint16_t __m_offset_do_addr;
std::map<int, std::string> numbarrier_config_map; std::map<int, std::string> numbarrier_config_map;
std::queue<BarrierGateControl::roadside_info_barrier>curExcBarrierQueue; std::queue<BarrierGateControl::roadside_info_barrier>curExcBarrierQueue;
Barrier_Gate_Log barrier_gate_Log;//记录日志数据
}; };
#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <mutex>
struct traffic_light_config
{
/* data */
uint16_t id;
std::string name;
std::string type;
std::vector<uint16_t> do_addr;
std::vector<std::string> color;
};
struct roadside_info_config
{
std::string id;
std::string topic;
double longitude;
double latitude;
double altitude;
uint32_t isLight;
bool isManualLane;
uint16_t lightState;
};
struct traffic_light_status_config
{
/* data */
uint16_t id;
std::string color;
};
struct traffic_mode_config
{
uint16_t id;
std::vector<traffic_light_status_config> lights;
};
// INI 配置文件管理类
class Barrier_Gate_Log {
private:
std::string filename;
std::map<std::string, std::map<std::string, std::string>> data;
bool file_exists = false;
std::string log_file;
// 去除字符串两端的空白字符
static std::string trim(const std::string &str)
{
size_t start = str.find_first_not_of(" \t\r\n");
size_t end = str.find_last_not_of(" \t\r\n");
if (start == std::string::npos)
return "";
return str.substr(start, end - start + 1);
}
// 检查字符串是否以指定前缀开头
static bool starts_with(const std::string &str, const std::string &prefix)
{
return str.size() >= prefix.size() &&
str.compare(0, prefix.size(), prefix) == 0;
}
// 获取当前时间字符串
static std::string current_time()
{
auto now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::tm now_tm = *std::localtime(&now_c);
std::ostringstream oss;
oss << std::put_time(&now_tm, "%Y-%m-%d %H:%M:%S");
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) %
1000;
oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
return oss.str();
}
// 确保目录存在
bool ensure_directory_exists(const std::string &path)
{
size_t pos = 0;
std::string dir;
while ((pos = path.find_first_of('/', pos + 1)) != std::string::npos)
{
dir = path.substr(0, pos);
if (dir.empty())
continue; // 跳过根目录
struct stat st;
if (stat(dir.c_str(), &st) != 0)
{
// 目录不存在,创建它
if (mkdir(dir.c_str(), 0755) != 0 && errno != EEXIST)
{
log("创建目录失败: " + dir);
return false;
}
}
else if (!S_ISDIR(st.st_mode))
{
log("路径不是目录: " + dir);
return false;
}
}
return true;
}
// 解析一行INI内容
void parse_line(const std::string &line, std::string &current_section)
{
std::string trimmed = trim(line);
// 跳过空行和注释
if (trimmed.empty() || starts_with(trimmed, "#") ||
starts_with(trimmed, ";"))
{
return;
}
// 处理节
if (trimmed.front() == '[' && trimmed.back() == ']')
{
current_section = trim(trimmed.substr(1, trimmed.size() - 2));
return;
}
// 处理键值对
size_t pos = trimmed.find('=');
if (pos != std::string::npos)
{
std::string key = trim(trimmed.substr(0, pos));
std::string value = trim(trimmed.substr(pos + 1));
// 处理带引号的值
if (!value.empty() && value.front() == '"' && value.back() == '"')
{
value = value.substr(1, value.size() - 2);
}
data[current_section][key] = value;
}
}
public:
// 记录日志
void log(const std::string &message)
{
if (log_file.empty())
return;
std::ofstream log_stream(log_file, std::ios::app);
if (log_stream.is_open())
{
// 移动指针到文件末尾
log_stream.seekp(0, std::ios::end);
// 获取文件大小
long long fileSize = log_stream.tellp();
if(fileSize>200*1024*1024)
{
log_stream.close();
log_stream.clear();
log_stream.open(log_file, std::ios::trunc);
}
log_stream << "[" << current_time() << "] " << message << "\n";
}
}
// 构造函数
Barrier_Gate_Log(const std::string &file) : filename(file)
{
struct stat st;
if (stat(filename.c_str(), &st) == 0)
{
file_exists = true;
log("INI文件存在: " + filename);
}
else
{
log("INI文件不存在: " + filename);
}
}
// 设置日志文件
void set_log_file(const std::string &inlog)
{
log_file = inlog;
log("日志文件设置为: " + inlog);
}
// 检查INI文件是否存在
bool exists() const
{
return file_exists;
}
// 创建INI文件
bool create()
{
if (file_exists)
{
log("INI文件已存在: " + filename);
return false;
}
// 确保目录存在
if (!ensure_directory_exists(filename))
{
log("无法创建目录路径: " + filename);
return false;
}
std::ofstream file(filename);
if (!file)
{
log("无法创建INI文件: " + filename + " - ");
return false;
}
// 写入默认配置
file << "# Linux INI 配置文件 记录一段时间内程序启动次数 \n";
file << "# 创建时间: " << current_time() << "\n";
file << "# 格式说明:\n";
file << "# [Section] 表示配置节\n";
file << "# key = value 表示键值对\n";
file << "# 以#或;开头的行是注释\n\n";
auto now = std::chrono::system_clock::now();
// 转换为时间戳(毫秒)
uint64_t timestamp_seconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
file << "[General]\n";
file << "app_name = Light_control\n";
file << "version = 1.0.0\n";
file << "LaunchTimes = " <<1<< "\n";
file << "LaunchTimestamp = " << timestamp_seconds << "\n";
file.close();
file_exists = true;
log("INI文件已创建: " + filename);
return true;
}
// 加载INI文件
bool load()
{
if (!file_exists)
{
log("INI文件不存在: " + filename);
return false;
}
std::ifstream file(filename);
if (!file)
{
log("无法打开INI文件: " + filename + " - ");
return false;
}
data.clear();
std::string line;
std::string current_section = "General";
while (std::getline(file, line))
{
parse_line(line, current_section);
std::cout << "getline...\n";
}
file.close();
log("INI文件已加载: " + filename);
return true;
}
// 保存INI文件
bool save()
{
if (!file_exists)
{
log("INI文件不存在: " + filename);
return false;
}
// 备份原文件
std::string backup = filename + ".bak";
if (std::rename(filename.c_str(), backup.c_str()) != 0)
{
log("创建备份失败: ");
}
else
{
log("已创建备份: " + backup);
}
std::ofstream file(filename);
if (!file)
{
log("无法写入INI文件: " + filename + " - ");
// 恢复备份
std::rename(backup.c_str(), filename.c_str());
return false;
}
file << "# Linux INI 配置文件\n";
file << "# 最后修改时间: " << current_time() << "\n";
file << "# 用户: " << getlogin() << "\n\n";
for (const auto &section : data)
{
file << "[" << section.first << "]\n";
for (const auto &key_value : section.second)
{
file << key_value.first << " = " << key_value.second << "\n";
}
file << "\n";
}
file.close();
log("INI文件已保存: " + filename);
return true;
}
// 获取配置值
std::string get_value(const std::string &section, const std::string &key, const std::string &default_value = "")
{
auto sec_it = data.find(section);
if (sec_it == data.end())
{
log("获取配置值失败 - 节不存在: [" + section + "] " + key);
return default_value;
}
auto key_it = sec_it->second.find(key);
if (key_it == sec_it->second.end())
{
log("获取配置值失败 - 键不存在: [" + section + "] " + key);
return default_value;
}
log("获取配置值: [" + section + "] " + key + " = " + key_it->second);
return key_it->second;
}
// 获取整数值
uint64_t get_int(const std::string &section, const std::string &key, int default_value = 0)
{
std::string value = get_value(section, key, "");
if (value.empty())
return default_value;
try
{
//return std::stoi(value);
char *endptr = nullptr;
errno = 0; // 重置错误标志
unsigned long long intvalue = std::strtoull(value.c_str(), &endptr, 10);
return static_cast<uint64_t>(intvalue);
}
catch (...)
{
log("转换整数值失败: [" + section + "] " + key + " = " + value);
return default_value;
}
}
// 获取浮点数值
double get_double(const std::string &section, const std::string &key, double default_value = 0.0)
{
std::string value = get_value(section, key, "");
if (value.empty())
return default_value;
try
{
return std::stod(value);
}
catch (...)
{
log("转换浮点数值失败: [" + section + "] " + key + " = " + value);
return default_value;
}
}
// 获取布尔值
bool get_bool(const std::string &section, const std::string &key, bool default_value = false)
{
std::string value = get_value(section, key, "");
if (value.empty())
return default_value;
// 转换为小写比较
std::string lower_value;
std::transform(value.begin(), value.end(), std::back_inserter(lower_value),
[](unsigned char c)
{ return std::tolower(c); });
if (lower_value == "true" || lower_value == "yes" || lower_value == "1")
{
return true;
}
else if (lower_value == "false" || lower_value == "no" || lower_value == "0")
{
return false;
}
else
{
log("转换布尔值失败: [" + section + "] " + key + " = " + value);
return default_value;
}
}
// 设置配置值
void set_value(const std::string &section, const std::string &key,
const std::string &value)
{
// std::lock_guard<std::mutex> lock(mtx);
std::string old_value = get_value(section, key, "");
data[section][key] = value;
log("设置配置值: [" + section + "] " + key +
" = " + value + " (原值: " + old_value + ")");
}
// 设置整数值
void set_int(const std::string &section, const std::string &key, uint64_t value)
{
set_value(section, key, std::to_string(value));
}
// 设置浮点数值
void set_double(const std::string &section, const std::string &key, double value)
{
set_value(section, key, std::to_string(value));
}
// 设置布尔值
void set_bool(const std::string &section, const std::string &key, bool value)
{
set_value(section, key, value ? "true" : "false");
}
// 删除配置项
bool remove_key(const std::string &section, const std::string &key)
{
auto sec_it = data.find(section);
if (sec_it == data.end())
{
log("删除配置项失败 - 节不存在: [" + section + "] " + key);
return false;
}
if (sec_it->second.erase(key) > 0)
{
log("已删除配置项: [" + section + "] " + key);
return true;
}
log("删除配置项失败 - 键不存在: [" + section + "] " + key);
return false;
}
// 删除配置节
bool remove_section(const std::string &section)
{
if (data.erase(section) > 0)
{
log("已删除配置节: [" + section + "]");
return true;
}
log("删除配置节失败 - 节不存在: [" + section + "]");
return false;
}
// 获取所有配置节
std::vector<std::string> get_sections()
{
std::vector<std::string> sections;
for (const auto &section : data)
{
sections.push_back(section.first);
}
return sections;
}
// 获取指定节的所有键
std::vector<std::string> get_keys(const std::string &section)
{
std::vector<std::string> keys;
auto sec_it = data.find(section);
if (sec_it != data.end())
{
for (const auto &key_value : sec_it->second)
{
keys.push_back(key_value.first);
}
}
return keys;
}
// 检查配置节是否存在
bool section_exists(const std::string &section)
{
return data.find(section) != data.end();
}
// 检查配置项是否存在
bool key_exists(const std::string &section, const std::string &key)
{
auto sec_it = data.find(section);
if (sec_it == data.end())
return false;
return sec_it->second.find(key) != sec_it->second.end();
}
// 显示所有配置
void display()
{
std::cout << "\nINI 文件内容 (" << filename << "):\n";
std::cout << "========================================\n";
for (const auto &section : data)
{
std::cout << "[" << section.first << "]\n";
for (const auto &key_value : section.second)
{
std::cout << " " << key_value.first << " = " << key_value.second << "\n";
}
std::cout << "\n";
}
std::cout << "========================================\n";
log("显示INI文件内容");
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment