MongoDB中的日志系统

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: 本文是一篇源码导读类文章,主要是写给MongoDB的开发者看的,首先会简单介绍一下MongoDB的日志系统的组成,然后会再介绍一下如何使用。 日志系统组成 首先介绍一下日志系统的几个基本组件和概念。 Encoder Encoder类负责对日志格式化,在不同的场景可能需要不同格式的日志,比如输

本文是一篇源码导读类文章,主要是写给MongoDB的开发者看的,首先会简单介绍一下MongoDB的日志系统的组成,然后会再介绍一下如何使用。

日志系统组成

首先介绍一下日志系统的几个基本组件和概念。

Encoder

Encoder类负责对日志格式化,在不同的场景可能需要不同格式的日志,比如输出到console和文件可以使用一种格式,输出到syslog用另一种格式,还有些时候是不需要特定格式,直接输出raw信息即可。那么只要定义一个特定格式的派生类,实现对应的encode()接口即可。MongoDB目前定义了以下3种Encoder分别用于console/文件、syslog和raw:

  • MessageEventDetailsEncoder
  • MessageEventWithContextEncoder
  • MessageEventUnadornedEncoder

Appender

和其他日志系统一样,Appender就是日志输出到什么地方,常见的有Console、File、syslog等。作为一个服务,日志切割是普遍需求,为此MongoDB实现了一个RotatableFileAppender结合RotatableFileWriter和RotatableFileManager来实现这个功能。
每个Appender类有一个append()接口,所有派生类都需要实现这个接口。Appender类在构造时需要指定一个Encoder,append()的时候调用Encoder的encode()接口对日志进行格式化,然后再输出。MongoDB目前定义了以下几种Appender分别用于console、File和syslog输出:

  • ConsoleAppender
  • RotatableFileAppender
  • SyslogAppender

LogDomain

LogDomain可以理解为用来对日志按照业务类型进行分类(Domain)。这里业务类型是一个抽象的说法,具体可以是普通的程序日志、或是一些特殊模块的日志。MongoDB中有一个全局的LogDomain用于普通的日志输出,另外还有一个专门用于JavaScript输出。每个LogDomain管理了一组Appender,因此可以实现比较灵活的配置,比如系统日志可以输出到一个文件,JavsScript相关的日志可以输出到console或是另一个文件。除Appender的管理方法(attachAppender()、detachAppender()、clearAppenders())外,LogDomain也提供一个append()方法,调用后就是遍历其包含的Appender依次调用append()方法。

LogManager

LogDomain的管理者,包含一个全局的LogDomain以及一个LogDomain map,可以根据LogDomain的名字获取到对应的LogDomain。

LogComponent

标识日志是哪个组件产生的,是一个枚举值,有

  • kDefault
  • kControl
  • kCommand
  • ...

如果没有明确的所属组件,那么使用kDefault这个默认组件。

LogSeverity

日志级别,按照严重程度包含以下级别:

  • Severe
  • Error
  • Warning
  • Info
  • Log
  • Debug(1)
  • Debug(2)

各级别有一个对应的整型值,从小到大依次对应-4到2。当一个log调用时使用的日志级别对应的整型值大于当前配置的日志级别的整型值时,这个log才会被记录。可以在YAML配置文件中使用systemLog.verbosity来配置日志级别,注意这个配置只能配置非负值,即0、1、2分别对应Log、Debug(1)和Debug(2)。因此,值为负数的日志,即Info级别以上的的日志是一定会被记录的。另外,MongoDB可以支持不同的LogComponent使用不同的LogSeverity,比如可以配置systemLog.component.control.verbosity等。

LogstreamBuilder

根据提供的LogDomain、的LogSeverity和LogComponent等封装一个日志流,包含一个std::ostringstream。它重载了『<<』操作符,将日志内容输入到std::ostringstream中去,因此可以直接按照std::ostringstream的使用方式去使用。在LogstreamBuilder析构时会调用LogDomain的append()方法将日志输出到Appender中。

如何使用

MongoDB启动时在GlobalLogManager这个全局初始化函数中实例化了全局的LogManager单例,其中包含了ComponentMessageLogDomain这个全局的LogDomain。因此我们只只需要在需要记log的地方构造LogstreamBuilder,再传入日志内容就可以了。

在util/log.h中定义了以下函数直接构造一个对应的LogstreamBuilder(使用全局的LogDomain和MONGO_LOG_DEFAULT_COMPONENT):

  • severe()
  • error()
  • warning()
  • log()

此外,还定义了以下一系列LOG宏来根据传入的DLEVEL值是否大于组件配置的日志级别的值来判断是否需要记录log:

  • LOG
  • MONGO_LOG(DLEVEL)
  • MONGO_LOG_COMPONENT(DLEVEL, COMPONENT1)
  • MONGO_LOG_COMPONENT2(DLEVEL, COMPONENT1, COMPONENT2)
  • MONGO_LOG_COMPONENT3(DLEVEL, COMPONENT1, COMPONENT2, COMPONENT3)

这种方式可以指定DLEVEL,因此更加灵活。

综上,MongoDB日志系统的使用非常简单,只需:

  1. 在cpp文件中include util/log.h头文件,注意不可include多次
  2. 在当前cpp文件中定义一个MONGO_LOG_DEFAULT_COMPONENT宏
  3. 使用预定义的几个函数或LOG系列宏来进行log调用
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
NoSQL MongoDB Docker
Docker Compose安装MongoDB,并向宿主机映射数据文件/配置文件/日志文件
本文为博主实践Docker Compose方式安装MongoDB记录,希望对大家有所帮助。
2378 0
|
NoSQL MongoDB 数据库
MongoDB日志浅析
MongoDB 日志
6106 0
|
11月前
|
JSON 缓存 负载均衡
【服务网格架构】Envoy架构概览(9):访问日志,MongoDB,DynamoDB,Redis
【服务网格架构】Envoy架构概览(9):访问日志,MongoDB,DynamoDB,Redis
|
11月前
|
NoSQL Shell Linux
一日一技:手动rotate MongoDB的日志
一日一技:手动rotate MongoDB的日志
91 0
|
11月前
|
JSON 缓存 负载均衡
Envoy架构概览(9):访问日志,MongoDB,DynamoDB,Redis
Envoy架构概览(9):访问日志,MongoDB,DynamoDB,Redis
|
12月前
|
NoSQL Java 测试技术
利用 Log4j2 异步保存日志到 MongoDB 中
利用 Log4j2 异步保存日志到 MongoDB 中
|
监控 NoSQL MongoDB
MongoDB数据的导出导入及日志分析
MongoDB数据的导出导入及日志分析
514 0
|
存储 缓存 NoSQL
分布式服务器框架之Servers.Core中 实现Log模块设计 写入MongoDB数据库
游戏服务器中都需要用到Log模块,log模块存在的意义第一个是将log输出到控制台又或者是写入到log文件中,出了BUG方便定位;第二是常用于将用户的数据(例如玩家登录、道具购买量)将这种log统计到数据库中,方便统计用户留存信息、数据分析等。
|
消息中间件 存储 NoSQL
Spring Boot中使用log4j实现http请求日志入mongodb
Spring Boot中使用log4j实现http请求日志入mongodb
255 0
|
JSON NoSQL Shell
如何将 winston log 库记录的日志写入 mongo DB 数据库
Winston 非常适合配置不同的日志目的地。 在我们的小应用程序中,让我们创建另一个传输。 这次我想把日志保存到一个数据库中,MongoDB 简洁一些。 在 logger.js 文件上,复制以下代码块。 确保安装 Winston MongoDB,即 npm install winston-mongodb。
如何将 winston log 库记录的日志写入 mongo DB 数据库

相关产品

  • 云数据库 MongoDB 版