OpenWrt 系统日志中频繁出现 cron.err 问题分析

本文分析了OpenWRT系统中crond日志默认全部以cron.err级别输出的情况,指出由于内存节省原因, BusyBox的syslog_info20选项未启用。解决方案包括接受这些日志为正常运行的提示,或者通过调整系统设置(如将cron.loglevel设为9)来减少日志输出。此外,介绍了cron日志等级及其含义,并提供了修改crond启动文件以更改日志等级的方法。

情况描述

日志类似

Wed Feb 16 05:00:03 2022 cron.err crond[31109]: crond (busybox 1.33.2) started, log level 5
Wed Feb 16 05:00:18 2022 cron.err crond[1475]: crond (busybox 1.33.2) started, log level 5

分析结果

The FEATURE_SYSLOG_INFO 20 option appeared in BusyBox v. 1.31.0.
But in OpenWRT in order to save memory :slight_smile: this option is disabled by default: master 4, openwrt-21.02 branch 16.
As a result, BusyBox components (including cron) in syslog write all messages with the error level.

说人话,这就是普通的输出日志
OpenWRT默认crond的日志全部使用cron.err输出了

解决方法

鉴于日志详细信息并没说什么错误,可以当做crond正常运行的日志提示
或者
你不想它显示,把OpenWrt的系统日志等级调高

uci set system.@system[0].cronloglevel=9
uci commit

service cron restart

补充知识

cron 日志等级

OpenWrt Wiki
System configuration /etc/config/system
0 会打印所有信息
8 会打印命令执行
9或更高 只会记录错误日志

参考链接

Cron.err - why?
crond log level meaning


❌这个不适用于OpenWrtcrond log level

-l emerg or panic  LOG_EMERG   0   [* system is unusable *]
-l alert           LOG_ALERT   1   [* action must be taken immediately *]
-l crit            LOG_CRIT    2   [* critical conditions *]
-l error or err    LOG_ERR     3   [* error conditions *]
-l warn or warning LOG_WARNING 4   [* warning conditions *]
-l notice          LOG_NOTICE  5   [* normal but significant condition *] the default
-l info            LOG_INFO    6   [* informational *]
-l debug           LOG_DEBUG   7   [* debug-level messages *] same as -d option

上文中的日志里可以看到log level使用的是5
我们如何更改它?
可以在crond的启动文件/etc/init.d/cron中看到端倪

...
start_service() {
	procd_set_param command "$PROG" -f -c /etc/crontabs -l "${loglevel:-5}"
}
...

应该是这里的 5 修改为我们需要的等级即可

<think>我们讨论的是OpenWrt中Lua的nixio.fs.readfile函数。首先,需要明确的是,nixio是OpenWrt中一个用于系统I/O操作的Lua库,而nixio.fs则提供了文件系统相关的操作。nixio.fs.readfile是一个用于读取整个文件内容的函数。它类似于其他编程语言中读取整个文件到字符串的函数(例如Python的`open().read()`)。函数原型通常为:```luacontent=nixio.fs.readfile(filename)```这个函数会打开指定的文件,读取所有内容,然后关闭文件,并返回文件内容作为字符串。如果读取过程中出现错误(如文件不存在),它会抛出错误(即Lua的error),因此我们可能需要使用pcall来捕获错误。下面是一个使用示例:```lualocalnixio=require"nixio"localnixio_fs=require"nixio.fs"--使用nixio.fs.readfile读取文件localfilename="/etc/config/system"--使用pcall来捕获可能的错误localcontent,errcontent,err=pcall(nixio_fs.readfile,filename)ifnotcontentthen--如果pcall返回的第一个值是false,表示有错误,第二个值就是错误信息print("Errorreadingfile:"..err)else--如果pcall成功,第一个值是true,第二个值才是函数返回的结果--所以这里我们取pcall的第二个返回值作为文件内容--注意:上面的写法不对,因为pcall返回两个值:第一个是布尔值(成功为true,失败为false),第二个是函数的返回值或错误信息。--所以正确的处理应该是:--我们重新写一下:end--更常见的写法是:localsuccess,result=pcall(nixio_fs.readfile,filename)ifsuccessthenprint("Filecontent:\n"..result)elseprint("Error:"..result)end--但是,注意:nixio.fs.readfile在文件不存在时会抛出错误,所以使用pcall是安全的做法。```然而,在OpenWrt的Lua环境中,我们也可以不使用pcall,而是检查返回值,因为根据文档,nixio.fs.readfile在失败时返回nil和错误信息。但根据实际代码和文档,nixio.fs.readfile在出错时确实会返回nil和错误信息,而不会抛出错误。所以我们可以不用pcall。修正:根据nixio库的源代码,nixio.fs.readfile在出错时返回nil,errmsg,成功时返回字符串。所以我们可以这样写:```lualocalcontent,err=nixio_fs.readfile(filename)ifnotcontentthenprint("Errorreadingfile:"..err)elseprint(content)end```因此,我们不需要使用pcall,因为函数本身就不会抛出错误,而是通过返回nil和错误信息来表示错误。总结:nixio.fs.readfile函数用于读取整个文件,返回文件内容。如果成功,返回字符串;如果失败,返回nil和错误信息。注意:这个函数会一次性将整个文件读入内存,所以对于大文件要谨慎使用。下面是一个完整的示例脚本,假设我们要读取OpenWrt中网络配置文件:```lua#!/usr/bin/lualocalnixio=require"nixio"localnixio_fs=require"nixio.fs"localfilename="/etc/config/network"localcontent,err=nixio_fs.readfile(filename)ifcontentthenprint("Contentof"..filename..":")print(content)elseprint("Failedtoreadfile:"..err)end```将上述代码保存为`readfile_example.lua`,然后在OpenWrt设备上运行即可。现在,根据要求,我们需要在最后提出相关问题。§§相关问题§§:1.OpenWrt的Lua中,如何使用nixio.fs.writefile写文件?2.nixio.fs模块中还有哪些常用的文件操作函数?3.如何用Lua在OpenWrt中检查文件是否存在?4.OpenWrt的Lua中,如何逐行读取文件(而不是一次性读取整个文件)?</think>### OpenWrt中Lua的`nixio.fs.readfile`详解 在OpenWrt的Lua环境中,`nixio.fs.readfile`是`nixio`文件系统模块提供的函数,用于**一次性读取整个文件内容到字符串**。它属于OpenWrt特有的Lua扩展库`luci.nixio`,专为嵌入式环境优化。 #### 函数原型 ```lua content = nixio.fs.readfile(filename) ``` #### 参数 - `filename` : 字符串类型,文件路径(如`"/etc/config/system"`) #### 返回值 - 成功时返回文件内容的字符串 - 失败时返回`nil` + 错误信息字符串(如文件不存在) --- ### 使用示例代码 ```lua -- 导入nixio模块 local nixio = require "nixio" local nixio_fs = require "nixio.fs" -- 读取OpenWrt系统配置文件 local filename = "/etc/config/system" local content, err = nixio_fs.readfile(filename) -- 处理结果 if not content then print("读取失败: " .. err) else print("文件内容:") print(content) -- 示例:解析UCI配置中的时区 local timezone = content:match("option timezone '([^']+)'") print("系统时区: " .. (timezone or "未设置")) end ``` #### 代码解释: 1. **模块导入** - `require "nixio"` 加载核心I/O库 - `require "nixio.fs"` 加载文件系统子模块 2. **安全读取** - 使用`content, err`接收双返回值,避免因文件不存在导致脚本中断 3. **错误处理** - 当`content`为`nil`时,`err`包含错误描述(如`"No such file or directory"`) 4. **内容解析** - 示例中使用Lua字符串匹配提取UCI配置中的时区设置 --- ### 关键特性 1. **原子操作** 整个文件读取是原子的,适合小文件(建议<1MB) 2. **自动处理** 自动打开/关闭文件句柄,无需手动资源管理 3. **二进制安全** 可读取二进制文件(如图片),但返回的是Lua字符串 4. **路径限制** 路径需为绝对路径,相对路径基于当前工作目录(通常是`/`) --- ### 典型应用场景 1. 读取UCI配置文件(`/etc/config/*`) 2. 获取系统信息(`/proc/cpuinfo`, `/etc/openwrt_release`) 3. 读取小型的日志文件或状态文件 > ⚠️ **注意**:不适合大文件(如>10MB),可能耗尽内存。大文件应使用`nixio.fs.open()`流式读取。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值