homework-jianmu/docs/zh/26-tdinternal/12-log.md

8.6 KiB
Raw Blame History

sidebar_label title toc_max_heading_level
日志系统 日志系统 4

TDengine 通过日志文件记录系统运行状态帮助用户监控系统运行情况排查问题。Log 分为普通日志和慢日志。引擎测的运行状态通过普通日志的方式记录下来,系统运行相关的慢日志操作则记录到慢日志文件里。

普通日志

普通日志实现逻辑

  • 普通日志分同步和异步两种方式,同步立即写入日志文件,异步写入到 buff 里,然后定时写入日志文件。
  • 异步方式日志文件缓存在循环 buff 里, buff 的大小为 buffSize = 20M。如果某次写 buf 的日志大小大于buf 可用空间,本次日志会舍弃,日志里记录: ...Lost N lines here... TDengine 日志循环buff
  • 异步线程里每隔 1s 会更新磁盘信息用于判断是否有空间写日志
  • 异步线程每隔 Interval 时间处理一次写入逻辑。写入规则如下:
    • 如果 buff 里数据小于 buffSize/10不写入磁盘除非超过 1s。
    • 如果 buff 里数据大于 buffSize/10全部写入磁盘。
  • Interval 默认值为 25 msInterval 值会根据每次写入日志的大小动态调整。Interval 调试规则如下:
    • 数据量小时(小于 buffSize/10增大写入间隔Interval 每次增加 5ms最大 25ms。
    • 数据量大时(大于 buffSize/3写入间隔最小Interval 为 5ms。
    • 数据量比较大时(大于 buffSize/4小于等于buffSize/3减小写入间隔Interval 每次减小 5ms最小 5ms。
    • 数据量适中时(大于等于 buffSize/10小于等于buffSize/4写入间隔不变。 TDengine 日志buff调整方式

普通日志行为说明

  • 普通日志命名规则
    • 同一台机器上可以起多个客户端进程,所以客户端日志命名方式为 taoslogX.Y其中 X 为序号,为空或者 0 到 9Y 为后缀 0 或者 1 windows 限制只有一个序号,所以格式为 taoslog.Y
    • 同一台机器上可以起多个服务端进程。所以服务端日志命名方式为 taosdlog.Y其中 Y 为后缀, 0 或者 1。
  • 序号和后缀确定规则如下(假设日志路径为 /var/log/taos/
    • 确定序号:使用 10 个序号作为日志命名方式,/var/log/taos/taoslog0.Y - /var/log/taos/taoslog9.Y依次检测每个序号是否使用找到第一个没使用的序号作为该进程的日志文件使用的序号。 如果 10 个序号都被进程使用,不使用序号,即 /var/log/taos/taoslog.Y进程都往相同的文件里写序号为空
    • 确定后缀0 或者 1。比如确定序号为 3备选的日志文件名就为 /var/log/taos/taoslog3.0 /var/log/taos/taoslog3.1。如果两个文件都不存在用后缀 0一个存在一个不存在用存在的后缀。两个都存在用修改时间最近的那个后缀。
    • 如果日志文件超过配置的条数 numOfLogLines会切换后缀名继续写日志比如/var/log/taos/taoslog3.0 写够了,切换到 /var/log/taos/taoslog3.1 继续写日志。/var/log/taos/taoslog3.0 会添加时间戳后缀重命名并压缩存储(异步线程操作)。
    • 通过配置 logKeepDays 控制日志文件保存几天,几天之外的日志会被删除。比如配置为 1则一天之前的日志会在新日志压缩存储时检测删除。不是自然天。
  • 当文件里日志行数大于 numOfLogLines默认 1000w取值范围 1000-20亿会触发日志归档。
    • 举例taoslog3.0 写满了,切换到 taoslog3.1 继续写。taoslog3.0 重命名为 taoslog.1735616543,然后压缩为 taoslog.1735616543.gz。同时如果 logKeepDays > 0会检测是否有超时的日志文件然后删除。该过程异步执行

慢日志

系统除了记录普通日志以外,对于执行时间超过配置时间的操作,会被记录到慢日志中。慢日志文件主要用于分析系统性能,排查性能问题。

慢日志实现逻辑

上报架构

TDengine 上报框架

缓存逻辑

  • 为了提高上报效率,慢 sql 日志上报方式为批量上报。
  • 慢 sql 日志上报为了防止缓存丢失采用写临时文件方式来实现缓存crash 后不会丢失)。
  • 每生成一条慢 sql 日志都会放到队列里,然后通知 slow log 线程从队列获取数据slow log 线程根据数据里 clusterId 写到不同的文件里。 数据格式如下其中clusterId 为当前日志所属的慢查询集群idvalue 为一条数据json字符串形式
     typedef struct {
         int64_t clusterId;
         char    *value;
     }MonitorSlowLogData
    
  • 说明:
    • 因为客户端进程里可能存在很多个链接 connection所以需要将慢查询日志根据 clusterId 来分组。分组方式通过临时文件名来实现,命名方式为 {tmp dir}/tdengine_slow_log/tdengeine-{clusterId1}-{processId}-{rand}processId 为进程ID主要为了区分多个客户端的上报。
    • 如上图 connection 1 连接的是 cluster 1。connection 2connection 3 连接的是 cluster 2所以connection 1 的慢 sql 数据写入文件 {tmp dir}/tdengine_slow_log/tdengeine-{clusterId1}-{processId}-{rand}connection 2 和 connection 3的慢 sql 数据写入文件 {tmp dir}/tdengine_slow_log/tdengeine-{clusterId1}-{processId}-{rand}

上报逻辑

  • 读取 {tmp dir}/tdengine_slow_log/tdengeine-{clusterId1}-{processId}-{rand} 临时文件内容,每行数据作为 json 数组的一个元素,组装成 json 数组上报(文件里数据每接近 1M 大小上报一次,上报成功后记录读取文件进度,上报采用异步上报方式。在 callback 里继续根据上次的进度继续读取文件的内容上报直至整个文件读取上报完毕上报完毕后会清空临时文件callback 里成功或失败都会继续读取文件,失败时会记录上报失败的数据日志)。每接近 1M 上报一次主要为了防止文件太大,放在一次上报失败)。

上报时机

  • 客户端运行过程中定时上报
    • 每个 monitorInterval 时间间隔上报数据。
  • 客户端正常退出
    • 上报所有慢 sql 日志文件, 上报成功后,删除文件。
  • 客户端异常退出
    • 异常退出后再次与某个集群(clusterId)建立新的链接后遍历 {tmp dir}/tdengine_slow_log/ 目录下 tdengine-{clusterId} 开头的所有文件进行重新上报(这些文件可能是另一个客户端进程或本进程正在操作的。所以每个文件打开时都需要添加文件锁),然后删除这个临时文件。

一些异常行为说明

  • 因为上报数据和删除文件里的上报内容没法作为一个原子操作,所以如果上报后还没删除数据就 crash可能导致下次重复上报重复上报的数据会覆盖并没丢失影响很小。
  • 另外为了保证性能slow log thread 线程把慢 sql 日志写入临时文件缓存,只保证刷新到操作系统的磁盘缓冲区,并不真正每次都 fsync 到磁盘,所以如果机器断电,仍可能丢失数据。该异常出现概率很小,可以容忍此种情况下的数据丢失。

慢日志行为说明

  • 慢日志一方面会记录到本地慢日志文件中,另一方面会通过 taosAdapter 发送到 taosKeeper 进行结构化存储(需打开 monitor 开关)。
  • 慢日志文件存储规则为:
    • 慢日志文件一天一个,如果当天没有慢日志,没有当天的文件。
    • 文件名为 taosSlowLog.yyyy-mm-ddtaosSlowLog.2024-08-02日志存储路径通过 logDir 配置。
    • 多个客户端的日志存储在相应日志路径下的同一个 taosSlowLog.yyyy.mm.dd 文件里。
    • 慢日志文件不自动删除,不压缩。
    • 使用和普通日志文件相同的三个参数 logDir、minimalLogDirGB、asyncLog。另外两个参数 numOfLogLines、logKeepDays 不适用于慢日志。

日志级别说明

日志级别分为 9 种,如下所示:

typedef enum {
    DEBUG_FATAL = 1,
    DEBUG_ERROR = 1,
    DEBUG_WARN = 2,
    DEBUG_INFO = 2,
    DEBUG_DEBUG = 4,
    DEBUG_TRACE = 8,
    DEBUG_DUMP = 16,
    DEBUG_SCREEN = 64,
    DEBUG_FILE = 128
} ELogLevel;

日志开关通过 bit 位来控制,具体如下:

TDengine 日志级别

例如:

  • 131 = 128 + 2 + 1 文件 + info + error
  • 135 = 128 + 4 + 2 + 1 文件 + debug + info + error
  • 143 = 128 + 8 + 4 + 2 + 1 文件 + trace + debug + info + error

通过设置日志开关的参数,可以开启不同级别的日志。