[C++]——同步異步日志系統(3)

同步異步日志系統

  • 一、日志系統框架設計
    • 1.1模塊劃分
      • 1.1.1 日志等級模塊
      • 1.1.2 日志消息模塊
      • 1.1.3 日志消息格式化模塊
      • 1.1.4 日志落地模塊(日志落地的方向是工廠模式)
      • 1.1.5 日志器模塊(日志器的生成是建造者模式)
      • 1.1.6 異步線程模塊(日志的輸出是用宏完成的代理模式)
      • 1.1.7 單例的日志器管理模塊(單例模式實現對日志器的管理)
    • 1.2 模塊關系圖
  • 二、代碼設計
    • 2.1 實用類設計

日志系統:
作用:將一條消息,進行格式化為指定格式的字符串后,寫入到指定位置

  1. 日志要寫入指定位置(標準輸出,指定文件, 滾動文件等等是可擴展得)
    日志系統需要支持將日志消息落地到不同的位置—多落地方向
  2. 日志寫入指定位置,支持不同的寫入方式(同步,異步)
    同步:業務線程自己負責日志的寫入(流程簡單,但是有可能會因為阻塞導致效率降低) 異步:業務線程將日志放入緩沖區內存,讓其他異步線程負責將日志寫入指定位置
  3. 日志輸出以日志器為單位,支持多日志器(不同的項目組有不同的輸出策略)

一、日志系統框架設計

本項?實現的是?個多?志器?志系統,主要實現的功能是讓程序員能夠輕松的將程序運??志信息落地到指定的位置,且?持同步異步兩種?式的?志落地?式。

1.1模塊劃分

1.1.1 日志等級模塊

枚舉出日志分為多少個等級—對不同的日志有不同等級標記–以便于控制輸出

  • OFF:關閉
  • DEBUG:調試,調試時的關鍵信息輸出。
  • INFO:提示,普通的提?型?志信息。
  • WARN:警告,不影響運?,但是需要注意?下的?志。
  • ERROR:錯誤,程序運?出現錯誤的?志。
  • FATAL:致命,?般是代碼異常導致程序?法繼續推進運?的?志。

1.1.2 日志消息模塊

封裝一條日志所需的各種要素(時間,線程ID,文件名,行號,日志等級,消息主體…)

  • 時間:描述本條?志的輸出時間。
  • 線程ID:描述本條?志是哪個線程輸出的。
  • ?志等級:描述本條?志的等級。
  • ?志數據:本條?志的有效載荷數據。
  • ?志?件名:描述本條?志在哪個源碼?件中輸出的。
  • ?志?號:描述本條?志在源碼?件的哪??輸出的。

1.1.3 日志消息格式化模塊

按照指定的格式,對于日志消息中關鍵要素進行組織,最終得到一個指定格式的字符串

系統默認的輸出格式: [%d{%H:%M:%S}]%T[%t]%T[%p]%T[%c]%T%f:%l%T%m%n
[12:38:45] [12345678] [FATAL] [root] main.c:178 套接字創建失敗…\n

  • %d{%H:%M:%S}:表??期時間,花括號中的內容表示日期時間的格式。
  • %T:表?制表符縮進。
  • %t:表?線程ID。%p:表??志級別。
  • %c:表??志器名稱,不同的開發組可以創建??的?志器進??志輸出,?組之間互不影響。
  • %f:表??志輸出時的源代碼?件名。
  • %l:表??志輸出時的源代碼?號。
  • %m:表?給與的?志有效載荷數據 。
  • %n:表?換行。
  • 設計思想:設計不同的?類,不同的?類從?志消息中取出不同的數據進?處理。

1.1.4 日志落地模塊(日志落地的方向是工廠模式)

決定了?志的落地?向,以什么方式輸出。

  • 標準輸出:表?將?志進?標準輸出的打印。
  • ?志?件輸出:表?將?志寫?指定的?件末尾。
  • 滾動?件輸出:當前以?件??進?控制,當?個?志?件??達到指定??,則切換下?個?件進?輸出 。
  • 后期,也可以擴展遠程?志輸出,創建客?端,將?志消息發送給遠程的?志分析服務器。
  • 設計思想:設計不同的?類,不同的?類控制不同的?志落地?向。

1.1.5 日志器模塊(日志器的生成是建造者模式)

對上邊幾個模塊的整合,??通過?志器進??志的輸出,有效降低??的使? 難度。
?志消息落地模塊對象,?志消息格式化模塊對象,?志輸出等級

  • 同步日志器模塊—完成日志的同步輸出功能。
  • 異步日志器模塊—完成日志的異步輸出功能(將日志消息發送到日志緩沖器內存)

1.1.6 異步線程模塊(日志的輸出是用宏完成的代理模式)

負責異步日志的實際落地輸出功能

  • 實現對?志的異步輸出功能,??只需要將輸出?志任務放?任務池,異步線程負責?志的落地輸出功能,提供了更加?效的?阻塞的?志輸出。

1.1.7 單例的日志器管理模塊(單例模式實現對日志器的管理)

為了方便管理,可以在程序的任意位置使用日志器,我設置一個單例對象。對日志進行全局的管理,以便于能夠在項目的任何位置獲取指定的日志器進行日志輸出。

  • 為了降低項?開發的?志耦合,不同的項?組可以有??的?志器來控制輸出格式以及落地?向,因此本項?是?個多?志器的?志系統。
  • 管理模塊就是對創建的所有?志器進?統?管理。并提供?個默認?志器,提供標準輸出的?志輸出。

1.2 模塊關系圖

在這里插入圖片描述
通過模塊關系圖,能夠簡單快速的了解模塊之間的關系。

二、代碼設計

2.1 實用類設計

提前完成一些功能和接口。

  1. 首先需要把架子搭起來,功能先聲明好。
//  通?功能類,與業務?關的功能實現
//  1. 獲取系統時間
//  2. 判斷文件是否存在
//  3. 獲取?件所在?錄的路徑
//  4. 創建?錄
//靜態接口可以直接使用,不需要實例化對象
#include <iostream>
namespace logsLearn {namespace util{//日期類class Data{public://獲取系統時間static time_t now();};//文件類class File{public://判斷文件是否存在static bool exists(const std::string &pathname);//獲取?件所在?錄的路徑static std::string path(const std::string &pathname);//創建?錄static void createDirectory(const std::string &pathname);};} 
}
  1. 其次在實現各個功能。
// 條件編譯,防止頭文件重復包含
#ifndef __M_UTIL_H__
#define __M_UTIL_H__
//  通?功能類,與業務?關的功能實現
//  1. 獲取系統時間
//  2. 判斷文件是否存在
//  3. 獲取?件所在?錄的路徑
//  4. 創建?錄
#include <iostream>
#include <ctime>
#include <sys/stat.h>
#include <sys/types.h>
namespace logsLearn
{namespace util{// 日期類class Data{public:// 獲取系統時間static time_t now(){// 返回當前系統時間return time(nullptr);}};// 文件類class File{public:// 判斷文件是否存在static bool exists(const std::string &pathname){ // 定義了一個stat的結構體變量struct stat st;// 獲取文件信息不成功,進入條件if (stat(pathname.c_str(), &st) < 0){return false;}return true;}// 獲取?件所在?錄的路徑static std::string path(const std::string &pathname){ if (pathname.empty()) return ".";// pos是當前查找的最后“/\\”的位置size_t pos = pathname.find_last_of("/\\");// 沒有找到"/\\"if (pos == std::string::npos)return ".";// 找到了,返回路徑,左閉右開原則,要想包括pos位置,需要加1return pathname.substr(0, pos + 1);}// 創建?錄static void createDirectory(const std::string &pathname){ // pos找到的位置,idx是存的位置size_t pos = 0, idx = 0;while (idx < pathname.size()){// 遍歷路徑每找到最后一個"/\\"創建文件夾size_t pos = pathname.find_first_of("/\\", idx);if (pos == std::string::npos){ // 創建文件夾,pathname.c_str()表示路徑名,0777表示權限mkdir(pathname.c_str(), 0777);}// 前面的路徑std::string parent_dir = pathname.substr(0, pos + 1);// 文件是否存在if (exists(parent_dir) == true){idx = pos + 1;continue;}// 文件不存在,創建文件mkdir(parent_dir.c_str(), 0777);idx = pos + 1;}}};}
}
#endif
  1. 我們每次編寫完一個模塊后,要對其進行單元測試,確保程序的準確性。
//測試代碼
#include "util.hpp"
int main()
{//工具類測試std::cout<<logsLearn::util::Data::now()<<std::endl;std::string pathname="./abc/bcd/a.txt";std::cout<<pathname;logsLearn::util::File::createDirectory(logsLearn::util::File::path(pathname));return 0;
}
  1. 界面展示
    make運行之前
    在這里插入圖片描述
    make運行之后
    在這里插入圖片描述
    補充:
    1.stat函數
    stat函數是用于獲取文件信息,比如文件權限,文件類型信息等等。
    函數的聲明:
    int stat(const char *pathname, struct stat *buf);
    參數說明:
    pathname:表示文件路徑名
    buf:用于保存獲取到的文件屬性信息(這是一個傳出參數)
    返回值說明:成功返回0,失敗返回-1并設置errno
    2.mkdir函數
    mkdir函數用于創建一個新的目錄。如果指定的目錄已經存在,并且沒有設置相應的標志來允許覆蓋或忽略已存在的目錄,則函數會失敗;它允許用戶為新創建的目錄設置權限,這些權限決定了誰可以訪問該目錄。
    函數聲明:
    int mkdir(const char * pathname , mode_t mode);
    參數說明:
    pathname(const char * ):指向以null結尾的字符串的指針,該字符串指定了要創建的目錄的路徑。路徑可以是相對路徑或絕對路徑。
    mode(mode_t):指定新目錄的權限。這些權限位使用八進制數表示(例如,0755),并且會受進程的文件模式創建掩碼(umask)的影響。最終權限是請求權限與umask的補碼的邏輯與結果。通常,mode參數包括文件所有者(user)、組(group)和其他人(other)的讀(r)、寫(w)和執行(x)權限的組合。
    返回值說明:成功時,返回0;失敗時,返回-1,并設置全局變量errno以指示錯誤類型(如EACCES表示權限不足,EEXIST表示目錄已存在等)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/43015.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/43015.shtml
英文地址,請注明出處:http://en.pswp.cn/web/43015.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android12上實現雙以太網卡共存同時訪問外網

具體實現如下&#xff1a; 修改main 表優先級到9999&#xff0c; 作用&#xff1a;eth0 eth1 訪問 不去teardown 低分數網線 diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 418e…

Ubuntu 22.04 設置swap交換空間

經常爆內存&#xff0c;導致很多應用沒有辦法一直正常運行&#xff0c;可以通過設置swap來緩解一下&#xff0c;雖然和內存的速度無法媲美&#xff0c;但是能一定程度緩解一下問題。 一、查看當前分區 查看當前系統的swap大小 free -m 二、關閉現有的swap分區 將/etc/fstab…

CUDA Kernel調試與優化--背景知識掃盲(LLM生成)

CUDA Kernel調試與優化–背景知識掃盲(LLM生成) 對于使用CUDA進行調試與性能優化&#xff0c;官方提供了豐富的參考資料和工具。以下是一些關鍵資源&#xff0c;可以幫助你更好地調試和優化CUDA代碼&#xff1a; 官方文檔和指南 CUDA Toolkit Documentation URL: CUDA Toolk…

強化學習總結(有具體代碼實現)

文章目錄 第一部分 強化學習基礎第1章 強化學習概述1.1 強化學習概念1.2 強化學習的環境1.3 強化學習的目標1.4 強化學習的數據 第2章 多臂老虎機問題&#xff08;MAB問題&#xff09;2.1 問題描述2.1.1 問題定義2.1.2 形式化描述2.1.3 累積懊悔2.1.4 估計期望獎勵 2.2 解決方法…

CSS 【詳解】CSS 函數(含 calc,min,max,clamp,cubic-bezier,env,steps 等)

函數描述CSS 版本attr()返回選擇元素的屬性值。2calc()允許計算 CSS 的屬性值&#xff0c;比如動態計算長度值。3cubic-bezier()定義了一個貝塞爾曲線(Cubic Bezier)。3hsl()使用色相、飽和度、亮度來定義顏色。3hsla()使用色相、飽和度、亮度、透明度來定義顏色。3linear-grad…

Bert 變種, T5模型

NLP-預訓練模型-2019-NLU&#xff1a;DistilBERT【 BERT模型壓縮】【模型大小減小了40%&#xff08;66M&#xff09;&#xff0c;推斷速度提升了60%&#xff0c;但性能只降低了約3%】_distillbert-CSDN博客 https://zhuanlan.zhihu.com/p/673535548 大語言模型系列-T5_t5模型…

【機器學習】必會數學知識:一文掌握數據科學核心數學知識點(上),值得收藏~

核心數學知識點 1、引言2、數據科學必會數學知識2.1 線性代數2.2 微積分2.3 概率論2.4 數理統計2.5 隨機過程2.6 數據分布2.7 貝葉斯統計2.8 線性回歸2.9 邏輯回歸2.10 矩陣分解2.11 主成分分析&#xff08;PCA&#xff09;2.12 奇異值分解&#xff08;SVD&#xff09; 3、總結…

【Git 入門】初始化配置與新建倉庫

文章目錄 前言配置git新建倉庫倉庫的概念創建倉庫命令總結前言 在現代軟件開發中,版本控制系統已經成為了不可或缺的工具。其中,Git 是最為廣泛使用的版本控制系統之一。Git 不僅可以幫助我們管理和跟蹤代碼的變化,還可以方便地與他人協作。本文將介紹 Git 的基礎知識,包括…

【人工智能大語言模型技術發展研究報告 2024】

文末?有福利&#xff01; 人工智能作為引領新一輪科技產業革命的戰略性技術和新質生產力重要驅動力&#xff0c;正在引發經濟、社會、文化等領域的變革和重塑&#xff0c;2023 年以來&#xff0c;以 ChatGPT、GPT-4 為代表的大模型技術的出臺&#xff0c;因其強大的內容生成及…

提升教師健康,聚焦智慧校園人事系統的職工體檢功能

智慧校園人事管理系統內置的職工體檢管理&#xff0c;是專為教職員工設計的一項健康管理創新實踐&#xff0c;巧妙融合先進信息技術&#xff0c;致力于為教職工提供更加便捷、易懂且持續性的健康檢查與管理支持。該服務從多個維度出發&#xff0c;全面呵護教職工的身心健康。 該…

給你的博客加上評論區

一個網站如果有評論功能&#xff0c;可以更好的和讀者互動。VuePress 也有很多評論插件&#xff0c;這里簡單介紹下&#xff0c;最后介紹本站所使用的 Twikoo。 大部分評論插件都是使用的 Github 或 Gitee 的 issue 功能&#xff0c;也就是用 issue 去存儲評論&#xff1b;而 …

自然語言處理(NLP)與大語言模型(LLM) 主要差異

一、簡述 NLP 和 LLM 技術是大規模分析和生成人類語言的核心。隨著它們的日益普及&#xff0c;區分 LLM 與 NLP 變得越來越重要。 NLP 包含一套用于理解、操縱和生成人類語言的算法。自 20 世紀 50 年代誕生以來&#xff0c;NLP 已發展到分析文本關系的階段。它使用詞性標注、命…

腳本實現保留文本中特定字符之后的字符串

#目的背景 原始txt文本如下圖 目的是為了去除序號&#xff0c;每行只單獨呈現域名 手工刪除漫長又麻煩&#xff0c;使用腳本快捷些 代碼實現邏輯&#xff1a; 1.使用open函數打開文本&#xff0c;之后用變量lines存儲文本的所有行&#xff0c;使用for循環&#xff0c;讓變量te…

暑假學習計劃怎么做 用待辦計劃軟件安排更科學

暑期來臨&#xff0c;無論是學生還是老師&#xff0c;做好暑期計劃都至關重要。記得去年暑假&#xff0c;我給自己定下了閱讀十本書的目標&#xff0c;卻因為缺乏明確的計劃&#xff0c;最后只草草讀完了兩本。而今年&#xff0c;我決定嘗試一種新的方式——使用待辦計劃軟件來…

大學生數學競賽教程(蒲和平)

大學生數學競賽教程(蒲和平) https://pan.baidu.com/s/1ytcIbVcZpof9WM1xa2dDfA 提取碼: kf2r 源文件來自于&#xff1a;大學生數學競賽教程【蒲和平】

谷粒商城實戰筆記-24-分布式組件-SpringCloud Alibaba-Nacos配置中心-命名空間與配置分組

文章目錄 一&#xff0c;命名空間1&#xff0c;簡介1.1&#xff0c;命名空間的主要功能和特點1.2&#xff0c;使用場景1.3&#xff0c;如何指定命名空間 2&#xff0c;命名空間實戰2.1&#xff0c;環境隔離2.2&#xff0c;服務隔離 二&#xff0c;配置集三&#xff0c;配置集ID…

【數據基礎】— 基于Go1.19的站點模板爬蟲的實現

目錄 1. 定義目標站點 2. 使用Go的庫 3. 發送HTTP請求 4. 解析HTML并提取數據 5. 存儲數據 6. 并發處理 示例代碼 基于Go 1.19的站點模板爬蟲實現通常涉及幾個關鍵步驟&#xff1a;定義目標站點、解析HTML頁面、提取所需數據、存儲數據以及可能的并發處理。下面我將詳細…

js原型和類---prototype,__proto__,new,class

原型和原型鏈 在js中&#xff0c;所有的變量都有原型&#xff0c;原型也可以有原型&#xff0c;原型最終都指向Object 什么是原型 在js中&#xff0c;一個變量被創建出來&#xff0c;它就會被綁定一個原型&#xff1b;比如說&#xff0c;任何一個變量都可以使用console.log打…

PostgreSQL 中如何實現數據的增量更新和全量更新的平衡?

文章目錄 一、增量更新與全量更新的概念增量更新全量更新 二、考慮的因素1. 數據量2. 數據更改的頻率和規模3. 數據一致性要求4. 系統性能和資源利用5. 業務邏輯和流程 三、解決方案&#xff08;一&#xff09;混合使用增量更新和全量更新&#xff08;二&#xff09;使用臨時表…

暑期旅游季必備,用這款客服神器應對爆棚的客流咨詢

解決暑期旅游客流高峰問題 暑期是旅游高峰季節&#xff0c;客流量劇增&#xff0c;客戶咨詢紛至沓來。在這個時候&#xff0c;如何高效處理客戶的咨詢成為每家旅游機構和景點不可忽視的挑戰。 聊天寶快捷回復助手是一款強大的工具&#xff0c;可幫助企業在客流高峰期快速回復客…