阅读专栏 · 实操指南

akashaProxy 问题排查:从两份日志和一次语法检查读证据

工作路径:/data/adb/akashaProxy/ 适用环境:Magisk / KernelSU (arm64-v8a)
开始阅读完整分步正文

改完配置执行热重载,结果什么都没变——规则不命中、流量路径照旧、面板依然打不开。这种局面不少人都遇到过,常见的反应是再改一遍、再执行一次重载,但往往还是原地踏步。现象相同,原因却可能完全不同。akashaProxy 问题排查的第一件事,是分清问题落在模块脚本层还是 mihomo 内核层。本篇只讨论三样东西:run/run.logs、run/kernel.log,以及 clash.tool -s 在热重载前执行的 mihomo -t 语法检查。安装过程、平台整体介绍、端口字段说明、插件机制、规则库结构这些内容,其他文章已经讲过了,这里不再重复。

akashaProxy 问题排查:akashaProxy 日志查看,两份文件各自记什么

akashaProxy 的工作目录下有两个日志文件,名字相近,很多人第一次接触时分不清该看哪一个。其实区分方式很简单:run/run.logs 是模块日志,记录模块脚本自身的执行过程;run/kernel.log 是内核日志,记录 mihomo 加载配置的加载情况和运行状态,可查看规则命中。它们不是同一个文件的两个部分,也不是先后的续写关系。

手机旁两个齿轮的检查主题示意
示意图:先区分运行设置与配置内容,再检查变化。

模块脚本负责把配置交给内核,内核负责实际执行代理逻辑。脚本在读取配置、处理热重载命令、调用内核时出了状况,痕迹会留在 run/run.logs。内核在解析配置、监听端口、处理规则时出了问题,信息会写进 run/kernel.log。所以做 akashaProxy 日志查看时,正确做法是把两个文件同时打开,按时间对照着读,而不是只盯住其中一个。

举个例子:执行热重载命令后,终端没有显示任何错误,但网络行为毫无变化。这时候打开 run/run.logs,可能会看到脚本确实接收并处理了重载动作。再翻 run/kernel.log,如果里面有配置解析失败或者端口无法监听的记录,那问题大概率出在 config.yaml 的内容上。反过来,如果内核日志显示配置正常加载、规则顺利更新,但 run/run.logs 里有脚本在某个环节报错的痕迹,那就要去看看是不是脚本流程本身卡住了。

读日志时最重要的是时间点。不要从头翻到尾,找热重载执行时刻前后的内容就够。旧错误和新错误要分开看,启动阶段的报错和热重载后的报错性质不同。同一行错误信息,出现在不同时间点,指向的结论可能完全相反。

akashaProxy 语法检查:先过关,才有重载

在 akashaProxy 的热重载链路里,clash.tool -s 执行前会先进行 mihomo -t 语法检查,不通过则不生效。这个顺序很多人没有意识到,恰恰是「改了没反应」的关键所在。

mihomo -t 检查的是配置文件能不能被正常解析,包括缩进、字段写法、结构是否完整这类层面。config.yaml 里存在解析错误时,检查不会通过,clash.tool -s 也就不会把这份配置交给正在运行的内核。旧配置继续执行,用户看到的现象就是:内容确实改过了,重载命令确实执行了,行为却一点没变。这不是模块失灵,而是语法检查挡住了错误的配置进入运行状态。

需要说清楚的是,mihomo -t 通过只代表配置「可解析」,不代表配置「符合意图」。一个代理组名称写错了,只要格式合法,语法检查很可能照样通过,因为从解析角度看它没有毛病。这类偏差要等配置加载之后,在内核日志的规则命中记录里才会暴露出来。所以遇到 akashaProxy 热重载失败,第一份要看的证据就是 mihomo -t 的输出,第二份才是加载后的内核日志。

排查顺序:先确认改动进了链路,再缩小范围

「修改配置后没生效」是一个宽泛的描述,直接动手改文件很容易越改越乱。建议先确认改动是否真正进入了运行链路,再逐步向具体层面收敛。

三块错落排列的日志信息卡片示意
示意图:把模块日志和内核日志中的信息分开阅读。

第一步,确认热重载命令是否真正执行。这一步不是看命令有没有报错,而是看模块是否有响应。命令执行完毕且没有明显错误信息,只说明没有语法问题阻止这次操作,不代表配置已经生效。

第二步,看 run/run.logs 的末尾部分。这里能确认模块脚本有没有记录这次热重载动作。有记录,说明脚本层没有卡住。没有相关条目,可能是命令没有作用到当前的模块实例,或者日志写入有延迟。先别急着下结论,继续看另一边。

第三步,看 run/kernel.log 的末尾部分。这里能看出 mihomo 是否重新加载了配置,加载过程中有没有报错。解析错误、监听失败、资源找不到,这些都会在这里留下记录。有错误,问题在配置本身或者相关资源上;一切正常,问题就可能出在规则逻辑层面——配置加载成功,但实际分流结果不符合预期。

第四步,回到文件本身。clash.config 用于模块启动配置,包含开机自启、代理模式和插件等;config.yaml 是 mihomo 配置文件,config.example.yaml 是默认配置模板。如果你改的是 clash.config,却一直在检查 config.yaml 的内容,自然会得出「改了没生效」的错觉。两个文件职责不同,排查前先确认自己动的是哪一个,这是最简单也最容易被跳过的一步。

第五步,确认改的是 config.yaml,mihomo -t 通过,内核日志没有异常,但行为仍不符合预期。到了这一步,问题已经脱离「有没有生效」的范畴,进入「生效结果对不对」的范畴。此时可以通过内核日志查看规则命中情况,确认某个具体请求走了哪条规则、进了哪个代理组。这是最后一步,不是第一步。

记录一次改动:比反复尝试更有效

排查问题期间,最消耗时间的行为不是看日志,而是随手改配置,改完就重载,重载完又改,几轮下来自己都记不清动了什么。与其这样,不如养成记录每一次改动的习惯。

记录的内容不需要复杂:改的是哪个文件、改动之前是什么、改成什么、什么时候执行的热重载。这几项写在纸面上或者在文本编辑器里留几行,就能给后续的日志对照提供时间锚点。热重载之后去看日志,拿着改动的时间点来定位记录,效率会高很多。如果改了几次都不成功,这份记录也能帮你看出自己是不是一直在同一个地方打转。

记录还有另一个作用:避免同时动多个文件。一次只改一个文件、只改一处内容,出了问题定位起来要快得多。如果同时改了 config.yaml、clash.config 和其他列表文件,日志里出现异常时你根本分不清是哪一处改动引起的。把改动拆小,配合记录,排查路径会清晰很多。

何时回到配置文档

排查进入僵局时,一个容易被忽视的动作是回到配置文档本身,而不是继续在日志里翻找。日志告诉你发生了什么,文档告诉你应该怎样。两者参照着看,很多疑惑会自然消解。

比如你不确定某个写法是否被支持,翻一下 mihomo 的配置文档或者官方提供的默认模板,比猜测要可靠。config.example.yaml 是默认配置模板,它本身就是一份可以对照的参考。你写的字段和模板有什么差异、结构上是否有遗漏,对比一下就清楚。与其在历史记录里找原因,不如直接用文档校正自己的理解。

当然,回到文档不等于照着抄模板。文档适合用来确认「某件事应该怎么做」,不适合用来解释「为什么我的环境里没生效」。前者是规范,后者是状态。规范的答案在文档里,状态的答案在日志里。两个视角都要有。

整理问题但不暴露私人信息

向别人描述问题时,怎么在不泄露私人信息的前提下把情况说清楚,是一件需要练习的事。很多人在求助时要么信息给得太少,别人无法判断;要么把整个配置文件原样贴出来,里面带着订阅地址、节点名称甚至一些能识别身份的内容,这就有风险了。

正确的做法是脱敏之后再描述。订阅地址和节点名称属于敏感信息,描述问题时需要模糊处理或者用代号代替,比如「第一个代理组引用的节点没有定义」这类表述就够了。重要的不是具体内容,而是结构和关系。配置文件中的字段结构、改动前后的差异、语法检查的输出、两份日志在热重载时间点前后的片段,这些才是判断问题所需的核心信息。私人信息不参与判断,自然也就没有必要暴露。

整理问题时,建议按时间顺序把证据串起来:什么时候改了什么,执行热重载后的命令输出是什么,run/run.logs 里出现了什么,run/kernel.log 里出现了什么。这样一条时间线摆出来,问题往往已经露出了轮廓。

什么时候问题在配置层

mihomo -t 不通过,问题在配置层,这没什么疑问。mihomo -t 通过了,但内核日志显示加载失败,问题也在配置层,只是性质从语法错误变成了运行时错误。mihomo -t 通过,内核日志也显示加载成功,但规则命中结果不对,这仍然属于配置层的问题,只是从能不能加载变成了加载得对不对。配置层问题的表现方式有差异,但排查的切入点是一样的:看语法检查结果,看内核加载记录。

模块脚本自身的问题,线索多半在 run/run.logs 里。脚本执行中断、某个步骤没有走完、调用内核失败,这些都会留下痕迹。热重载失败时如果语法检查正常、内核日志也没有异常,回头看一下模块日志里有没有脚本层面的报错信息,往往能找到被忽略的一环。

收敛问题所需的最少信息

akashaProxy 问题排查的主路径可以归纳为:确认改的是哪个文件,执行 clash.tool -s,同时打开 run/run.logs 与 run/kernel.log 按时间对照,先看 mihomo -t 的语法检查结果,再根据内核日志判断配置是否被真正加载,最后才进入规则逻辑的分析。akashaProxy 日志查看的重点是热重载时间点前后的内容,而不是把整个文件从头翻到尾。

真正需要聚集的信息只有三项:改动的是哪个文件、语法检查的完整输出、两份日志在热重载时间点前后的片段。不要在信息不全时反复执行重载或者删掉配置重来。把这三样握在手里,大部分「配置改了没生效」的情况都能在较短时间内收敛到具体的层面。该改语法就改语法,该查脚本就查脚本,该调规则就调规则。排查的意义从来不是碰运气,而是让每一个判断都有对应的证据支撑。