改写SimpleLogger支持C++10

本文介绍了一个轻量级的C++日志记录库SimpleLogger,该库利用了C++11的一些特性,提供了初始化、日志级别设置、日期时间前缀等功能,并详细解释了如何在项目中进行配置和使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SimpleLogger这个轻量级的log记录库,里面用到了一些c++11的一些特性,我要在项目中使用,我的项目是基于c++10的,所以对它的内容做了一些修改。

未修改的SimpleLogger:https://github.com/juzzlin/SimpleLogger

simple_logger.hpp

// MIT License
//
// Copyright (c) 2018 Jussi Lind <jussi.lind@iki.fi>
//
// https://github.com/juzzlin/SimpleLogger
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef JUZZLIN_LOGGER_HPP
#define JUZZLIN_LOGGER_HPP

#include <cstdio>
#include <memory>
#include <sstream>

namespace juzzlin {

/*!
 * Example initialization:
 *
 * using juzzlin::L;
 *
 * L::init("myLog.txt");
 *
 * Example logging:
 *
 * L().info() << "Initialization finished.";
 * L().error() << "Foo happened!";
 */
typedef class Logger
{
public:

    enum Level
    {
        Trace = 0,
        Debug,
        Info,
        Warning,
        Error,
        Fatal
    };

    //! Constructor.
    Logger();

    //! Destructor.
    ~Logger();

    /*! Initialize the logger.
     *  \param filename Log to filename. Disabled if empty.
     *  \param append The existing log will be appended if true.
     *  Throws on error. */
    static void init(std::string filename, bool append = false);

    //! Enable/disable echo mode.
    //! \param enable Echo everything if true. Default is false.
    static void enableEchoMode(bool enable);

    //! Enable/disable date and time prefix.
    //! \param enable Prefix with date and time if true. Default is true.
    static void enableDateTime(bool enable);

    //! Set the logging level.
    //! \param level The minimum level. Default is Info.
    static void setLoggingLevel(Level level);

    //! Set custom symbol for the given logging level.
    //! \param level The level.
    //! \param symbol The symbol outputted for the messages of this level.
    static void setLevelSymbol(Level level, std::string symbol);

    //! Get stream to the trace log message.
    std::ostringstream & trace();

    //! Get stream to the debug log message.
    std::ostringstream & debug();

    //! Get stream to the info log message.
    std::ostringstream & info();

    //! Get stream to the warning log message.
    std::ostringstream & warning();

    //! Get stream to the error log message.
    std::ostringstream & error();

    //! Get stream to the fatal log message.
    std::ostringstream & fatal();

private:

    //Logger(const Logger & r) = delete;
    //Logger & operator=(const Logger & r) = delete;

    class Impl;
    std::unique_ptr<Impl> m_impl;
}L;
} // juzzlin

#endif // JUZZLIN_LOGGER_HPP

simple_logger.cpp

#include "stdafx.h"
// MIT License
//
// Copyright (c) 2018 Jussi Lind <jussi.lind@iki.fi>
//
// https://github.com/juzzlin/SimpleLogger
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#define _CRT_SECURE_NO_WARNINGS

#include "simple_logger.hpp"

#include <ctime>
#include <fstream>
#include <iostream>
#include <map>
#include <stdexcept>

#ifdef Q_OS_ANDROID
#include <QDebug>
#else
#include <cstdio>
#endif

namespace juzzlin {

class Logger::Impl
{
public:

    Impl();

    ~Impl();

    std::ostringstream & trace();

    std::ostringstream & debug();

    std::ostringstream & info();

    std::ostringstream & warning();

    std::ostringstream & error();

    std::ostringstream & fatal();

    static void enableEchoMode(bool enable);

    static void enableDateTime(bool enable);

    static void setLevelSymbol(Logger::Level level, std::string symbol);

    static void setLoggingLevel(Logger::Level level);

    static void init(std::string filename, bool append);

    void flush();

    std::ostringstream & getStream(Logger::Level level);

    void prefixDateTime();

	typedef std::map<Logger::Level, std::string> SymbolMap;
	typedef std::map<Logger::Level, std::ostream *> StreamMap;

	static SymbolMap CreateSymbolMap()
	{
		SymbolMap tmp_map;
		tmp_map[Logger::Level::Trace] = "T:";
		tmp_map[Logger::Level::Debug] =  "D:";
		tmp_map[Logger::Level::Info] = "I:";
		tmp_map[Logger::Level::Warning] = "W:";
		tmp_map[Logger::Level::Error] = "E:";
		tmp_map[Logger::Level::Fatal] = "F:";
		return tmp_map;
	}

	static StreamMap CreateStreamMap()
	{
		StreamMap tmp_map;
		tmp_map[Logger::Level::Trace] =  &std::cout;
		tmp_map[Logger::Level::Debug] =   &std::cout;
		tmp_map[Logger::Level::Info] =  &std::cout;
		tmp_map[Logger::Level::Warning] = &std::cerr;
		tmp_map[Logger::Level::Error] = &std::cerr;
		tmp_map[Logger::Level::Fatal] = &std::cerr;
		return tmp_map;
	}

private:

    static bool m_echoMode;

    static bool m_dateTime;

    static Logger::Level m_level;

    static std::ofstream m_fout;

	
    static SymbolMap m_symbols;

    static StreamMap m_streams;

    Logger::Level m_activeLevel;

    std::ostringstream m_oss;
};

bool Logger::Impl::m_echoMode = true;

bool Logger::Impl::m_dateTime = true;

Logger::Level Logger::Impl::m_level = Logger::Level::Info;

std::ofstream Logger::Impl::m_fout;


// Default level symbols
Logger::Impl::SymbolMap Logger::Impl::m_symbols = Logger::Impl::CreateSymbolMap();
// Default streams
Logger::Impl::StreamMap Logger::Impl::m_streams = Logger::Impl::CreateStreamMap();

Logger::Impl::Impl()
{
	

	m_activeLevel = Logger::Level::Info;
}

Logger::Impl::~Impl()
{
    flush();
}

void Logger::Impl::enableEchoMode(bool enable)
{
    Impl::m_echoMode = enable;
}

void Logger::Impl::enableDateTime(bool enable)
{
    Impl::m_dateTime = enable;
}

std::ostringstream & Logger::Impl::getStream(Logger::Level level)
{
    m_activeLevel = level;
    Impl::prefixDateTime();
    m_oss << Impl::m_symbols[level] << " ";
    return m_oss;
}

void Logger::Impl::setLevelSymbol(Level level, std::string symbol)
{
    Impl::m_symbols[level] = symbol;
}

void Logger::Impl::setLoggingLevel(Logger::Level level)
{
    Impl::m_level = level;
}

void Logger::Impl::prefixDateTime()
{
    if (Impl::m_dateTime)
    {
        time_t rawTime;
        time(&rawTime);
        std::string timeStr(ctime(&rawTime));
        timeStr.erase(timeStr.length() - 1);
        m_oss << "[" << timeStr << "] ";
    }
}

void Logger::Impl::flush()
{
    if (m_activeLevel < m_level)
    {
        return;
    }

    if (!m_oss.str().size())
    {
        return;
    }

    if (Impl::m_fout.is_open())
    {
        Impl::m_fout << m_oss.str() << std::endl;
        Impl::m_fout.flush();
    }

    if (Impl::m_echoMode)
    {
#ifdef Q_OS_ANDROID
        qDebug() << m_oss.str().c_str();
#else
        auto stream = Impl::m_streams[m_activeLevel];
        if (stream) {
            *stream << m_oss.str() << std::endl;
            stream->flush();
        }
#endif
    }
}

void Logger::Impl::init(std::string filename, bool append)
{
    if (!filename.empty())
    {
        Impl::m_fout.open(filename, append ? std::ofstream::out | std::ofstream::app : std::ofstream::out);
        if (!Impl::m_fout.is_open())
        {
            throw std::runtime_error("ERROR!!: Couldn't open '" + filename + "' for write.\n");
        }
    }
}

std::ostringstream & Logger::Impl::trace()
{
    return getStream(Logger::Level::Trace);
}

std::ostringstream & Logger::Impl::debug()
{
    return getStream(Logger::Level::Debug);
}

std::ostringstream & Logger::Impl::info()
{
    return getStream(Logger::Level::Info);
}

std::ostringstream & Logger::Impl::warning()
{
    return getStream(Logger::Level::Warning);
}

std::ostringstream & Logger::Impl::error()
{
    return getStream(Logger::Level::Error);
}

std::ostringstream & Logger::Impl::fatal()
{
    return getStream(Logger::Level::Fatal);
}

Logger::Logger()
    : m_impl(new Logger::Impl)
{
}

void Logger::init(std::string filename, bool append)
{
    Impl::init(filename, append);
}

void Logger::enableEchoMode(bool enable)
{
    Impl::enableEchoMode(enable);
}

void Logger::enableDateTime(bool enable)
{
    Impl::enableDateTime(enable);
}

void Logger::setLoggingLevel(Level level)
{
    Impl::setLoggingLevel(level);
}

void Logger::setLevelSymbol(Level level, std::string symbol)
{
    Impl::setLevelSymbol(level, symbol);
}

std::ostringstream & Logger::trace()
{
    return m_impl->trace();
}

std::ostringstream & Logger::debug()
{
    return m_impl->debug();
}

std::ostringstream & Logger::info()
{
    return m_impl->info();
}

std::ostringstream & Logger::warning()
{
    return m_impl->warning();
}

std::ostringstream & Logger::error()
{
    return m_impl->error();
}

std::ostringstream & Logger::fatal()
{
    return m_impl->fatal();
}

Logger::~Logger()
{

}

} // juzzlin

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值