|
- #include "StdAfx.h"
- #include "TraceService.h" // #include "EventService.h"
- #include "../Spdlog/spdlog/sinks/base_sink.h"
- #include "../Spdlog/spdlog/sinks/msvc_sink.h"
- #include "../Spdlog/spdlog/sinks/stdout_color_sinks.h"
- #include "../Spdlog/spdlog/sinks/daily_file_sink.h"
- #include "../Spdlog/spdlog/sinks/basic_file_sink.h"
- //////////////////////////////////////////////////////////////////////////
- //颜色定义
- #define COLOR_TIME RGB(0,0,0)
- #define COLOR_NORMAL RGB(125,125,125)
- #define COLOR_WARN RGB(255,128,0)
- #define COLOR_EXCEPTION RGB(200,0,0)
- #define COLOR_DEBUG RGB(0,128,128)
-
- #define EVENT_LEVEL_COUNT 5
-
- #define IDM_MENU0 100
- #define IDM_MENU1 110
- #define IDM_MENU2 120
- #define IDM_MENU3 130
- #define IDM_MENU4 140
- #define IDM_MENU5 150
-
- //////////////////////////////////////////////////////////////////////////
-
- //追踪服务
- //////////////////////////////////////////////////////////////////////////
-
- Logger::~Logger()
- {
- };
-
- //Spdlog
- void Logger::ShutDown()
- {
- spdlog::shutdown();
- };
-
- Logger& Logger::GetInstance()
- {
- static Logger _log;
- return _log;
- }
-
- std::shared_ptr<spdlog::logger> Logger::GetTableLogger(int tableId)
- {
- if (tablelogger_.count(tableId))
- {
- return tablelogger_.at(tableId);
- }
- //创建新的logger
- auto new_loger = spdlog::basic_logger_mt(fmt::format("{}", tableId), fmt::format("{}table_{}.log", logfile_dir_, tableId));
- tablelogger_[tableId] = new_loger;
- return new_loger;
- }
-
- void Logger::DeleteTableLogger(int tableId)
- {
- if (tablelogger_.count(tableId))
- {
- spdlog::drop(fmt::format("{}", tableId));
- tablelogger_.erase(tableId);
- }
- }
- ;
-
- bool Logger::InitDefaultLog(std::string logger_name, std::string file_name, spdlog::level::level_enum log_level /*= spdlog::level::trace*/)
- {
- [](const char* dir, size_t len = 0) -> bool {
- assert(dir != NULL);
- if (len < 1 || len > 1024)
- return false;
- char* head, * p;
- char tmpDir[1024] = { 0 };
- // strcpy_s(tmpDir, 1024, dir); //拷贝1024字节发现,len之后的字符全部变为-2
- strcpy_s(tmpDir, len + 1, dir);
- head = tmpDir;
- if (*head == '\\' || *head == '/')
- ++head;
- p = head;
- if (*(tmpDir + len - 1) != '\\' && *(tmpDir + len - 1) != '/')
- *(tmpDir + len) = '\\';
-
- while (*p)
- {
- if (*p == '\\' || *p == '/')
- {
- *p = '\0';
- if (_access(head, 0)) // 头文件io.h
- {
- if (_mkdir(head))
- {
- #ifdef _DEBUG
- fprintf(stderr, "Failed to create directory %s\n", head);
- return false;
- #endif
- }
- }
- *p = '\\';
- }
- ++p;
- }
- return true;
- }("logs");
-
- spdlog::set_level(spdlog::level::trace);
- //SPDLOG_TRACE("Some trace message.. {} ,{}", 1, 3.23);
- //SPDLOG_DEBUG("Some debug message.. {} ,{}", 1, 3.23);
- //设置为异步日志
- // spdlog::set_async_mode(32768); // 必须为 2 的幂
-
- //spdlog::pattern_formatter formatter("%g", spdlog::pattern_time_type::local, "");
-
- //创建一个对应多个sink的_logger_,每一个sink都有独有的格式和日志级别
- std::vector<std::shared_ptr<spdlog::sinks::sink>> logger_sinks;
- //#ifdef _CONSOLE
- #ifdef _DEBUG
- auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
- console_sink->set_level(log_level);
- console_sink->set_pattern("[%m-%d %H:%M:%S.%e][%^%L%$] [%t:%@] %v");
- logger_sinks.push_back(console_sink);
- #endif
- // Create a daily logger - a new file is created every day on 2:30am.
- logfile_dir_ = fmt::format("logs/{}/", CT2A(AfxGetAppName()));
- auto dailyfile_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt>(logfile_dir_ + file_name, 23, 59, true);
- dailyfile_sink->set_level(log_level);
- //格式说明参照https://github.com/gabime/spdlog/wiki/3.-Custom-formatting
- dailyfile_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%t:%@] %v");
- logger_sinks.push_back(dailyfile_sink);
- #ifdef _WIN32
- //使用OutputDebugStringA窗口输出日志
- auto vs_sink = std::make_shared<spdlog::sinks::msvc_sink_mt>();
- vs_sink->set_level(log_level);
- vs_sink->set_pattern("[%m-%d %H:%M:%S.%e] [%^%l%$] [%t:%@] %v");
- logger_sinks.push_back(vs_sink);
- #endif
-
- logger_ = std::make_shared<spdlog::logger>(logger_name, begin(logger_sinks), end(logger_sinks));
- // register it if you need to access it globally
- spdlog::register_logger(logger_);
- // 设置日志记录级别
- #ifdef _DEBUG
- logger_->set_level(log_level);
- #else
- logger_->set_level(spdlog::level::err);
- #endif
- //设置当出发 err 或更严重的错误时立刻刷新日志到 disk
- logger_->flush_on(spdlog::level::err);
- //对所有已注册的loggers定期1秒调用flush()
- spdlog::flush_every(std::chrono::seconds(1));
- //替换任何其它logger为默认logger
- spdlog::set_default_logger(logger_);
- logger_->info("spdlog init success\n");
- //SPDLOG_LOGGER_TRACE(logger_, "test");
- return true;
- };
-
- static ITraceService* g_pITraceService = NULL;
- //函数定义
- //////////////////////////////////////////////////////////////////////////
- //构造函数
- CTraceService::CTraceService()
- {
-
- }
-
- //服务配置
- //////////////////////////////////////////////////////////////////////////
- //设置服务
- bool CTraceService::SetTraceService(IUnknownEx* pIUnknownEx)
- {
- g_pITraceService = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, ITraceService);
- return NULL != g_pITraceService;
- }
-
- //获取服务
- VOID* CTraceService::GetTraceService(const IID& Guid, DWORD dwQueryVer)
- {
- ASSERT(g_pITraceService);
- if (g_pITraceService) return NULL;
-
- return (VOID*)g_pITraceService->QueryInterface(Guid, dwQueryVer);
- return NULL;
- }
-
- //获取服务
- VOID* CTraceService::GetTraceServiceManager(const IID& Guid, DWORD dwQueryVer)
- {
- return NULL;
- }
-
- //状态管理
- //////////////////////////////////////////////////////////////////////////
- //追踪状态
- bool CTraceService::IsEnableTrace(enTraceLevel TraceLevel)
- {
- return false;
- }
-
- //追踪控制
- bool CTraceService::EnableTrace(enTraceLevel TraceLevel, bool bEnableTrace)
- {
- return false;
- }
-
- //功能函数
- //////////////////////////////////////////////////////////////////////////
- //追踪信息
- bool CTraceService::TraceString(LPCTSTR pszString, enTraceLevel TraceLevel)
- {
- if (TraceLevel == TraceLevel_Debug)
- return false;
-
- if (g_pITraceService)
- return g_pITraceService->TraceString(pszString, TraceLevel);
-
- return false;
- }
-
- //////////////////////////////////////////////////////////////////////////
- //追踪服务
- //////////////////////////////////////////////////////////////////////////
-
- BEGIN_MESSAGE_MAP(CTraceServiceControl, CRichEditCtrl)
- ON_WM_RBUTTONDOWN()
- ON_COMMAND(IDM_MENU0, OnCopyString)
- ON_COMMAND(IDM_MENU1, OnSelectAll)
- ON_COMMAND(IDM_MENU2, OnDeleteString)
- ON_COMMAND(IDM_MENU3, OnClearAll)
- ON_COMMAND(IDM_MENU4, OnSaveString)
- END_MESSAGE_MAP()
-
- //函数定义
- //////////////////////////////////////////////////////////////////////////
- //构造函数
- CTraceServiceControl::CTraceServiceControl()
- {
- CTraceService::SetTraceService((IUnknownEx*)QueryInterface(IID_IUnknownEx, VER_IUnknownEx));
- }
-
- //析构函数
- CTraceServiceControl::~CTraceServiceControl()
- {
- CTraceService::SetTraceService(NULL);
- }
-
- //基础接口
- //////////////////////////////////////////////////////////////////////////
- //接口查询
- VOID* CTraceServiceControl::QueryInterface(const IID& Guid, DWORD dwQueryVer)
- {
- QUERYINTERFACE(ITraceService, Guid, dwQueryVer);
- QUERYINTERFACE_IUNKNOWNEX(ITraceService, Guid, dwQueryVer);
- return NULL;
- }
-
- //信息接口
- //////////////////////////////////////////////////////////////////////////
- //追踪信息
- bool CTraceServiceControl::TraceString(LPCTSTR pszString, enTraceLevel TraceLevel)
- {
- //效验参数
- ITraceService* pITraceService = (ITraceService*)(QueryInterface(IID_ITraceService, VER_ITraceService));
- ASSERT(pITraceService != NULL);
- if (pITraceService == NULL) return false;
-
- //变量定义
- CHARFORMAT2 CharFormat;
- ZeroMemory(&CharFormat, sizeof(CharFormat));
-
- //构造数据
- CharFormat.cbSize = sizeof(CharFormat);
- CharFormat.dwMask = CFM_COLOR | CFM_BACKCOLOR;
- CTraceServiceControl* pRichEditTrace = static_cast<CTraceServiceControl*>(pITraceService);
- if (pRichEditTrace == NULL) return false;
- CharFormat.crTextColor = RGB(0, 0, 0);
- CharFormat.crBackColor = RGB(255, 255, 255);
-
- lstrcpyn(CharFormat.szFaceName, TEXT("宋体"), sizeof(CharFormat.szFaceName));
- //获取时间
- SYSTEMTIME SystemTime;
- TCHAR szTimeBuffer[4098] = { 0 };
- ZeroMemory(szTimeBuffer, sizeof(TCHAR) * 4096);
- GetLocalTime(&SystemTime);
- _snwprintf(szTimeBuffer, sizeof(szTimeBuffer), TEXT("【 %04d-%02d-%02d %02d:%02d:%02d 】"), SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
-
- // InsertString(szTimeBuffer, CharFormat);
-
- //长度判断
- int iLen = wcslen(pszString);
-
- if (iLen > 3800)
- {
- _sntprintf(szTimeBuffer, sizeof(szTimeBuffer), TEXT("%s%s\n"), szTimeBuffer, _T("输出信息超长,信息请小于4K。"));
- }
- else
- {
- _sntprintf(szTimeBuffer, sizeof(szTimeBuffer), TEXT("%s%s\n"), szTimeBuffer, pszString);
- }
-
- CharFormat.crTextColor = pRichEditTrace->GetTraceColor(TraceLevel);
- return InsertString(szTimeBuffer, CharFormat);
- }
-
- //重载函数
- //////////////////////////////////////////////////////////////////////////
- //绑定函数
- VOID CTraceServiceControl::PreSubclassWindow()
- {
- __super::PreSubclassWindow();
- CTraceService::SetTraceService((IUnknownEx*)QueryInterface(IID_IUnknownEx, VER_IUnknownEx));
- }
-
- //功能函数
- //////////////////////////////////////////////////////////////////////////
- //加载消息
- bool CTraceServiceControl::LoadMessage(LPCTSTR pszFileName)
- {
- if (static_cast<CTraceServiceControl*>(g_pITraceService) == NULL) return false;
- return static_cast<CTraceServiceControl*>(g_pITraceService)->LoadMessage(pszFileName);
- }
-
- //保存信息
- bool CTraceServiceControl::SaveMessage(LPCTSTR pszFileName)
- {
- if (static_cast<CTraceServiceControl*>(g_pITraceService) == NULL) return false;
- return static_cast<CTraceServiceControl*>(g_pITraceService)->SaveMessage(pszFileName);
- }
-
- //设置参数
- bool CTraceServiceControl::SetParameter(LONG lMaxLineCount, LONG lReserveLineCount)
- {
- m_lMaxLineCount = lMaxLineCount; //最大行数
- m_lReserveLineCount = lReserveLineCount; //保留行数
-
- return true;
- }
-
- //辅助函数
- //////////////////////////////////////////////////////////////////////////
- //配置服务
- VOID CTraceServiceControl::InitializeService()
- {
-
- }
-
- //获取颜色
- COLORREF CTraceServiceControl::GetTraceColor(enTraceLevel TraceLevel)
- {
- switch (TraceLevel)
- {
- case TraceLevel_Info:
- return RGB(133, 124, 129);
- break;
- case TraceLevel_Normal:
- return RGB(133, 124, 129);
- break;
- case TraceLevel_Warning:
- return RGB(255, 0, 0);
- break;
- case TraceLevel_Exception:
- return RGB(255, 0, 0);
- break;
- case TraceLevel_Debug:
- return RGB(19, 127, 140);
- break;
- }
-
- return RGB(0, 0, 0);
- }
-
- //字符判断
- bool EfficacyUrlChar(TCHAR chChar)
- {
- //特殊字符
- if (chChar == TEXT('.')) return true;
- if (chChar == TEXT('=')) return true;
- if (chChar == TEXT('+')) return true;
- if (chChar == TEXT('?')) return true;
- if (chChar == TEXT('#')) return true;
- if (chChar == TEXT('%')) return true;
- if (chChar == TEXT('/')) return true;
- if (chChar == TEXT(':')) return true;
- if (chChar == TEXT('&')) return true;
-
- //字符范围
- if ((chChar >= TEXT('a')) && (chChar <= TEXT('z'))) return true;
- if ((chChar >= TEXT('A')) && (chChar <= TEXT('Z'))) return true;
- if ((chChar >= TEXT('0')) && (chChar <= TEXT('9'))) return true;
-
- return false;
- }
-
- //地址判断
- bool EfficacyUrlString(LPCTSTR pszUrl)
- {
- for (WORD i = 0; i < wcslen(pszUrl); i++)
- {
- if (!EfficacyUrlChar(pszUrl[i])) return false;
- }
-
- return true;
- }
-
- //插入字串
- bool CTraceServiceControl::InsertString(LPCTSTR pszString, CHARFORMAT2& CharFormat)
- {
- if (GetTextLength() >= 1024 * 512)
- OnClearAll();
-
- //插入消息
- //变量定义
- bool bResumeSelect;
- CHARRANGE CharRange;
-
- //保存状态
- SetSel(-1L, -1L);
- GetSel(CharRange.cpMin, CharRange.cpMax);
- bResumeSelect = (CharRange.cpMax != CharRange.cpMin);
-
- //搜索变量
- LPCTSTR pszHttp = TEXT("http://");
- const INT nHttpLength = lstrlen(pszHttp);
- const INT nStringLength = lstrlen(pszString);
-
- //索引定义
- INT nStringStart = 0;
- INT nStringPause = 0;
-
- //字符解释
- for (INT i = 0; i < nStringLength; i++)
- {
- //变量定义
- INT nUrlPause = i;
-
- //地址判断
- if (((i + nHttpLength) < nStringLength) && (memcmp(&pszString[i], pszHttp, nHttpLength * sizeof(TCHAR)) == 0))
- {
- //设置索引
- nUrlPause = i + nHttpLength;
-
- //地址搜索
- while (nUrlPause < nStringLength)
- {
- //字符判断
- if (EfficacyUrlChar(pszString[nUrlPause]) == true)
- {
- nUrlPause++;
- continue;
- }
-
- break;
- }
- }
-
- //终止字符
- if (nUrlPause <= (i + nHttpLength)) nStringPause = (i + 1);
-
- //插入字符
- if ((i == (nStringLength - 1)) || (nUrlPause > (i + nHttpLength)))
- {
- //普通字符
- if (nStringPause > nStringStart)
- {
- //获取缓冲
- CString strNormalString;
- LPTSTR pszNormalString = strNormalString.GetBuffer(nStringPause - nStringStart + 1);
-
- //拷贝字符
- pszNormalString[nStringPause - nStringStart] = 0;
- CopyMemory(pszNormalString, &pszString[nStringStart], (nStringPause - nStringStart) * sizeof(TCHAR));
-
- //释放缓冲
- strNormalString.ReleaseBuffer();
-
- //插入消息
- SetSel(-1L, -1L);
- SetWordCharFormat(CharFormat);
- ReplaceSel((LPCTSTR)strNormalString);
- }
-
- //连接地址
- if (nUrlPause > (i + nHttpLength))
- {
- //获取缓冲
- CString strUrlString;
- LPTSTR pszUrlString = strUrlString.GetBuffer((nUrlPause - i) + 1);
-
- //拷贝字符
- pszUrlString[nUrlPause - i] = 0;
- CopyMemory(pszUrlString, &pszString[i], (nUrlPause - i) * sizeof(TCHAR));
-
- //释放缓冲
- strUrlString.ReleaseBuffer();
-
- //构造格式
- CHARFORMAT2 CharFormatHyper;
- CharFormatHyper = CharFormat;
-
- //效验地址
- if (EfficacyUrlString(strUrlString) == true)
- {
- CharFormatHyper.dwMask |= CFM_LINK;
- CharFormatHyper.dwEffects |= CFE_LINK;
- }
-
- //插入消息
- SetSel(-1L, -1L);
- SetWordCharFormat(CharFormatHyper);
- ReplaceSel((LPCTSTR)strUrlString);
- }
-
- //设置索引
- nStringStart = __max(i, nUrlPause);
- }
-
- //设置索引
- i += (nUrlPause - i);
- }
-
- //状态设置
- if (bResumeSelect == true) SetSel(CharRange);
- else PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
-
- return true;
- }
-
- //回调函数
- //////////////////////////////////////////////////////////////////////////
- //加载回调
- DWORD CALLBACK CTraceServiceControl::LoadCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb)
- {
- return 0;
- }
-
- //保存回调
- DWORD CALLBACK CTraceServiceControl::SaveCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb)
- {
- return 0;
- }
-
- //菜单命令
- //////////////////////////////////////////////////////////////////////////
- //删除信息
- VOID CTraceServiceControl::OnClearAll()
- {
- SetWindowText(NULL);
- }
-
- //全部选择
- VOID CTraceServiceControl::OnSelectAll()
- {
- __super::SetSel(0, __super::GetTextLength());
- }
-
- //拷贝字符
- VOID CTraceServiceControl::OnCopyString()
- {
- __super::Copy();
- }
-
- //保存信息
- VOID CTraceServiceControl::OnSaveString()
- {
- CFileDialog dlg(FALSE, TEXT("*.txt"), NULL, 4 | 2, TEXT("信息|*.txt||"));
- if (dlg.DoModal() == IDOK)
- {
- CString m_filename = dlg.GetPathName();
- CString strInput;
- GetWindowText(strInput);
-
- CFile file(m_filename, CFile::modeCreate | CFile::modeWrite);
- file.Write(strInput, strInput.GetLength());
- file.Close();
- }
- }
-
- //删除字符
- VOID CTraceServiceControl::OnDeleteString()
- {
- ReplaceSel(NULL, true);
- }
-
- //消息映射
- //////////////////////////////////////////////////////////////////////////
- //建立消息
- INT CTraceServiceControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- return __super::OnCreate(lpCreateStruct);
- }
-
- //右键消息
- VOID CTraceServiceControl::OnRButtonDown(UINT nFlags, CPoint point)
- {
- CMenu menu;
- ClientToScreen(&point);
-
- menu.CreatePopupMenu();
-
- CHARRANGE sl;
- GetSel(sl);
- menu.AppendMenu(MF_STRING | (sl.cpMax != sl.cpMin) ? 0 : MF_DISABLED | MF_GRAYED, IDM_MENU0, TEXT("复制(&C)\tCtrl+C"));
- menu.AppendMenu(MF_STRING | (GetTextLength() > 0 && sl.cpMax - sl.cpMin < GetTextLength()) ? 0 : MF_DISABLED | MF_GRAYED, IDM_MENU1, TEXT("全选(&A)\tCtrl+A"));
- menu.AppendMenu(MF_STRING | (false) ? 0 : MF_DISABLED | MF_GRAYED, IDM_MENU2, TEXT("删除(&D)"));
- menu.AppendMenu(MF_STRING | (GetTextLength() > 0) ? 0 : MF_DISABLED | MF_GRAYED, IDM_MENU3, TEXT("清除信息"));
- menu.AppendMenu(MF_SEPARATOR, 0);
- menu.AppendMenu(MF_STRING | (GetTextLength() > 0) ? 0 : MF_DISABLED | MF_GRAYED, IDM_MENU4, TEXT("保存信息..."));
-
- TrackPopupMenu(menu.m_hMenu, nFlags, point.x, point.y, 0, m_hWnd, NULL);
- }
-
- //追踪消息
- LRESULT CTraceServiceControl::OnTraceServiceMessage(WPARAM wParam, LPARAM lParam)
- {
- return 0;
- }
|