高吞吐koa日志中间件
Midlog中间件
node服务端开发中少不了日志打点,而在koa框架下的日志打点在多进程环境中日志信息往往无法对应上下文,而且在高并发下直接进行写buffer操作(内核调用writev)也会造成内存泄漏,因此Midlog就是为了缓解这种问题而产生的,其采用多种缓冲调度策略尽可能降低writev的代价,减缓内存溢出的速率。

日志系统的三个关键要素:稳定、性能和易用。

当前log4js遇到的问题。

设计新系统的前提。

回顾node原生模块--“流”的读与写,涉及到了多个缓冲区以及他们缓冲区的实现(stream2.0的 Transform流同时包括了读写缓冲区)

优化点与优化方式。

Midlog系统架构图,其中reqContainer收集同一个上下文的日志信息并转码;
StrategyMaker负责制定双缓冲缓存策略和超时刷新以及强制刷新策略;
Writeable则负责真正的写buffer操作,内部通过链表保存数据;

详细介绍每个模块的功能。
快速使用
app.js
var koa = require('koa');
var midlog = require('midlog');
var app = koa();
// 配置日志中间件
var firstValve = midlog({
env: 'online',
exportGlobalLogger: true,
appender: [{
type: 'INFO',
logdir: '/tmp/log/midlog',
pattern: '%d %r %x{name}:%z %p - %m%n',
rollingFile: false,
duation: 60000,
name: 'info.log',
nameformat: '[info.]HH-mm-ss[.log]',
tokens: {
name: 'helloworld'
},
cacheSize: 5 * 1024 * 1024,
flushTimeout: 15000
},{
type: 'ERROR',
logdir: '/tmp/log/midlog',
pattern: '%d %r %x{name}:%z %p - %m%n',
rollingFile: false,
duation: 60000,
name: 'error.log',
nameformat: '[info.]HH-mm-ss[.log]',
tokens: {
name: 'helloworld'
},
cacheSize: 10240,
flushTimeout: 10000
},{
type: 'TRACE',
logdir: '/tmp/log/midlog',
pattern: '%d %r %x{name}:%z %p - %m%n',
rollingFile: false,
duation: 60000,
name: 'trace.log',
nameformat: '[info.]HH-mm-ss[.log]',
tokens: {
name: 'helloworld'
},
cacheSize: 5 * 1024 * 1024,
flushTimeout: 10000
}]
});
// 使用全局的logger接口
logger.info('i am the global logger');
// 将midlog放在中间件的前列
app.use(firstValve);
// 业务中间件
app.use(function*(next){
this.logger.info(this.url+' this is the first valve!! ');
this.logger.error('midlog tracing' + this.url+' this is the first valve!! ');
this.logger.trace('midlog tracing' + this.url+' this is the first valve!! ');
yield next;
});
app.use(function*(){
this.logger.info(this.url+' this is the 2cd valve!! ');
this.logger.error('midlog tracing' + this.url+' this is the 2cd valve!! ');
this.logger.trace('midlog tracing' + this.url+' this is the 2cd valve!!');
this.body = '<h1>hello midlog</h1>';
});
app.listen(8888);
功能
midlog提供了3种日志刷新级别:
TRACE、INFO、ERROR,
并且提供了两种写日志文件的方式:
单文件写 (通过设置appender的rollingFile为false触发)
文件分时间片写 (通过设置appender的rollingFile为true触发)
midlog采用和log4js相同的layout格式和语法,生成可定制的日志输出格式。
最后,midlog采用多级缓冲的架构(针对单文件写模式采用双缓冲,文件分时写模式采用单缓冲),可以有效的控制Stream写的频率,而缓冲的大小和刷新频率可以由开发者根据实际需要自由设置。
配置
env {String} 环境设置。若设置为development,则会在控制台和文件中同时输出日志
exportGlobalLogger {Boolean} 是否保留全局logger对象。设置为true,则在全局使用logger对象
appender {Array} 日志类型配置数组。数组每一项描述每种类型日志的相关信息及缓冲刷新频率
appender详解
type {String} 日志类型。可以为 “INFO、TRACE和ERROR” 任意一种
logdir {String} 日志文件所在的绝对目录
rollingFile {Boolean} 是否按照时间进行日志文件分割。设置为true时则按照设置的duration间隔分割文件
duration {Number} 分割日志文件的间隔。若rollingFile为true,则按照duration大小分割文件
name {String} 日志文件名称。name属性在单文件写模式下有效,在rollingFile == true时无效
nameformat {String} 日志文件格式匹配定义。nameformat属性在文件分时间片写模式下有效,即rollingFile == true
格式定义的字符串意义如下所示:
'd': 日期和时间,
'h': 主机名称,
'm': 日志信息格式化,主要优化错误输出,
'n': 换行符,
'p': 日志级别,
'r': 时间输出,
'z': 进程号输出,
'%': 百分号占位符,
'x': 用户自定义变量或函数,搭配{token}属性
- tokens {Object} 与nameformat搭配使用,对象的属性值可为常亮,也可为函数
如定义nameformat为 pattern: '%d %r %x{name}:%z %p - %m%n' 且tokens设置为 {name: 'helloworld'}
则输出日志格式为:
(%d) (%r) (%x{name}) (%z) (%p) (%m) (%n)
2017-01-16 10:59:55.611 10:59:55 helloworld:13736 INFO - / this is the first valve!!
cacheSize {Number} 缓冲大小,单位字节。midlog在单文件写模式下采用双缓冲结构控制I/O速率,因此开发者可以通过定义缓冲大小实现高效的写入流程,默认为10kB大小;在文件分时间片写模式下该选项无效
flushTimeout {Number} 缓冲刷新间隔。在单文件写和文件分时间片写两种模式下都起作用,定点刷新缓冲
高吞吐koa日志中间件的更多相关文章
- 攻克数据库核心技术壁垒,实现百万级QPS的高吞吐
CynosDB是腾讯云自研的新一代高性能高可用的企业级分布式云数据库.融合了传统数据库.云计算与新硬件的优势,100%兼容开源数据库,百万级QPS的高吞吐,不限存储,价格仅为商用数据库的1/10. C ...
- 高吞吐高并发Java NIO服务的架构(NIO架构及应用之一)
高吞吐高并发Java NIO服务的架构(NIO架构及应用之一) http://maoyidao.iteye.com/blog/1149015 Java NIO成功的应用在了各种分布式.即时通信和中 ...
- dotnet core高吞吐Http api服务组件FastHttpApi
简介 是dotNet core下基于Beetlex实现的一个高度精简化和高吞吐的HTTP API服务开源组件,它并没有完全实现HTTP SERVER的所有功能,而是只实现了在APP和WEB中提供数据服 ...
- 高吞吐低延迟Java应用的垃圾回收优化
高吞吐低延迟Java应用的垃圾回收优化 高性能应用构成了现代网络的支柱.LinkedIn有许多内部高吞吐量服务来满足每秒数千次的用户请求.要优化用户体验,低延迟地响应这些请求非常重要. 比如说,用户经 ...
- Spark Streaming高吞吐、高可靠的一些优化
分享一些Spark Streaming在使用中关于高吞吐和高可靠的优化. 目录 1. 高吞吐的优化方式 1.1 更改序列化的方式 1.2 修改Receiver接受到的数据的存储级别 1.3 广播配置变 ...
- 高吞吐、低延迟 Java 应用的 GC 优化实践
本篇原文作者是 LinkedIn 的 Swapnil Ghike,这篇文章讲述了 LinkedIn 的 Feed 产品的 GC 优化过程,虽然文章写作于 April 8, 2014,但其中的很多内容和 ...
- Kafka是如何实现高吞吐率的
Kafka是如何实现高吞吐率的 原创 2016-02-27 杜亦舒 性能与架构 Kafka是分布式消息系统,需要处理海量的消息,Kafka的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的 ...
- 深入探析koa之中间件流程控制篇
koa被认为是第二代web后端开发框架,相比于前代express而言,其最大的特色无疑就是解决了回调金字塔的问题,让异步的写法更加的简洁.在使用koa的过程中,其实一直比较好奇koa内部的实现机理.最 ...
- 查看JAVA占用CPU高的线程日志
# . 查看主进程占用cpu高 top # java # . 按照线程占用cpu由高到低进行排查: -o THREAD,tid, # USER %CPU PRI SCNT WCHAN USER SYS ...
随机推荐
- [翻译]现代java开发指南 第一部分
现代java开发指南 第一部分 第一部分:Java已不是你父亲那一代的样子 第一部分,第二部分 =================== 与历史上任何其他的语言相比,这里要排除c语言和cobol语言,现 ...
- mybatis系列笔记(2)---mapper代理方法
mapper代理方法 在我们在写MVC设计的时候,都会写dao层和daoimp实现层,但假如我们使用mapper代理的方法,我们就可以不用先daoimp实现类 当然这得需要遵守一些相应的规则: (1) ...
- struts2.5新配置动态调用
开启动态调用: <constant name="struts.enable.DynamicMethodInvocation" value="true"/& ...
- mybatis系列笔记(4)---输入输出映射
输入输出映射 通过parameterType制定输入参数类型 类型可以是简单类型(int String)也可以是POJO本身 或者包装类 1输入映射 关于输入简单类型和pojo本身的我就不写了,因为比 ...
- 【Java集合类】ArrayList详解 (JDK7)
相信对于使用过Java的人来说,ArrayList这个类大家一定不会陌生. 数据结构课上讲过, Array是数组,它能根据下标直接找到相应的地址,所以索引速度很快,但是唯一的缺点是不能动态改变数组的长 ...
- 算法模板——Dinic最小费用最大流
实现功能:输入M,N,S,T:接下来M行输入M条弧的信息(包括起点,终点,流量,单位费用):实现功能是求出以S为源点,T为汇点的网络最大流的最小费用 其实相当的像Dinic最大流呐= = 还是spfa ...
- java Pattern和Matcher详解
结论:Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持. 单独用Pattern只能使用Pattern.matcher(String ...
- ajax天气查询
直接法伤代码: <!DOCTYPE html><html><head> <meta charset="utf-8" /> ...
- 配置adb环境变量
作为Android开发人员,会经常使用adb命令来进行push.pull.install.看数据库等.记录一下adb配置流程,以备后用. 在没有配置adb之前,我们打开Windows命令处理程序(cm ...
- idea 使用常见问题处理
问题一: 项目中使用了 lombok,但是代码中一直报错,提示 bean 注入失败,set 和 get 方法都飘红 解决:idea 中安装 lombok 插件,安装方法自行百度吧~ 如果是用的 ecl ...