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

第二人生的源码分析(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的代码。
分享到:
评论

相关推荐

    log4net源码

    **log4net源码分析** `log4net`是一款广泛使用的日志记录框架,它源自Java平台上的log4j,并被移植到了.NET环境中。这款开源库提供了强大的日志记录功能,支持多种输出方式,如控制台、文件、数据库等,且具有可...

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

    本文将深入探讨“c# log日志类和日志分析器”的相关知识点,包括日志的创建、存储、分析以及提供的源码在实际项目中的应用。 首先,让我们了解什么是日志。日志是程序运行过程中产生的事件记录,这些记录包含了...

    log4cpp源码完整解析

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

    Log日志分析源码

    本文将深入探讨"Log日志分析源码",特别是Log.java的底层JNI(Java Native Interface)代码程序结构。我们将依次解析涉及到的文件:JNIHelp-.c、AndroidRuntime.cpp、android_util_Log.cpp、jni.h、JNIHelp.h以及Log...

    log4j源码 log4j源码

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

    log4qt源码

    源码中,Logger类实现了日志级别控制、日志事件分发等关键功能。 三、Appender:追加器 追加器是Log4Qt中负责实际输出日志的地方。它可以将日志信息写入文件、标准输出、网络、数据库等不同的目标。常见的Appender...

    log4j 1.2.15 源码

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

    log4cpp 日志 源码

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

    B3LOG Solo 开源博客 v0.6.6源码

    5. **源码结构分析** - **b3log-solo-gae-0.6.6**:这个压缩包包含整个 B3LOG Solo v0.6.6 的源代码,包括核心服务、视图层、模型层、控制层、配置文件以及静态资源。 - **src/main/java**:Java 源代码目录,按照...

    Log4j2效率测试源码

    - **性能测试类**:测试源码通常包括一个或多个测试类,这些类模拟了大量日志记录,以测量不同场景下Log4j2的性能。 3. **测试指标** - **吞吐量**:测试源码可能会计算在一定时间内能够处理的日志条数,以评估...

    Log4j_1.2.15 源码

    5. **源码学习要点** - `Logger`类:了解如何创建和使用日志记录器,以及如何设置日志级别。 - `Appender`接口及其实现类:理解日志输出到不同目的地的机制。 - `PatternLayout`类:深入研究日志格式化的实现。 ...

    log4j-1.2.17含源码

    源码分析方面,我们可以关注几个关键类:`org.apache.log4j.Logger`是日志记录的主要接口,`org.apache.log4j.Category`(Logger的实现)负责实际的日志记录,`org.apache.log4j.Appender`接口定义了日志输出的基本...

    log4net1.2.11.dll 和 log4net1.2.11源码

    源码分析对于理解log4net的工作原理和扩展其功能至关重要。通过阅读源码,开发者可以: 1. **理解内部工作流程**:查看Appender、Layout、Repository、Hierarchy等关键组件的实现,了解它们如何协同工作,记录、...

    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的日志处理框架。这个库设计的目标是为应用程序提供灵活、可配置的日志记录机制,支持多种日志级别、输出目的地以及...

    log4j 源码包 日志包 2.11.0

    通过对Log4j 2.11.0源码的深入研究,开发者不仅可以掌握其基本用法,还能了解其背后的实现机制,从而更好地利用这一强大的工具,提升开发效率,优化系统性能。同时,源码学习也是提升编程技能的重要途径,能帮助...

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

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

    log4j学习源码教程

    本教程将通过源码分析,深入讲解log4j的工作原理和使用方法。 **1. log4j的基本概念** - **Logger**: 日志记录器,是log4j的核心接口,用于生成不同级别的日志事件。 - **Level**: 日志级别,包括DEBUG、INFO、...

    Log4j工程官方源码

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

Global site tag (gtag.js) - Google Analytics