diff --git a/f8/dbpool.cc b/f8/dbpool.cc index 84f7943..f657f7c 100644 --- a/f8/dbpool.cc +++ b/f8/dbpool.cc @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/f8/httpclientpool.cc b/f8/httpclientpool.cc index 8b9f298..db458cf 100644 --- a/f8/httpclientpool.cc +++ b/f8/httpclientpool.cc @@ -17,13 +17,13 @@ #include #include #include -#include #include #include -#include "f8/httpclientpool.h" -#include "f8/msgqueue.h" -#include "f8/utils.h" +#include +#include +#include +#include #define F8_MUTLI_THREAD_HTTP 1 diff --git a/f8/netmsghandler.cc b/f8/netmsghandler.cc index 971bd62..eafb742 100644 --- a/f8/netmsghandler.cc +++ b/f8/netmsghandler.cc @@ -1,10 +1,10 @@ #include -#include #include #include #include +#include #include #include #include @@ -23,7 +23,7 @@ namespace f8 return; ::google::protobuf::Message* msg = handler->prototype->New(); bool ok = msg->ParseFromArray(hdr.buf + hdr.offset, hdr.buflen - hdr.offset); - a8::UdpLog::Instance()->Debug + f8::UdpLog::Instance()->Debug ( "%s%s %s", { @@ -37,7 +37,7 @@ namespace f8 void DumpMsgToLog(const ::google::protobuf::Message& msg, const char* prefix) { return; - a8::UdpLog::Instance()->Debug + f8::UdpLog::Instance()->Debug ( "%s%s %s", { diff --git a/f8/scriptengine.cc b/f8/scriptengine.cc index dad06f9..7b21efe 100644 --- a/f8/scriptengine.cc +++ b/f8/scriptengine.cc @@ -1,6 +1,7 @@ #include #include -#include + +#include #include "scriptengine.h" diff --git a/f8/udplog.cc b/f8/udplog.cc new file mode 100644 index 0000000..61a2adf --- /dev/null +++ b/f8/udplog.cc @@ -0,0 +1,224 @@ +#include +#include +#include + +#include +#include + +#include + +namespace f8 +{ + struct UdpLogMsgNode + { + std::string logmsg; + UdpLogMsgNode* next = nullptr; + }; + + struct UdpLogImpl + { + unsigned short log_level = 0; + bool debuging = false; + std::string log_filename; + + std::thread* save_thread = nullptr; + bool save_thread_shutdown = false; + + std::mutex msg_mutex; + UdpLogMsgNode* top_node = nullptr; + UdpLogMsgNode* bot_node = nullptr; + UdpLogMsgNode* work_node = nullptr; + std::mutex *save_cond_mutex = nullptr; + std::condition_variable *save_cond = nullptr; + + }; + + UdpLog::UdpLog() + { + impl_ = new UdpLogImpl(); + impl_->save_cond_mutex = new std::mutex(); + impl_->save_cond = new std::condition_variable(); + + impl_->log_level = 0; + #ifdef DEBUG + impl_->debuging = true; + #endif + impl_->top_node = nullptr; + impl_->bot_node = nullptr; + impl_->work_node = nullptr; + } + + UdpLog::~UdpLog() + { + delete impl_->save_cond_mutex; + impl_->save_cond_mutex = nullptr; + delete impl_->save_cond; + impl_->save_cond = nullptr; + delete impl_; + impl_ = nullptr; + } + + void UdpLog::Init() + { + impl_->save_thread_shutdown = false; + impl_->save_thread = new std::thread(&UdpLog::SaveToFileThreadProc, this); + } + + void UdpLog::UnInit() + { + impl_->save_thread_shutdown = true; + impl_->save_thread->join(); + delete impl_->save_thread; + impl_->save_thread = nullptr; + impl_->msg_mutex.lock(); + if (impl_->work_node) { + impl_->work_node = impl_->top_node; + impl_->top_node = nullptr; + impl_->bot_node = nullptr; + } + while (impl_->work_node) { + UdpLogMsgNode* pdelnode = impl_->work_node; + impl_->work_node = impl_->work_node->next; + if (!impl_->work_node) { + impl_->work_node = impl_->top_node; + impl_->top_node = nullptr; + impl_->bot_node = nullptr; + } + delete pdelnode; + } + impl_->msg_mutex.unlock(); + } + + void UdpLog::SetLogFileName(const std::string& filename) + { + impl_->log_filename = filename; + } + + void UdpLog::Emergency(const char *format, std::initializer_list args) + { + if (impl_->log_level > 6) { + return; + } + SendLog("[EMERGENCY]", format, args); + } + + void UdpLog::Alert(const char *format, std::initializer_list args) + { + if (impl_->log_level > 5) { + return; + } + SendLog("[ALERT]", format, args); + } + + void UdpLog::Error(const char *format, std::initializer_list args) + { + if (impl_->log_level > 4) { + return; + } + SendLog("[ERROR]", format, args); + } + + void UdpLog::Warning(const char *format, std::initializer_list args) + { + if (impl_->log_level > 3) { + return; + } + SendLog("[WARNING]", format, args); + } + + void UdpLog::Notice(const char *format, std::initializer_list args) + { + if (impl_->log_level > 2) { + return; + } + SendLog("[NOTICE]", format, args); + } + + void UdpLog::Info(const char *format, std::initializer_list args) + { + if (impl_->log_level > 1) { + return; + } + SendLog("[INFO]", format, args); + } + + void UdpLog::Debug(const char *format, std::initializer_list args) + { + if (impl_->log_level > 0) { + return; + } + SendLog("[DEBUG]", format, args); + } + + void UdpLog::SendLog(const char *category, const char *format, + std::initializer_list& args) + { + time_t nowtime = time(nullptr); + struct tm tm_nowtime = {0}; + struct tm *ptr = localtime_r(&nowtime, &tm_nowtime); + char strtime[80]; + strftime(strtime, 80, "%F %T", ptr); + + UdpLogMsgNode *p = new UdpLogMsgNode(); + p->logmsg.reserve(128); + p->logmsg.append((char*)strtime); + p->logmsg.append(category); + p->logmsg.append(" "); + p->logmsg.append(a8::FormatEx(format, args)); + p->logmsg.append("\n"); + if (impl_->debuging) { + printf("%s", p->logmsg.c_str()); + } + impl_->msg_mutex.lock(); + if (impl_->bot_node) { + impl_->bot_node->next = p; + impl_->bot_node = p; + } else { + impl_->top_node = p; + impl_->bot_node = p; + } + impl_->msg_mutex.unlock(); + { + std::unique_lock lk(*impl_->save_cond_mutex); + impl_->save_cond->notify_all(); + } + } + + void UdpLog::SaveToFileThreadProc() + { + while (!impl_->save_thread_shutdown) { + if (!impl_->work_node && impl_->top_node) { + impl_->msg_mutex.lock(); + impl_->work_node = impl_->top_node; + impl_->top_node = nullptr; + impl_->bot_node = nullptr; + impl_->msg_mutex.unlock(); + } + + if (impl_->work_node) { + time_t nowtime = time(nullptr); + struct tm tm_nowtime = {0}; + localtime_r(&nowtime, &tm_nowtime); + + char szfilename[256]; + strftime(szfilename, a8::ArraySize(szfilename), impl_->log_filename.c_str(), &tm_nowtime); + std::string filename((char*)szfilename); + FILE *logfile = fopen(filename.c_str(), "a+"); + if (logfile) { + while (impl_->work_node) { + UdpLogMsgNode *nextnode = impl_->work_node->next; + fwrite(impl_->work_node->logmsg.c_str(), 1, impl_->work_node->logmsg.length(), logfile); + delete impl_->work_node; + impl_->work_node = nextnode; + } + fclose(logfile); + } + } + { + std::unique_lock lk(*impl_->save_cond_mutex); + impl_->save_cond->wait_for(lk, std::chrono::seconds(10)); + } + } + } + +} diff --git a/f8/udplog.h b/f8/udplog.h new file mode 100644 index 0000000..6ce77df --- /dev/null +++ b/f8/udplog.h @@ -0,0 +1,39 @@ +#pragma once + +#include + +namespace f8 +{ + + class UdpLog : public a8::Singleton + { + private: + UdpLog(); + friend class a8::Singleton; + + public: + ~UdpLog(); + + void Init(); + void UnInit(); + + void SetLogFileName(const std::string& filename); + + void Emergency(const char *format, std::initializer_list args); + void Alert(const char *format, std::initializer_list args); + void Error(const char *format, std::initializer_list args); + void Warning(const char *format, std::initializer_list args); + void Notice(const char *format, std::initializer_list args); + void Info(const char *format, std::initializer_list args); + void Debug(const char *format, std::initializer_list args); + + private: + void SendLog(const char *category, const char *format, + std::initializer_list& args); + void SaveToFileThreadProc(); + + private: + struct UdpLogImpl* impl_ = nullptr; + }; + +} diff --git a/f8/utils.cc b/f8/utils.cc index 9b66f20..56e2cc3 100644 --- a/f8/utils.cc +++ b/f8/utils.cc @@ -2,12 +2,14 @@ #include #include -#include #include #include #include #include +#include +#include + #include #include #include @@ -376,8 +378,8 @@ namespace f8 void InitMysqlConnection(a8::mysql::Query* query) { - a8::UdpLog::Instance()->Info("show variables like 'character%';", {}); - a8::UdpLog::Instance()->Info("Variable_name\tValue", {}); + f8::UdpLog::Instance()->Info("show variables like 'character%';", {}); + f8::UdpLog::Instance()->Info("Variable_name\tValue", {}); #if 1 query->ExecScript("SET character_set_server=utf8;", {}); query->ExecScript("SET NAMES utf8;", {}); @@ -386,7 +388,7 @@ namespace f8 while (!query->Eof()) { std::string line; line = query->GetValue(0).GetString() + "\t" + query->GetValue(1).GetString(); - a8::UdpLog::Instance()->Info(line.c_str(), {}); + f8::UdpLog::Instance()->Info(line.c_str(), {}); assert(!(query->GetValue(0).GetString() == "character_set_client" && query->GetValue(1).GetString() != "utf8")); assert(!(query->GetValue(0).GetString() == "character_set_connection" && @@ -402,13 +404,13 @@ namespace f8 query->Next(); } - a8::UdpLog::Instance()->Info("show variables like '%collation%';", {}); - a8::UdpLog::Instance()->Info("Variable_name\tValue", {}); + f8::UdpLog::Instance()->Info("show variables like '%collation%';", {}); + f8::UdpLog::Instance()->Info("Variable_name\tValue", {}); query->ExecQuery("show variables like '%collation%';", {}); while (!query->Eof()) { std::string line; line = query->GetValue(0).GetString() + "\t" + query->GetValue(1).GetString(); - a8::UdpLog::Instance()->Info(line.c_str(), {}); + f8::UdpLog::Instance()->Info(line.c_str(), {}); assert(query->GetValue(1).GetString() == "utf8_general_ci"); query->Next(); } @@ -418,12 +420,12 @@ namespace f8 std::string dbhost, int port, std::string dbuser, std::string dbpasswd, std::string gamedb) { if (query->ExecQuery("SELECT 1;", {}) <= 0) { - a8::UdpLog::Instance()->Warning("mysql disconnect", {}); + f8::UdpLog::Instance()->Warning("mysql disconnect", {}); if (conn->Connect(dbhost, 3306, dbuser, dbpasswd, gamedb)) { f8::InitMysqlConnection(query); - a8::UdpLog::Instance()->Info("mysql reconnect successed", {}); + f8::UdpLog::Instance()->Info("mysql reconnect successed", {}); } else { - a8::UdpLog::Instance()->Info("mysql reconnect failed", {}); + f8::UdpLog::Instance()->Info("mysql reconnect failed", {}); } } }