首页 > 编程语言 >自己动手写一个C++日志库

自己动手写一个C++日志库

时间:2023-09-09 09:44:38浏览次数:48  
标签:std console log level oss C++ 动手 日志 logger

自己动手写一个C++日志库

logger.h

//
// Created by Fkkt on 2023/9/8.
//

#pragma once

#include <string>
#include <iostream>
#include <fstream>
#include <chrono>
#include <sstream>

namespace fkkt {

    class logger {
    public:

        enum log_level {
            D, // Debug
            I, // Info
            W, // Warning
            E  // Error
        };

        /**
         * Construct logger
         *
         * @param log_file_name log file name
         * @param default_console_log_level log level, see log_level
         * @param mode mode, default is append
         */
        explicit logger(const std::string &log_file_name = "app.log",
                        log_level default_console_log_level = D,
                        const std::ios_base::openmode &mode = std::ios_base::app);

        ~logger();

        /**
         * Set level of console, which will be print
         *
         * @param level log level, see log_level
         */
        void set_console_log_level(log_level level);

        template<typename... Args>
        void d(Args... args) {
            std::ostringstream oss;
            append(oss, args...);
            write(D, oss.str());
        }

        template<typename... Args>
        void i(Args... args) {
            std::ostringstream oss;
            append(oss, args...);
            write(D, oss.str());
        }

        template<typename... Args>
        void w(Args... args) {
            std::ostringstream oss;
            append(oss, args...);
            write(D, oss.str());
        }

        template<typename... Args>
        void e(Args... args) {
            std::ostringstream oss;
            append(oss, args...);
            write(D, oss.str());
        }

    private:
        std::ofstream log_file;
        log_level console_log_level;

        static std::string get_log_level(log_level level);

        static std::string get_current_time_stamp();

        void write(log_level level, const std::string &message);

        void append(std::ostringstream &oss) {}

        template<typename T, typename... Args>
        void append(std::ostringstream &oss, const T &first, Args... args) {
            oss << first;
            append(oss, args...);
        }

    };
}

logger.cpp

//
// Created by Fkkt on 2023/9/8.
//
#include "logger.h"
#include <iostream>
#include <ctime>
#include <iomanip>
#include <fstream>
#include <mutex>

namespace fkkt {
    logger::logger(const std::string &log_file_name,
                   log_level default_console_log_level,
                   const std::ios_base::openmode &mode) : console_log_level(default_console_log_level) {
        log_file.open(log_file_name, mode);
        if (!log_file.is_open()) {
            throw std::runtime_error("Failed to open log file: " + log_file_name);
        }
        std::ios::sync_with_stdio(false);
        set_console_log_level(W);
    }

    logger::~logger() {
        if (log_file.is_open()) {
            log_file.close();
        }
        std::ios::sync_with_stdio(true);
    }

    void logger::set_console_log_level(log_level level) {
        console_log_level = level;
    }

    std::string logger::get_log_level(log_level level) {
        switch (level) {
            case D:
                return "DEBUG";
            case I:
                return "INFO";
            case W:
                return "WARNING";
            case E:
                return "ERROR";
            default:
                return "UNKNOWN";
        }
    }

    std::string logger::get_current_time_stamp() {
        auto currentTime = std::chrono::system_clock::now();
        auto currentTimeT = std::chrono::system_clock::to_time_t(currentTime);
        auto timeInfo = *std::localtime(&currentTimeT);
        std::stringstream ss;
        ss << std::put_time(&timeInfo, "%Y-%m-%d %H:%M:%S");
        return ss.str();
    }

    void logger::write(log_level level, const std::string &message) {
        std::lock_guard<std::mutex> lock(std::mutex);
        std::string logMessage = get_current_time_stamp() + " [" + get_log_level(level) + "] " + message + "\n";
        if (level >= console_log_level) {
            std::cout << logMessage;
        }
        if (log_file.is_open()) {
            log_file << logMessage;
        }
    }

}

使用方法

#include "logger.h"

int main() {

    auto log = make_unique<fkkt::logger>("app.log", fkkt::logger::log_level::D, ios::in);
    log->set_console_log_level(fkkt::logger::D);
    log->d("Hello ", 10924);

    return 0;
}

标签:std,console,log,level,oss,C++,动手,日志,logger
From: https://www.cnblogs.com/imorning/p/cpp_log_utils.html

相关文章

  • C# 封装 C++的dll
    C#的程序引用C++的dll时,首先要保证两者基于的平台一致,比如都是x64,或者都是x86的程序,否者两者之间不能直接调用,然后,要保证两者的数据类型可以相互识别,相互通用。在此重点介绍几个常用的数据转换。C++的char*和char[]数组,对应到C#的string类型C++的Handle类型,一般是一个很......
  • mysql 开启cdc归档日志
    1、介绍mysql开启归档只需要在mysql的 my.ini 中添加几个配置即可(适用版本如下:)2、说明如下:#配置二进制日志,下面的路径logs文件夹需要提前建好log-bin=E:/mariadb-10.4.20-winx64/logs/mysql-bin.log#设置最大存储空间max-binlog-size=50000M#指定服务idser......
  • C++系列三:QT-Quick
    目录前言:理论:案例:前言:其实和我接触过的Flutter,有异曲同工之处。记住F1,其实就ok了。参考链接:官方、教程1、教程2、教程3、教程3理论:案例://main.cpp:QQmlApplicationEngineengine;engine.load(QUrl(QStringLiteral("qrc:/qt/qml/qtquickapplication1/main.qml")));if(e......
  • 使用NLog记录上位机操作日志
    在上位机中一些重要日志信息需要保存到日志中,比如登录信息,操作信息等。用于日志的库常用的有NLog、Log4Net等,相较而言NLog库配置简单,学习成本低。使用方法如下:1、NuGet下载安装NLog库;2、修改或创建配置文件,方法有两种,分别如下:方法1:创建一个“nlog.config”的配置文件(注意,文件......
  • 机器学习日志 新闻标题分类
    根据标题内容,分类有财经、彩票、房产、股票、家居、教育、科技、社会、时尚、时政、体育、星座、游戏、娱乐#导入必要的包importrandomimportjieba#处理中文fromsklearnimportmodel_selectionfromsklearn.naive_bayesimportMultinomialNBimportjoblibimportr......
  • C++的纯虚函数和抽象类
    在C++中,可以将虚函数声明为纯虚函数,语法格式为:virtual返回值类型函数名(函数参数)=0;纯虚函数没有函数体,只有函数声明,在虚函数声明的结尾加上=0,表明此函数为纯虚函数。最后的=0并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”。包含纯虚函数的类称为抽......
  • 用现代C++写一个python的简易型list
    std::variant介绍:en.cppreference.com/w/cpp/utility/variant  通过泛型模板(仅提供了int,double,string三种类型的存储),实现了append,pop,front,back,size等方法,并且通过重载运算符实现了对负数索引的访问。#include<iostream>#include<vector>#include<variant>......
  • C++语言学习12
    STL算法组件STL算法库提供大量用途的函数(例如查找、排序、计数、操作),它们在元素范围上操作。注意范围定义为[first,last),其中last指代要查询或修改的最后元素的后一个元素。include不修改序列的操作调用函数之后,不会影响序列中本来元素的值all_of所有都满......
  • JAVA日志技术 & Logback
    前言为什么需要记录日志?我们不可能实时的24小时对系统进行人工监控,那么如果程序出现异常错误时要如何排查呢?并且系统在运行时做了哪些事情我们又从何得知呢?这个时候日志这个概念就出现了,日志的出现对系统监控和异常分析起着至关重要的作用一、日志概括1.了解日志框架JAVA在早期的日......
  • 项目八股[日志系统]
    日志系统涉及到的C++特性语法用了一个锁+两个条件变量,跟线程池不一样只用了一个锁一个条件变量C++11提供的condition_variable类是一个同步原语,它能够阻塞一个或者多个线程,直到另一线程修改共享变量并通知condition_variable。对比POSIX的pthread_cond,pthread移植性好,condi......