easylog

</pre><pre name="code" class="cpp"><pre name="code" class="plain">非常简单的日志系统,一个静态类提供一个写日志的接口WriteLog,该日志提供了log分类,用stream进行文件读写,避免printf操作不当引起的内存溢出。
代码流程:
1.构造函数中打开日志文件,虚构函数关闭文件。
2.围绕接口WriteLog提供不同类型的调用方式(使用宏定义日志类型)
3.具有回调,写入日志后的本地操作

不足:
1.打开文件在创建时,关闭文件在销毁时,这就意味着文件在运行过程中一直是被占用的状态,如果程序运行过程中崩溃或者非正常关闭,会产生文件占用
2.所以的log输出在同一份文件中,对分类log查看非常不方便
3.没有日志关闭管理(方便debug,release版本发布)

使用场景:
对一些demo,小项目使用还是非常不错的


 
</pre><pre name="code" class="cpp"><p>
</p><p>//</p>//  EasyLog.h
//
//  Created by sollyu on 14/11/20.
//  Copyright (c) 2014年 sollyu. All rights reserved.
//

/**
 事例代码: 
     // 设置onLogChange回调函数
     EasyLog::GetInstance()->onLogChange = [=](EasyLog::LOG_LEVEL level, std::string logText) -> void
     {
        std::cout << level << " " << logText;
     };
 
     LOGI("i'm %s", "sollyu");          // 输出 INFO (只有 LOGI 不会打印所在行)
     LOGE("I'm " << "sollyu");          // 输出 ERROR (会打印所在行)
     LOG_DEBUG("i'm %s", "sollyu");     // 输出 DEBUG (会打印所在行)非常简单的日志系统,一个静态类提供一个写日志的接口WriteLog,该日志提供了log分类,用stream进行文件读写,避免printf操作不当引起的内存溢出。
     EasyLog::GetInstance()->WriteLog(EasyLog::LOG_DEBUG, "i'm %s", "sollyu");
 
 // 上面代码的执行结果
 2 [2014-11-26 11:10:54 LOG_INFO ] i'm sollyu
 4 [2014-11-26 11:10:54 LOG_ERROR] I'm sollyu (/Projects/EasyLog/EasyLog/main.cpp : main : 20 )
 1 [2014-11-26 11:10:54 LOG_DEBUG] i'm sollyu (/Projects/EasyLog/EasyLog/main.cpp : main : 21 )
 1 [2014-11-26 11:10:54 LOG_DEBUG] i'm sollyu
 
 */

#ifndef ___EasyLog_h
#define ___EasyLog_h

#include <string>
#include <sstream>
#include <fstream>
#include <functional>
#include <codecvt>
#include <iomanip>

#ifndef EASY_LOG_FILE_NAME
#  define EASY_LOG_FILE_NAME			"EasyLog.log"   /** 日志的文件名 */
#endif

#ifndef EASY_LOG_LINE_BUFF_SIZE
#  define EASY_LOG_LINE_BUFF_SIZE		1024            /** 一行的最大缓冲 */
#endif

#ifndef EASY_LOG_DISABLE_LOG
#  define EASY_LOG_DISABLE_LOG          0               /** 非0表示禁用LOG - 非0情况下依然会触发onLogChange */
#endif

#ifdef WIN32
#else
#   define  sprintf_s   sprintf
#   define  vsnprintf_s vsnprintf
#endif

/** 写日志方法 */
#define WRITE_LOG(LEVEL, FMT, ...) \
{ \
    std::stringstream ss; \
    ss << FMT; \
    if (LEVEL != EasyLog::LOG_INFO) \
    { \
        ss << " (" << __FILE__ << " : " << __FUNCTION__ << " : " << __LINE__ << " )"; \
    } \
    EasyLog::GetInstance()->WriteLog(LEVEL, ss.str().c_str(), ##__VA_ARGS__); \
}

//! 快速宏
#define LOG_TRACE(FMT , ...) WRITE_LOG(EasyLog::LOG_TRACE, FMT, ##__VA_ARGS__)
#define LOG_DEBUG(FMT , ...) WRITE_LOG(EasyLog::LOG_DEBUG, FMT, ##__VA_ARGS__)
#define LOG_INFO(FMT  , ...) WRITE_LOG(EasyLog::LOG_INFO , FMT, ##__VA_ARGS__)
#define LOG_WARN(FMT  , ...) WRITE_LOG(EasyLog::LOG_WARN , FMT, ##__VA_ARGS__)
#define LOG_ERROR(FMT , ...) WRITE_LOG(EasyLog::LOG_ERROR, FMT, ##__VA_ARGS__)
#define LOG_ALARM(FMT , ...) WRITE_LOG(EasyLog::LOG_ALARM, FMT, ##__VA_ARGS__)
#define LOG_FATAL(FMT , ...) WRITE_LOG(EasyLog::LOG_FATAL, FMT, ##__VA_ARGS__)

#define LOGT( FMT , ... ) LOG_TRACE(FMT, ##__VA_ARGS__)
#define LOGD( FMT , ... ) LOG_DEBUG(FMT, ##__VA_ARGS__)
#define LOGI( FMT , ... ) LOG_INFO (FMT, ##__VA_ARGS__)
#define LOGW( FMT , ... ) LOG_WARN (FMT, ##__VA_ARGS__)
#define LOGE( FMT , ... ) LOG_ERROR(FMT, ##__VA_ARGS__)
#define LOGA( FMT , ... ) LOG_ALARM(FMT, ##__VA_ARGS__)
#define LOGF( FMT , ... ) LOG_FATAL(FMT, ##__VA_ARGS__)

/* wstring转string方法 */
#define WS2A(ws)		  EasyLog::WS2S(ws)

class EasyLog
{
public:
    /** 日志级别*/
	enum LOG_LEVEL { LOG_TRACE = 0, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_ALARM,  LOG_FATAL };
    
public:
    /** 单例模式 */
    static EasyLog * GetInstance() { static EasyLog* m_pInstance = new EasyLog(); return m_pInstance; }
    
public:
	std::function<void(LOG_LEVEL level, std::string logText)> onLogChange;
    
public:
	static std::string WS2S(const std::wstring& ws) { return WS2S(ws.c_str()); }
	static std::string WS2S(const wchar_t *pWcsStr)
	{
        std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
        std::string narrowStr = conv.to_bytes(pWcsStr);
        return narrowStr;
	}

    /** 写日志操作 */
	void WriteLog(LOG_LEVEL level, const char *pLogText, ...)
	{
		va_list args;
		char logText[EASY_LOG_LINE_BUFF_SIZE] = { 0 };
		va_start(args, pLogText);
		vsnprintf_s(logText, EASY_LOG_LINE_BUFF_SIZE - 1, pLogText, args);
		WriteLog(logText, level);
	}

	void WriteLog(std::string logText, LOG_LEVEL level = LOG_ERROR)
	{
		static const char *const LOG_STRING[] =
		{
			"LOG_TRACE",
			"LOG_DEBUG",
			"LOG_INFO ",
			"LOG_WARN ",
			"LOG_ERROR",
			"LOG_ALARM",
			"LOG_FATAL",
		};

		// 添加时间信息
        std::time_t t  = std::time(NULL);
        std::tm     tm = *std::localtime(&t);
        
		// 生成一行LOG字符串
        std::stringstream szLogLine;
        szLogLine << "[" << std::put_time(&tm,"%Y-%m-%d %H:%M:%S") << " " << LOG_STRING[level] << "] " << logText;
		    
		#ifdef WIN32
        szLogLine << "\r\n";
		#else
        szLogLine << "\n";
		#endif
        
#if defined EASY_LOG_DISABLE_LOG && EASY_LOG_DISABLE_LOG == 0
		/* 输出LOG字符串 - 文件打开不成功的情况下按照标准输出 */
		if (m_fileOut.is_open())
		{
		    m_fileOut.write(szLogLine.str().c_str(), szLogLine.str().size());
		    m_fileOut.flush();
		}
		else
		{
		    std::cout << szLogLine.str() << std::endl;
		}
#endif
        
		/* 使用CallBack方式调用回显 */
		if (onLogChange)
		{
			onLogChange(level, szLogLine.str());
		}
	}

private:
    EasyLog(void)
	{
		m_fileOut.open(EASY_LOG_FILE_NAME, std::ofstream::out);
		WriteLog("------------------ LOG SYSTEM START ------------------ ", EasyLog::LOG_INFO);
	}
    virtual ~EasyLog(void) 
	{
		WriteLog("------------------ LOG SYSTEM END ------------------ ", EasyLog::LOG_INFO);
		if (m_fileOut.is_open()) m_fileOut.close();
	}
    
private:
    /** 写文件 */
    std::ofstream m_fileOut;
};

#endif  /** ___EasyLog_h */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值