Electron netLog 模块实战:为 Session 网络事件录制日志(含 --log-net-log 开关与源码剖析) Electron netLog 模块实战为 Session 网络事件录制日志含 --log-net-log 开关与源码剖析【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron在排查 Electron 应用的网络问题时netLog模块提供了一种原生的、基于 Chromium 网络栈的抓包手段它能把某个 session 在任意时间段内发生的全部网络事件以 JSON 格式落盘供事后分析。本文以 docs/api/net-log.md 为骨架完整覆盖startLogging/stopLogging/currentlyLogging三个 API 的参数与语义、全程抓包的--log-net-log命令行开关并结合 C 实现、JS 包装层 与 官方测试讲清楚这些 API 在底层究竟做了什么、有哪些边界条件和错误路径。模块概览与快速上手netLog是主进程Main process模块用于为 session 记录网络事件。最简用法如下继承自官方文档const { app, netLog } require(electron) app.whenReady().then(async () { await netLog.startLogging(/path/to/net-log) // After some network events const path await netLog.stopLogging() console.log(Net-logs written to, path) })需要注意两条前提所有方法都只能在app的ready事件之后调用文档中的 NOTE 明确标注独立的netLog模块实际上是session模块上netLog属性的门面。从 lib/browser/api/net-log.ts 可以看到每个方法内部都先判断app.isReady()然后把调用转发给session.defaultSession.netLog。文件头部的注释也说明该独立模块已被标记为Deprecate and remove standalone netLog module, it is now a property of session module即netLog现已是session的属性。因此在实际应用中更推荐直接使用session.fromPartition(...).netLog来精确控制要记录哪个会话的网络事件。C 侧对应地通过 electron_api_session.cc 将netLog属性挂到Session对象上.SetProperty(netLog, Session::NetLog)每个ElectronBrowserContext各持有一个NetLog实例。netLog.startLogging(path[, options])pathstring - 网络日志的写入文件路径。optionsObject (optional)captureModestring (optional) - 决定捕获哪些种类的数据。默认只捕获请求的元数据metadata。设为includeSensitive时会包含 cookie 和认证数据设为everything时会包含 socket 上流转的全部字节。可选值default、includeSensitive、everything。maxFileSizenumber (optional) - 当日志增长超过该大小时自动停止记录。默认为不限制unlimited。返回Promisevoid当 net log 开始记录后 resolve。captureMode 三档的底层映射captureMode字符串并不是 Electron 自定义的概念而是直接映射到 Chromium 网络栈的net::NetLogCaptureMode枚举。electron_api_net_log.cc 中注册了一个 gin 类型转换器逐一完成字符串到枚举的映射if (type default) *out net::NetLogCaptureMode::kDefault; else if (type includeSensitive) *out net::NetLogCaptureMode::kIncludeSensitive; else if (type everything) *out net::NetLogCaptureMode::kEverything; else return false;转换器遇到非法值时返回false上层随即抛出Invalid value for captureMode的 TypeError。spec/api-net-log-spec.ts 中的测试印证了这一行为传入{ captureMode: aoeu }、{ maxFileSize: null }或空path都会同步抛错。三档模式的实际差异也被测试逐档验证过includeSensitive下测试用net.request手动设置Cookie: foouuid头发起请求stopLogging后读取 dump 文件断言文件内容确实包含foouuid见 api-net-log-spec.ts 第 90-106 行everything下测试发起 POST 并在 body 中写入随机 UUID然后断言 dump JSON 的events数组中存在某条事件其params.bytesbase64 解码后包含该 UUID 字节见 api-net-log-spec.ts 第 108-127 行。由此可以确认日志文件是一个 JSON 结构顶层有events数组每条事件带paramseverything模式的 socket 字节以 base64 形式存放在params.bytes中。maxFileSize 的默认值与单实例约束C 实现中两个选项都有明确的默认值electron_api_net_log.cc 第 96-124 行net::NetLogCaptureMode capture_mode net::NetLogCaptureMode::kDefault; uint64_t max_file_size network::mojom::NetLogExporter::kUnlimitedFileSize;即文档中maxFileSize默认为 unlimited在源码中的落点是kUnlimitedFileSize常量。此外还有两条容易踩坑的运行时约束测试均有覆盖同一 session 同时只能有一个 net log 在跑。StartLogging开头检查if (net_log_exporter_)已存在直接抛出There is already a net log running的 TypeErrorstopLogging没有对应的进行中记录时会 reject错误信息为No net log in progress见 StopLogging 实现 与 spec 第 78-80 行。落盘流程Mojo NetLogExporter 与文件任务线程从源码结构看startLogging的完整调用链StartLogging / StartNetLogAfterCreateFile是校验参数path为空字符串时抛出The first parameter must be a valid string解析options中的captureMode和maxFileSize建立 Mojo 管道通过browser_context_-GetDefaultStoragePartition()-GetNetworkContext()拿到该 session 对应的NetworkContext调用CreateNetLogExporter(...)创建一个network::mojom::NetLogExporter远程端——真正的事件采集与写文件逻辑由 Chromium 的 network service 承担Electron 只负责传递参数和接收回调异步创建输出文件文件打开操作被投递到一个专用的SequencedTaskRunner上base::ThreadPool::CreateSequencedTaskRunner带base::MayBlock()与SKIP_ON_SHUTDOWN标志。源码注释解释了原因该 runner 上的任务只做同步文件 I/O检查路径、设置文件权限而这些操作在关闭阶段可以安全跳过因为FileNetLogObserver的 API 并不要求它们已完成启动导出文件创建成功后调用net_log_exporter_-Start(file, custom_constants, capture_mode, net::NetLogFileFormat::kJson, max_file_size, ...)注意日志格式被固定为kJsoncustom_constants中写入了进程命令行字符串和Electron 版本的 channel 信息便于事后分析时确认日志来源Promise 收敛启动回调NetLogStarted收到 Chromium 返回的net::OK才 resolve若文件创建失败则以base::File::ErrorToString(error_details)为消息 rejectMojo 管道断开OnConnectionError时则以Failed to start net log exporterreject。这个设计的实际含义await startLogging()成功返回意味着网络 service 端的 exporter 已经真正开始捕获事件而不是任务已提交。netLog.stopLogging()返回Promisevoid当日志刷新flush到磁盘后 resolve。停止记录网络事件如果不主动调用net log 会在应用退出时自动结束。C 侧的一个实现细节值得注意Stop的回调通过std::move(net_log_exporter_)把 Mojo 远程端整体移入回调闭包第 207-218 行以保证在 Promise resolve 之前 mojo pointer 存活同时让成员变量置空——这也是currentlyLogging能在stopLogging之后立即变为false的原因IsCurrentlyLogging只是返回!!net_log_exporter_。测试 spec/api-net-log-spec.ts 第 68-76 行 验证了最基础的生命周期startLogging后currentlyLogging为truestopLogging之后 dump 文件确实存在于磁盘。netLog.currentlyLogging只读boolean属性表示当前是否正在记录网络日志。JS 侧包装lib/browser/api/net-log.ts在app未 ready 时直接返回falseC 侧则查询是否存在活跃的net_log_exporter_。该属性适合用于条件分支例如只有尚未开启记录时才启动。命令行开关--log-net-logpath覆盖整个应用生命周期如果需要从进程启动那一刻就开始记录而不是等到ready之后可以在启动 Electron 时传入--log-net-logpath开关它使 net log 事件被保存并写入path见 docs/api/command-line-switches.md。在应用内部也可以用app.commandLine.appendSwitch(log-net-log, path)达到同样效果。测试夹具 spec/fixtures/api/net-log/main.js 展示了完整的组合玩法const { app, net, session } require(electron); if (process.env.TEST_DUMP_FILE) { app.commandLine.appendSwitch(log-net-log, process.env.TEST_DUMP_FILE); } // ... app.whenReady().then(async () { const netLog session.defaultSession.netLog; if (process.env.TEST_DUMP_FILE_DYNAMIC) { await netLog.startLogging(process.env.TEST_DUMP_FILE_DYNAMIC); } await request(); if (process.env.TEST_MANUAL_STOP) { await netLog.stopLogging(); } app.quit(); });围绕这段代码api-net-log-spec.ts 设计了三个进程级测试覆盖了三种生命周期组合场景开关API 调用验证点仅命令行开关--log-net-log无应用退出后 dump 文件自动落盘开关 API 并存--log-net-logstartLoggingstopLogging两份 dump 文件同时生成互不干扰仅 API无仅startLogging不调用stopLogging时退出时自动结束并落盘注意这三个进程级测试用ifit(process.platform ! linux)做了平台限定——Linux 平台上不会执行其余平台macOS、Windows上执行。实用建议与边界总结结合文档与源码使用netLog时的注意事项时机startLogging/stopLogging必须在appready 之后调用要捕获启动阶段的网络活动用--log-net-log开关或在ready前appendSwitch作用范围是 session 级每个ElectronBrowserContextpartition有独立的NetLog实例记录session.fromPartition(p1)的日志不会影响defaultSession敏感数据includeSensitive会写入 cookie 与认证数据everything会写入 socket 明文字节——日志文件本质上是明文敏感信息的载体仅应在本机调试环境使用不要随包分发磁盘控制长时间记录或高频流量场景下建议显式设置maxFileSize避免日志无限增长默认kUnlimitedFileSize格式与分析dump 文件是 Chromium netlog 的标准 JSON 格式顶层events数组 自定义常量区其中包含 Electron 版本与完整命令行可直接用 Chromium 的 netlog 查看器打开分析错误处理stopLogging在无进行中记录时 reject、重复startLogging抛 TypeError、文件路径不可写时以底层文件错误 reject生产代码中应对这些 Promise 做catch处理。相关源码与测试索引内容路径API 文档docs/api/net-log.mdJS 包装层委托给 sessionlib/browser/api/net-log.tsC 核心实现Mojo exporter 调用链shell/browser/api/electron_api_net_log.ccC 头文件类结构定义shell/browser/api/electron_api_net_log.h--log-net-log开关说明docs/api/command-line-switches.md单元/进程级测试spec/api-net-log-spec.ts测试夹具开关 API 组合示例spec/fixtures/api/net-log/main.js【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考