日志

日志

一,需求
软件上线后,出现问题再去排查,看日志是第一步,那就需要一个专业的日志框架,这里推荐spdlog,多线程安全,使用简单,基本功能都具备。
二, 使用
1, 将源码放到工程目录下。
https://github.com/gabime/spdlog

2,写一个单列 来配置日志和调用日志。

#pragma once

#include <QCoreApplication>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/async.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <iostream>
#include <QDateTime>

class XLogger
{
public:
    static XLogger* getInstance()
    {
        static XLogger xlogger;
        return &xlogger;
    }

    std::shared_ptr<spdlog::logger> getLogger()
    {
        return m_logger;
    }
private:
    XLogger()
    {
        try
        {
            //日志等级 可以从配置文件读取
            spdlog::level::level_enum level = spdlog::level::debug;
            const QString logger_name = QCoreApplication::applicationDirPath() + "\\log\\" +QDateTime::currentDateTime().toString("yyyy-MM-dd") + ".log";

            auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
            //文件大小 限制,日志命名
            auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logger_name.toStdString(), 100 * 1024 * 1024, 1000);

            console_sink->set_pattern("%Y-%m-%d %H:%M:%S.%f [%l] [%@] %v");
            file_sink->set_pattern("%Y-%m-%d %H:%M:%S.%f [%l] [%@] %v");

            //这里即输出到控制台 也写到文件
            console_sink->set_level(level);
            file_sink->set_level(level);

            std::vector<spdlog::sink_ptr> sinks;
            sinks.push_back(console_sink);
            sinks.push_back(file_sink);

            m_logger = std::make_shared<spdlog::logger>("multi-sink", begin(sinks), end(sinks));
            m_logger->set_level(spdlog::level::trace);
            m_logger->flush();
        }
        catch (const spdlog::spdlog_ex& ex)
        {
            std::cout << "Log initialization failed: " << ex.what() << std::endl;
        }
    }

    ~XLogger()
    {
        spdlog::drop_all();
    }

    void* operator new(size_t size)
    {}

    XLogger(const XLogger&) = delete;
    XLogger& operator=(const XLogger&) = delete;

private:
    std::shared_ptr<spdlog::logger> m_logger;
};

#define LOGT(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::trace, __VA_ARGS__)
#define LOGD(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::debug, __VA_ARGS__)
#define LOGI(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::info, __VA_ARGS__)
#define LOGW(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::warn, __VA_ARGS__)
#define LOGE(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::err, __VA_ARGS__)

3, 使用的时候 直接使用宏即可。


//没有参数
LOGI("Camera close!");

//携带参数
int index=0;
LOGI("{} close!",index);

发表回复