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

Log 问题域

 
阅读更多

  • 如何不带来额外的效率损失
  • 如何在程序运行出错时记录尽可能多的信息
  • 如何方便查找特定条件的错误
  • 如何横切的添加通用信息

如何不带来额外的效率损失


在之前接触的一个大型产品中见过散布着如下代码:

if (Log.Level > DEBUG) {
logger.write(some_method_to_build_the_log_string());
}

问为什么不在logger.write()里面判断日志级别, 这样外面写起来就很清爽

logger.write(some_method_to_build_the_log_string());

答曰效率问题, 后面一种写法会导致无论日志最终有没有被写入, some_method_to_build_the_log_string()都会先行被调用求值, 而这可能很耗时...

一个解决办法是额外的中间层: 能够延时求值的东东, 比如函数指针, 函数对象, 总而言之能够保存当前上下文而在将来某个时刻能够回调的东西, 诸如 C# 里的 Func<string>

这样logger.write()的签名就从 void write(string info) 变成 void write(Func<string> getInfo);

带来的一个问题是啥时真正写入, 一般可以是用户事务结束的时候. 其实当并发用户量大时, 表面上延时求值可以不阻碍当前请求的处理速度, 但当求值发生时, 可能会阻碍其它请求的处理. 所以Func<string>代替string效率上的优势并不明显, 更多的是代码上的简洁

(Func<string>的另一个好处是把IO操作推迟了, 当时没有IO操作,所有IO操作都被推到完成用户请求之后再进行,尤其是如果因为其它原因需要把Log存到数据库的时候. 当然不用Func<string>, 直接用string也可以实现推迟IO操作, 只需要把string都缓存起来, 找个时机再写出来即可)


然而Func<string>更大的意义是解决第二个问题:

如何在程序运行出错时记录尽可能多的信息


通常最终写到日志里的信息, 都是根据配置的级别决定的, 比如配置了日志级别是INFO, 那么无论出不出错, DEBUG级别的信息都不会被写到日志里. 然而现实情况是, 一旦出错, 我们可能需要DEBUG信息来定位问题. 于是我们不得不把日志级别设置成DEBUG,然后重新运行应用,企图复现. 但运行环境的差异使得复现像撞大运, 可遇不可得. 于是在案发第一现场就记录所有线索变得极具效率

对日志即时求值和写入是很难实现这个目的的, 而延时求值, 回调, 这层额外的间接则将其变得轻而易举.

我们要做的就是保存所有写日志的回调, 直到写入的那一刻, 根据某种规则, 从中挑选部分回调真正去执行; 规则可以是正常情况下根据日志级别设置, 出错的时候则全部写入, 等等

(这里的目的就是避免日志过于简略或者繁琐, 鼓励大家多写日志而不必担心运行时效率)

如何方便查找特定条件的错误


查找是数据库的强项, 把日志结构化, 存到数据库里即可. 这会带来事务的问题: 写日志是否和用户正常的业务放在一个事务里?

如何横切的添加通用信息


如果把log建模为一个对象, 可以应用builder模式, pipeline等, 让log对象依次通过一堆builder组成的pipeline, 每个builder负责给log增砖添瓦, 最后出来的就是一个包含了各种彼此独立的信息的对象

分享到:
评论

相关推荐

    JS中的变量作用域(console版)

    作用域说明:指一个变量的作用范围 1.全局作用域 (1) 全局作用域在页面打开时被创建,页面关闭时被销毁 (2) 编写在script标签中的变量和函数,作用域为全局,在页面的任意位置都可以访问到 (3) 在全局作用域中有全局...

    JavaScript 作用域 和作用域链

    JavaScript 作用域 和...console.log(str); // Uncaught ReferenceError: inVariable is not defined 变量 str 在全局作用域没有声明,所以在全局作用域下取值会报错。作用域就是一个独立的盒子,让变量不会外泄、暴

    Powershell小技巧之通过EventLog查看近期电脑开机和关机时间

    机器开机和关机时写在EventLog中的第一条日志和最后一条日志分别为:6005和6006。 TimeCreated Id LevelDisplayName Message ----------- -- ---------------- ------- 8/18/2014 9:23:04 AM 6005 Information The ...

    USBTRACE LogFile Decoder V1.0.7.rar

    加密狗数据解码工具,支持龙脉NOX\NOX2\NOX5\NOX定制狗\DAM精简型\DAM2+网络狗、R2\R4SMART\R4ND、域天简单型\密码型\F2K\易用专业型、坚石ET99、精灵狗UGA、精锐E\精锐IV、磐石NT77\NT88\NT199、SuperPro\ULTRAPRO...

    浅谈Nodejs中的作用域问题

    在JS中有全局作用域和函数作用域,而在Nodejs中也自己的作用域,分为全局作用域(global)和模块作用域。 js作用域: 以前学js的时候我们的全局对象是window,如: var a = 10; console.log(window.a); 我们定义的...

    基于DD-DWT和Log-Logistic参数回归的癫痫脑电自动识别方法.pdf

    基于DD-DWT和Log-Logistic参数回归的癫痫脑电自动识别方法.pdf,针对现有癫痫脑电(EEG)识别算法分类模式单一、普适性不强的问题,提出了一种新的基于双密度离散小波变换(DD DWT)和Log Logistic参数回归(LLPR)的...

    二维正交Log-Gabor滤波器结合混沌加密的掌纹认证方法

    该方法使用二维正交Log-Gabor滤波器从图像中提取二进制掌纹相位模板,通过混沌序列控制的随机密文反馈加密,生成可更新的和隐私保护的掌纹模板。识别匹配阶段在加密域实现,根据2个加密模板间的汉明距离衡量掌纹间的...

    Log4F-开源

    Log4F 是一个用于 Flex 应用程序的 Log4j 风格的日志框架。 它基于 http://code.audiofarm.de/Logger/ 上的公共域日志记录框架,并添加了有用的 Flex 特定增强功能,包括调试控制台、实例检查器等。

    域组策略的说明

    与Win2000用户登录/注销脚本 (logon/logoff scrīpts)相比,它们之间的主要区别是:计算机启动/关机脚本在计算机启动和关机时运行,脚本程序只运行一次,通常在启动脚本运行完毕后才出现邀请用户登录的对话框;...

    changelog-io:生成变更日志

    变更日志 使用一个命令生成变更日志。 安装 npm i changelog-io -g 这个怎么运作? 如果您已经有标签并使用如下约定: ...changelog version &gt; ChangeLog # to save output to ChangeLog 执照 麻省理工学院

    Java Framework 关于IOC、AOP、Log的案例源码

    该源码是课程 Java Spring案例精讲 ---- Spring框架 的源码,包含Java Spring的最简单的Hello World、IOC、AOP及Log的源码 Spring整体框架中的核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等...

    JS 作用域与作用域链详解

    (1)作用域 一个变量的作用域(scope)是程序源代码中定义的这个变量的区域。 1. 在JS中使用的是词法作用域... console.log(name); //two } test(); 函数内省略var的,会影响全局变量,因为它实际上已经被重写

    基于ES6作用域和解构赋值详解

    作用域 •var 声明局部变量,for/if花括号中定义的变量在花括号外也可访问 •let 声明的变量为块作用域,变量不可重复定义 •const 声明常量,块作用域,声明时必须赋值,不可修改 // const声明的k指向一个对象,k...

    详解JavaScript作用域、作用域链和闭包的用法

    1. 作用域 作用域是指可访问的变量和函数的集合。 作用域可分为全局作用域和局部作用域。 1.1 全局作用域 全局作用域是指最外层函数外面定义的变量和函数的集合。 换言之,这些最外层函数外面定义的变量和函数在任何...

    js作用域及作用域链概念理解及使用

    (1)作用域 一个变量的作用域(scope)是程序源代码中定义的这个变量的区域。 ... console.log(name); //two } test(); 函数内省略var的,会影响全局变量,因为它实际上已经被重写成了全局变量 v

    spring-security-eventlog:一个Grails插件来记录Spring安全事件

    事件记录到名为SPRING_SECURITY_EVENT的表中,该表映射到域对象ca.redtoad.eventlog.SpringSecurityEvent。 每个事件都有以下字段: 用户名-输入的用户名sessionId-用户的会话eventName-事件的名称remoteAddress-...

    JavaScript作用域、闭包、对象与原型链概念及用法实例总结

    本文实例讲述了JavaScript作用域、闭包、对象与原型链概念及用法。分享给大家供大家参考,具体如下: 1 JavaScript变量作用域 1.1 函数作用域 没有块作用域:即作用域不是以{}包围的,其作用域完成由... console.log

    JavaScript进阶(二)词法作用域与作用域链实例分析

    想了解更多关于作用域的问题推荐阅读《你不知道的JavaScript上卷》第一章(或第一部分),从编译原理的角度说明什么是作用域。概括的说作用域就是一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量。 ...

    关于JavaScript中var声明变量作用域的推断

    一、迷思!由一段代码引发的疑惑 请看如下代码: 代码如下: for... 如果JavaScript中用var声明的变量可视为局部变量,那么能访问到这个变量的作用域就是这个变量的局部作用域。如上例,在console.log行处,依然有j、k

Global site tag (gtag.js) - Google Analytics