`
yuanjinxiu
  • 浏览: 665819 次
文章分类
社区版块
存档分类
最新评论

第二人生的源码分析(5)类Log的实现

 
阅读更多
Log定义如下:
#001class Log
#002{
#003public:
#004 static bool shouldLog(CallSite&);
#005 static std::ostringstream* out();
#006 static void flush(std::ostringstream*, const CallSite&);
#007};
在类Log里的函数shouldLog是先获取全局的Log对象和全局设置参数,然后检查是否需要保存这条Log信息,同时把这条Log保存起来。它的代码如下:
#001bool Log::shouldLog(CallSite& site)
#002{
#003 LogLock lock;
#004 if (!lock.ok())
#005 {
#006 return false;
#007 }
#008
#009 Globals& g = Globals::get();
#010 Settings& s = Settings::get();
#011
#012 s.shouldLogCallCounter += 1;
#013
#014 std::string class_name = className(site.mClassInfo);
#015 std::string function_name = functionName(site.mFunction);
#016 if (site.mClassInfo != typeid(NoClassInfo))
#017 {
#018 function_name = class_name + "::" + function_name;
#019 }
#020
#021 ELevel compareLevel = s.defaultLevel;
#022
#023 checkLevelMap(s.functionLevelMap, function_name, compareLevel)
#024 || checkLevelMap(s.classLevelMap, class_name, compareLevel)
#025 || checkLevelMap(s.fileLevelMap, abbreviateFile(site.mFile), compareLevel);
#026
#027 site.mCached = true;
#028 g.addCallSite(site);
#029 return site.mShouldLog = site.mLevel >= compareLevel;
#030}
在类Log里的函数out是获取保存字符串的输出对象std::ostringstream,由它来格式化所有输出的字符串。它的代码如下:
#001std::ostringstream* Log::out()
#002{
#003 LogLock lock;
#004 if (lock.ok())
#005 {
#006 Globals& g = Globals::get();
#007
#008 if (!g.messageStreamInUse)
#009 {
#010 g.messageStreamInUse = true;
#011 return &g.messageStream;
#012 }
#013 }
#014
#015 return new std::ostringstream;
#016}
在类Log里的函数flush是把保存在Log缓存里字符串输出到合适的地方,比如把一条Log输出到文件里。
#001void Log::flush(std::ostringstream* out, const CallSite& site)
#002{
#003 LogLock lock;
#004 if (!lock.ok())
#005 {
#006 return;
#007 }
#008
这里进行加锁操作。
#009 Globals& g = Globals::get();
#010 Settings& s = Settings::get();
#011
获取全局保存LOG的对象和LOG参数对象。
#012 std::string message = out->str();
#013 if (out == &g.messageStream)
#014 {
#015 g.messageStream.clear();
#016 g.messageStream.str("");
#017 g.messageStreamInUse = false;
#018 }
#019 else
#020 {
#021 delete out;
#022 }
#023
#024 if (site.mLevel == LEVEL_ERROR)
#025 {
#026 std::ostringstream fatalMessage;
#027 fatalMessage << abbreviateFile(site.mFile)
#028 << "(" << site.mLine << ") : error";
#029
#030 writeToRecorders(site.mLevel, fatalMessage.str());
#031 }
#032
写出错的LOG处理。
#033
#034 std::ostringstream prefix;
#035
#036 switch (site.mLevel)
#037 {
#038 case LEVEL_DEBUG: prefix << "DEBUG: "; break;
#039 case LEVEL_INFO: prefix << "INFO: "; break;
#040 case LEVEL_WARN: prefix << "WARNING: "; break;
#041 case LEVEL_ERROR: prefix << "ERROR: "; break;
#042 default: prefix << "XXX: "; break;
#043 };
#044
输出LOG的前缀提示。
#045 if (s.printLocation)
#046 {
#047 prefix << abbreviateFile(site.mFile)
#048 << "(" << site.mLine << ") : ";
#049 }
#050
#051 if (message.find(functionName(site.mFunction)) == std::string::npos)
#052 {
#053#if LL_WINDOWS
#054 // DevStudio: __FUNCTION__ already includes the full class name
#055#else
#056 if (site.mClassInfo != typeid(NoClassInfo))
#057 {
#058 prefix << className(site.mClassInfo) << "::";
#059 }
#060#endif
#061 prefix << site.mFunction << ": ";
#062 }
#063
#064 prefix << message;
#065 message = prefix.str();
#066
#067 writeToRecorders(site.mLevel, message);
#068
写调试、提示、警告、错误的LOG到文件或者显示窗口。
#069 if (site.mLevel == LEVEL_ERROR&&s.crashFunction)
#070 {
#071 s.crashFunction(message);
#072 }
#073}
最后处理出错LOG的情况。
Log通过上面三个函数来检查是否可以输出LOG,怎么样保存LOG信息,然后怎么样输出LOG到文件或者窗口里。到这里就分析完成类Log了,下面再来分析类CallSite的代码。
分享到:
评论

相关推荐

    log4cpp源码完整解析

    完整分析了log4cpp的整体架构,详细介绍了log4cpp的这个重要组件的实现分析了log4cpp内部所使用的设计模式。介绍了log4cpp中的Category的完整实现细节,介绍了所有的Layout及其子类的具体实现。也详细介绍了比较常用...

    log4net源码

    log4net 源码

    log4j源码 log4j源码

    Log4j的源码是公开的,允许开发者深入理解其内部工作原理,以便更好地利用它或者进行二次开发。 在Log4j源码中,有几个核心概念值得我们关注: 1. **Logger**:日志器是Log4j的核心组件,它负责接收日志信息并决定...

    log4j 1.2.15 源码

    在log4j 1.2.15源码中,我们可以深入研究这些核心组件的实现细节,例如Logger是如何根据配置文件进行初始化的,Appender是如何实现日志输出的,以及Level是如何影响日志过滤的。通过对这些关键部分的分析,开发者...

    c#log日志类和日志分析器(源码)

    c# 最简单的log功能和log查看分析器,可以直接在项目中使用,也可以修改源码成为你自己的日志功能某模块,供c#入门的同学学习和参考

    log4cpp 日志 源码

    本文将深入探讨log4cpp的源码,揭示其内在的设计理念和实现机制,为C++开发者提供宝贵的学习资源。 一、log4cpp简介 log4cpp是基于Apache的log4j项目构建的C++版本,旨在为C++程序员提供类似的功能。它支持多线程...

    Log日志分析源码

    分析Log.java的底层JNI代码程序结构

    Log已经实现 Log已经实现

    在IT行业中,日志(Log)...总之,“Log已经实现”意味着系统具有强大的日志管理和分析能力,这对于软件开发、调试、性能优化和故障排除都至关重要。正确理解和利用日志,可以极大地提升工作效率,保障系统的稳定运行。

    B3LOG Solo 开源博客 v0.6.6源码

    B3LOG Solo 开源博客 v0.6.6源码

    Yocto Kernel编译过程分析完整log

    3. 《[【SemiDrive源码分析】【Yocto源码分析】03 - yocto/meta-semidrive目录及Yocto Kernel编译过程分析(上)](https://ciellee.blog.csdn.net/article/details/124566955)》 4. 《[【SemiDrive源码分析】...

    log4cpp源码

    **log4cpp源码分析** `log4cpp`是一个用于C++编程的开源日志库,它提供了类似于Java中的log4j的日志处理框架。这个库设计的目标是为应用程序提供灵活、可配置的日志记录机制,支持多种日志级别、输出目的地以及...

    log4qt源码

    log4qt日志源码

    安卓Android源码——网上绝无仅有的Log分析教程及例子.rar

    安卓Android源码——网上绝无仅有的Log分析教程及例子.rar

    IISLog 分析工具源码

    【IISLog分析工具源码】是一个专门针对IIS日志进行解析和展示的应用程序,主要服务于那些需要深入了解和分析IIS服务器运行情况的开发者或系统管理员。此工具的目的是提取并显示IIS日志文件(.log)中的各种字段信息...

    Log4j工程官方源码

    这个压缩包文件包含的是Log4j的官方源码,对于开发者来说,能够直接导入到Eclipse中进行学习和研究,或者进行二次开发,具有很高的价值。下面将详细解释Log4j的核心概念、功能以及如何在Eclipse中使用这些源码。 1....

    log4j返序列化源码分析

    log4j返序列化源码分析

    log4cplus 源码(C++编写的开源的日志系统)

    LogLog类实现了debug, warn, error 函数用于输出调试、警告或错误信息, 同时提供了两个方法来进一步控制所输出的信息,其中: setInternalDebugging方法用来控制是否屏蔽输出信息中的调试信息,当输入 参数为...

    log4j 1.2.8 jar 包含源码

    1.2.8 版本是 Log4j 的一个较早版本,但其源码仍然具有很高的学习价值,尤其对于理解日志系统的设计原理和实现细节。 **1. 日志级别** 在 Log4j 中,日志级别定义了日志事件的重要性,包括 `DEBUG`、`INFO`、`WARN...

    log4j源码二次开发-集中处理日志消息

    总的来说,通过`log4j`源码的二次开发和`DatagramSocket`的使用,我们可以构建一个高效、可扩展的日志管理系统,实现对多应用、多模块日志的集中处理和有序管理,便于故障排查和数据分析。这种方案尤其适用于分布式...

    Log4j2效率测试源码

    Log4j2效率测试源码

Global site tag (gtag.js) - Google Analytics