# 日志回收策略

### Rsyslog介绍

#### Rsyslog是什么

rsyslog 是一个 syslogd 的多线程增强版。rsyslog是Linux系统日志守护进程。默认的rsyslog配置文件是/etc/rsyslog.conf文件。程序，守护进程和内核提供了访问系统的日志信息

几乎所有的网络设备都可以通过rsyslog协议，将日志信息以用户数据报协议(UDP)方式传送到远端服务器，远端接收日志服务器必须通过rsyslogd监听UDP 端口514，并根据 rsyslog.conf配置文件中的配置处理本机，接收访问系统的日志信息，把指定的事件写入特定文件中，供后台数据库管理和响应之用。意味着可以让任何事件都登录到一台或多台服务器上，以备后台数据库用off-line(离线) 方法分析远端设备的事件。

通常，rsyslog 接受来自系统的各种功能的信息，每个信息都包括重要级。/etc/rsyslog.conf 文件通知 rsyslogd 如何根据设备和信息重要级别来报告信息。

rsyslog相关特性为：

- 多线程工作
- 基于UDP、TCP、协议，还可以基于tls/ssl进行加密通信，还可以基于RELP进行通信
- 存储日志信息于MySQL、PostgreSQL(PGSQL)、Oracle等RDBMS
- 强大的过滤器，实现过滤日志信息中任何部分的内容
- 自定义的输出格式

### Rsyslog相关术语

- facility：收集日志的通道设施，信道，可以理解为日志通过那个虚拟设备发送进来，包括
  - auth 认证相关
  - authpriv 权限，授权相关的
  - cron 任务计划相关的
  - daemon 守护进程相关的
  - kern 内核相关的
  - lpr 打印相关的
  - mail 邮件相关的
  - mark 标记相关的
  - news 新闻相关的
  - security 安全相关的
  - syslog syslog自己的
  - user 用户相关的
  - uucp unix to unix cp 相关的
  - local0 to local7 用户自定义相关的
  - 表示所有的facility
- priority：log level，日志的级别，一般有以下级别
  - debug 程序或系统的调试信息
  - info 一般信息
  - notice 不影响功能，需要注意的消息
  - warning 可能影响系统功能，需要提醒用户的重要事件
  - error 错误信息
  - cirt 比较严重的
  - alert 必须马上处理的
  - emerg/panic 会导致系统不可用的
  - 表示所有的日志级别
  - none 与*相反
- target：日志记录的位置，常见的有：
  - 文件：将制定的日志信息记录到指定的文件中
  - -文件：将制定的日志信息记录到指定的文件中，异步写入
  - 用户：将日志时间通知给指定的用户，通常是将日志信息发送给登录到当前系统上的所有用户的终端
  - 日志服务器：格式为@RSYSLOG_SERVER ,表示将日志信息发送给指定的日志服务器
  - 管道：格式为 COMMAND 表示将日志信息管道送给指定的命令

### Rsyslog日志格式

syslog标准协议如下图：

facility.priority target 表示将哪个信道传进来的日志，哪个日志级别(及其之上的日志级别)，记录到哪个目标中 facility格式： *表示所有的facility

- 表示所有的facility
  - FACI1,FACI2,FACI1,… 列表中给定的所有facility
  - FACI1.PRI1;FACI2.PRI2;FACI3.PRI3;… 列表中给定的facility和对应的priority及其之上级别的记录
- priority格式： priority格式： *所有级别
- none 没有级别，不记录日志
- PRIORITY：此级别(含)及其以上的所有级别
- =PRIORITY： 仅指定的级别 例如：
- *.info;mail.none;authpriv.none;cron.none /var/log/messages 表示所有信道的info级别以上的信息，除了mail设备，authprioriv设备、cron设备的日志，都记录到/var/www/messages文件
- authpriv.* /var/log/secure 表示authpriv设备上所有日志级别的日志，都记录到/var/log/secure文件中
- mail.* -/var/log/maillog 表示mail设备所有日志级别的日志，都以异步方式记录到/var/log/mailog文件
- auth.=info @10.0.0.1 表示将auth相关的,级别为只为info的日志记录到10.0.0.1主机上去，前提是10.0.0.1要能接收其他主机发来的日志信息
- user.!=error /var/log/test.log 表示记录user相关的,不包括error级别的信息，记录到/var/log/test.log文件中
- cron.info;mail.info /var/log/test.log 与cron.info;mail.info 是一个意思
- mail.*;mail.!=info /var/log/test.log
- 表示记录mail相关的所有级别的信息,但是不包括info级别的

### Rsyslog 存储

- 记录到普通文件或设备文件

#### logger 命令用于产生日志

logger -p local3.info 'KadeFor is testing the rsyslog and logger'

- 转发到远程 . @192.168.0.1 # 使用UDP协议转发到192.168.0.1的514(默认)端口 . @@192.168.0.1:10514 # 使用TCP协议转发到192.168.0.1的10514(默认)端口
- 发送给用户（需要在线才能收到） . root
  . root,kadefor,up01 # 使用,号分隔多个用户 . * # *号表示所有在线用户
- 忽略，丢弃 local3.* ~ # 忽略所有local3类型的所有级别的日志
- 执行脚本 local3.* ^/tmp/a.sh # ^号后跟可执行脚本或程序的绝对路径 日志内容可以作为脚本的第一个参数 可用来触发报警
- 日志记录的顺序有先后关系 :: .info;mail.none;authpriv.none;cron.none /var/log/messages authpriv. /var/log/secure mail.* /var/log/maillog cron.* /var/log/cron .emerg * uucp,news.crit /var/log/spooler local7. /var/log/boot.log

#### 工智机软件log方案介绍

- log方案功能需求分析
- 工智机log方案

> Log采集以及存储方案采用 rsyslog + logrotate + slog实现，通过实现slog接口对于底层syslog接口进行封装对上层统一接口方便统一log输出格式，具体框架如下图：

- rsyslog随系统启动负责记录系统各模块事件日志，目前会重点关注Kernel日志、各Service模块日志、Application相关日志，将日志信息分别存储至对应的日志文件中。
- LogService负责日志收集
- slog 负责对上提供底层记录Log接口，同时对需要保存的日志信息按照需求进行统一格式化输出，输出信息满足Log格式需求

#### 基础功能介绍

- rsyslog配置

    # if you experience problems, check
    # if you experience problems, check
    # rsyslog v3: load input modules
    # If you do not load inputs, nothing happens!
    # You may need to set the module load path if modules are not found.
    #
    # Ported from debian's sysklogd.conf
    $ModLoad immark   # provides --MARK-- message capability
    $ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
    $ModLoad imklog   # kernel logging (formerly provided by rklogd)

    #
    # Set the default permissions
    #
    $FileOwner root
    $FileGroup adm
    $FileCreateMode 0640
    $DirCreateMode 0755
    $Umask 0022
    $template sinsegye_format, "%$NOW% %TIMESTAMP:8:15%  %syslogtag%%msg%\n"
    #$ActionFileDefaultTemplate sinsegye_format

    auth,authpriv.*                 /var/log/auth.log
    *.*;auth,authpriv.none          -/var/log/syslog
    cron.*                          /var/log/cron.log
    daemon.*                        -/var/log/daemon.log
    lpr.*                           -/var/log/lpr.log
    mail.*                          -/var/log/mail.log
    user.*                          -/var/log/user.log

    kern.*                          /log/kernel/kern.log
    local7.*                         /log/kernel/boot.log
    local1.*                        /log/service/service.log;sinsegye_format
    local2.*                        /log/app/app.log;sinsegye_format
    #
    # Logging for the mail system.  Split it up so that
    # it is easy to write scripts to parse these files.
    #
    mail.info                       -/var/log/mail.info
    mail.warn                       -/var/log/mail.warn
    mail.err                        /var/log/mail.err

    # Logging for INN news system
    #
    news.crit                       /var/log/news.crit
    news.err                        /var/log/news.err
    news.notice                     -/var/log/news.notice

    #
    # Some `catch-all' logfiles.
    #
    *.=debug;\
              auth,authpriv.none;\
            news.none;mail.none     -/var/log/debug
    *.=info;*.=notice;*.=warn;\
           auth,authpriv.none;\
           cron,daemon.none;\
           mail,news.none          -/var/log/messages

    #
    # Emergencies are sent to everybody logged in.
    #
    *.emerg                         :omusrmsg:*

    #
    # Include all config files in /etc/rsyslog.d/
    #
    $IncludeConfig /etc/rsyslog.d/*.conf
    - 下面是针对syslog中Service、Kernel、Application三个的输出配置
    #  Default rules for rsyslog.
    #
    #           For more information see rsyslog.conf(5) and /etc/rsyslog.conf

    template(name="sinsegyetmplate" type="string" string="[%TIMESTAMP:::date-rfc3339%] [%hostname%] [%syslogseverity-text%] %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n")

    auth,authpriv.* /log/auth/auth.log;sinsegyetmplate
    local3.* -/log/service/service.log;sinsegyetmplate
    local4.* -/log/application/application.log;sinsegyetmplate
    #cron.*             /var/log/cron.log
    daemon.* -/log/daemon/daemon.log
    kern.* -/log/kern/kern.log
    #lpr.*              -/var/log/lpr.log
    #mail.* -/var/log/mail.log
    #user.*             -/var/log/user.log

    #
    # Logging for the mail system.  Split it up so that
    # it is easy to write scripts to parse these files.
    #
    #mail.info          -/var/log/mail.info
    #mail.warn          -/var/log/mail.warn
    #mail.err /var/log/mail.err

    #
    # Some "catch-all" log files.
    #
    #*.=debug;\
    #   auth,authpriv.none;\
    #   news.none;mail.none -/var/log/debug
    #*.=info;*.=notice;*.=warn;\
    #   auth,authpriv.none;\
    #   cron,daemon.none;\
    #   mail,news.none      -/var/log/messages

    #
    # Emergencies are sent to everybody logged in.
    #
    *.emerg :omusrmsg:*

    #
    # I like to have messages displayed on the console, but only on a virtual
    # console I usually leave idle.
    #
    #daemon,mail.*;\
    #   news.=crit;news.=err;news.=notice;\
    #   *.=debug;*.=info;\
    #   *.=notice;*.=warn   /dev/tty8

- slog 模块 slog模块会对syslog等系统log接口进行一层接口封装，便于统一app以及service层统一调用，统一Log格式，按照需求会提供不同LOG优先级设定以及不同log类型的tag属性
- log uploader模块 无

### 日志功能描述

#### 日志源

日志要求方便后期查询处理，主要分为Kernel日志、Service日志、Application日志、Peripheral日志。这些日志源主要方便IDE汇总以及云端制定特定日志文件回读

系统 | 日志源 | 日志内容
--- | --- | ---
工智机系统 | Kernel | Linux kernel日志
-- | Service | Linux 常驻Service 运行日志
-- | Application | 各个组件或应用程序日志
-- | IO_DEVICES | 关键外设日志
-- | COMMUNICATION_BUS | 总线相关服务的日志
-- | RUNTIME | Codesys runtime日志
-- | EXTENSION_COMPONENTS | 扩展组件的日志
-- | SYSTEM_MAINTENANCE | 系统维护和诊断日志
-- | TEMPORARY_DEBUGGING | 调试日志
-- | SAFETY_SYSTEMS | 安全模块服务日志

### 日志级别

根据日志所记录问题的严重等级不同，日志优先级要求分为：`FATAL`、`ERROR`、`WARN`、`INFO`、`DEBUG`、`TRACE`。

不同版本默认日志等级也不通，为减少系统资源占用及控制日志数量，Release版本默认等级为INFO，INFO以下的日志不会被输出。Debug版本默认的等级为全部日志。交付给用户必须是默认等级，即Release版本的等级为INFO。

#### 日志格式

日志格式主要分为2种：kernel格式以及非kernel格式。

- Codesys runtime 日志格式
  - Codesys SDK自带日志格式不变，但是按照rsyslog进行格式化，格式如下： Aug 30 20:38:32 sinsegye-sx21 SinsegyeRTE[2073]: 2024-08-29T11:00:03-0800: Cmp=CmpRouter, Class=1, Error=0, Info=1, pszInfo= Setting router 2 address to
- 非kernel日志格式
  - 日志内容以及TAG中不能出现“^”字符
  - 时间：记录请求时间（YY-MM-DD HH:MM:SS,SSS），本地时间
  - 日志所属进程号：日志所属模块的进程号
  - 日志级别：输出日志信息优先级：FATAL、ERROR、WARN、INFO、DEBUG、TRACE;
  - TAG:按照“模块名-文件名”的格式，TAG的长度尽量不超过20个字符。
  - 日志内容：日志描述内容，描述清晰，简短，携带关键参数信息，每条日志长度不超过255个字符
  - 日志编码UTF-8 2020-01 08：16：53.214 1726 1726 ERROR MODBUS.RTU: at xxxxx failed
- Kernel日志格式 [13579.24680] KERN_WARNING: Example warning message from the kernel module
  - [13579.24680] 是时间戳，表示日志输出的时间。具体的时间戳格式可能因系统配置而异。
  - KERN_WARNING 是日志级别，表示这是一个警告条件的日志信息。
  - Example warning message from the kernel module 是日志内容，表示实际的日志信息。
- TAG名称格式
  - 软件模块名称的命名要遵守基本的编程规范和命名风格
  - 推荐使用自然语义的完整的英文单词（或通用的缩写）组合
  - 推荐使用 UpperCamelCase 风格，遵从驼峰形式，kernel 日志除外
  - 要有可读性，容易识别.
  - 禁止使用不规范的缩写，避免望文不知义
  - 禁止以下划线或美元符号开头，也不能以下划线或美元符号结束
  - 禁止使用拼音与英文混合的方式，不允许直接使用中文命名
  - 避免使用‘^’符号
  - 软件模块名称要能体现模块的功能，通过模块名可识别出模块的所属和功能，不能使用“test”之类的命名 日志存储
    - 存储空间 系统文件目录 存储和上传日志规则待定 *

> 工智机日志要求分区如下：

Log下子目录结构如下：

    /log
        - kernel #kernel 的log
        - service # service log
        - application # app log
        - rte # codesys rte log
        - xxxxxxx

#### 示例

    /log/auth/auth.log
    /log/iodevice/iodevice.log
    /log/commbus/commbus.log
    /log/safetybus/safetybus.log
    /log/service/service.log
    /log/application/application.log
    /log/rte/rte.log
    /log/maintenance/maintenance.log
    /log/temp/temp.log
    /log/daemon/daemon.log
    /log/kern/kern.log
    {
    	rotate 7
    	maxsize 50M
    	weekly
    	missingok
    	notifempty
    	compress
    	delaycompress
    	sharedscripts
    	postrotate
    		/usr/lib/rsyslog/rsyslog-rotate
    	endscript
    }

### 配置解析

- 日志文件路径：列出了需要进行轮换的多个日志文件路径，如 `/log/auth/auth.log`、`/log/iodevice/iodevice.log` 等。

- rotate 7：保留 7 个轮换的日志文件，旧的日志会被删除。

- maxsize 50M：如果日志文件超过 50 MB，则会进行轮换。

- weekly：每周进行轮换。

- missingok：如果日志文件丢失，不会报错。

- notifempty：如果日志文件为空，则不进行轮换。

- compress：轮换后压缩日志文件。

- delaycompress：延迟压缩，意味着当前轮换的日志不会立即被压缩，而是在下次轮换时进行压缩。

- sharedscripts：如果有多个日志文件被轮换，`postrotate` 脚本只会执行一次。

- postrotate /usr/lib/rsyslog/rsyslog-rotate：在轮换后执行的脚本，通常用于重新加载或重新启动日志收集服务。

根据整体方案要求，需要在如下情况下创建新的日志文件

- 每次开机、唤醒且有新的日志产生时，新建日志文件
- 当前日志文件已满时，新建日志文件 日志文件以文件形式存储。日志文件名称以“日志源/二级源-Serial-创建时间.log”格式命名，其中Serial为每个工智机独有的一个设备编码号，用于区分不同设备的日志。创建时间要求 YYYY-MM-DD-HH_MM_SS格式。 例如文件名：
- CH20X-Kernel-1122334455-2022-08-01-15_22_08.log
- CH20X-Service-1122334455-2022-08-01-15_22_08.log
- SX5100-APP-1122334455-2022-08-01-15_22_08.log

### 日志上传

无需求

### 日志清除

### 日志轮转

采用logrotate服务，并根据rsyslog配置文件进行轮转, 具体配置文件在promtail安装包

### 外设日志

若工智机有外部设备接入，需要将外部设备产生的log进行采集记录

### 日志功能设计

日志模块启动流程 Log模块是单独的Log守护进程，主要流程是由linux init进程将其启动，由system service 进程保证其正常工作，然后Log模块启动其他子模块。System service守护进程监控Log模块状态，一旦log模块异常守护进程立即将log模块进行恢复。