mcpField
L
log-coverage-analyzer

log-coverage-analyzer

github.com/openharmonyinsight测试与质量3589 次安装11 周前更新
代码仓库

关于 log-coverage-analyzer

log-coverage-analyzer 是用于代码仓库的日志覆盖分析技能,面向需要检查日志完整性与性能风险的开发者。它沿调用链检查分支和错误返回路径,并识别高频函数中的日志风险,生成 Markdown 报告。

主要功能

  1. 01按调用链检查分支日志覆盖
  2. 02检查错误返回路径的 LOGE
  3. 03识别高频函数中的日志风险
  4. 04按优先级分类日志缺陷
  5. 05生成含修复建议的 Markdown 报告

适用场景

  1. 01审查代码中的错误路径日志
  2. 02排查网络回调中的高频日志
  3. 03检查多步骤操作的成功日志
  4. 04生成日志审计报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/openharmonyinsight/openharmony-skills --skill log-coverage-analyzer

安装后在 Claude Code 中输入/log-coverage-analyzer确认已加载。

详细介绍

此技能可对代码仓库进行全面的日志覆盖率分析,识别调用链中的日志缺失,并检测可能影响性能的高频日志风险。

分析原则

日志级别定义
日志级别行为使用场景
LOGE始终打印,不会丢失严重 - 所有错误返回路径都必须有此日志
LOGI始终打印;若同一位置触发频率过高,日志可能丢失重要 - 成功路径、关键操作
LOGD仅在启用调试开关时打印可选 - 仅用于调试信息
LOGW仅在启用调试开关时打印可选 - 仅用于警告信息
核心分析规则
  1. 日志覆盖规则:函数调用链中的每个分支都必须包含 LOGE 或 LOGI 级别的日志
  2. 高频风险规则:可能频繁调用(循环、定时器、回调、事件处理器)的函数中若包含 LOGE/LOGI 日志,则存在性能风险
  3. 错误路径规则:所有错误返回路径都必须包含 LOGE 日志
  4. 上下文规则:所有日志都必须包含足够的上下文信息(ID、状态、参数)

执行工作流

步骤 00:创建分析计划

说明:开始前创建详细的分析计划

操作:

  • 使用 TodoWrite 工具创建任务列表
  • 规划分析范围:
    • 查找并筛选源文件
    • 提取函数调用链
    • 分析各分支的日志覆盖情况
    • 检测高频风险
    • 生成报告

输出:通过 TodoWrite 工具创建分析计划

步骤 01:发现源文件

说明:查找仓库中所有相关源文件

操作:

  • 使用 Glob 工具,根据语言模式查找源文件:
    • C/C++:**/*.cpp、**/*.cc、**/*.cxx、**/*.h、**/*.hpp
    • Java:**/*.java
    • Python:**/*.py
    • JavaScript/TypeScript:**/*.js、**/*.ts
    • Go:**/*.go
    • Rust:**/*.rs
  • 如有指定,则排除测试文件(模式:**/test/**、**/tests/**、**/*_test.*)
  • 排除构建目录(模式:**/build/**、**/out/**、**/target/**)

输出:待分析的源文件列表

步骤 02:扫描日志模式

说明:扫描所有源文件中的日志宏/函数

操作:

  • 使用 Grep 工具,按以下模式查找日志语句:
    • 不区分大小写搜索:LOG[DEIW]、HILOG[DEIW]、ALOG[DEIW]
    • 同时搜索:\.log[deiw]\(、Log\.[deiw]、LOG\.
  • 统计每个文件中的出现次数
  • 确定日志级别分布

输出:各文件的日志统计信息

步骤 03:提取函数和调用链

说明:解析源文件,提取函数定义和调用关系

操作:

  • 对每个源文件:
    • 识别函数定义(各语言的不同模式)
    • 提取包含所有分支的函数体
    • 识别各函数中的函数调用
    • 构建调用链图
  • 映射分支条件(if/else、switch/case、try/catch、提前返回)

输出:包含调用关系的函数列表

步骤 04:分析各分支的日志覆盖情况

说明:检查调用链中的各个分支是否包含所需日志

操作:

  • 对调用链中的每个函数:
    • 识别所有分支:
      • 提前返回
      • if/else 分支
      • switch/case 分支
      • try/catch 块
      • 带错误条件的循环退出
    • 检查每个分支是否包含 LOGE 或 LOGI
    • 将缺少所需日志的分支标记为 日志缺失
    • 专门检查错误返回路径是否包含 LOGE

缺失分类:

  • 高优先级:错误返回路径缺少 LOGE
  • 中优先级:多步骤操作的成功路径缺少 LOGI
  • 低优先级:分支完全没有日志(非关键)

输出:包含位置的日志缺失列表

步骤 05:检测高频日志风险

描述:识别包含 LOGE/LOGI 且可能被频繁调用的函数

操作:

  • 识别高频函数模式:
    • 网络数据回调(OnDataReceived、OnPacketReceived、OnMessage)
    • 定时器回调(OnTimer、Tick、Update)
    • 事件处理程序(HandleEvent、ProcessEvent、OnEvent)
    • 循环操作(ProcessItem、HandlePacket、SendData)
    • 流处理(ProcessStream、HandleFrame、EncodeFrame)
    • 消息队列处理程序(OnMessage、Dispatch)
  • 对于这些模式中包含 LOGE/LOGI 的函数:
    • 分析潜在调用频率
    • 划分风险等级:高/中/低
    • 标记为高频风险

风险分类:

  • 高风险:数据路径中按数据包/帧记录 LOGE/LOGI
  • 中风险:消息路径中按消息记录 LOGI
  • 低风险:记录日志的低频回调

输出:列出高频风险及其位置

步骤 06:生成分析报告

描述:根据所有发现创建全面的分析报告

操作:

  • 生成 Markdown 报告,包含:
    1. 汇总统计信息
    2. 日志缺失项及修复建议
    3. 高频风险及修复建议
    4. 调用链分析
    5. 详细代码示例
  • 使用 Write 工具将报告保存到 log-coverage-report-YYYYMMDD-HHmmss.md

输出:完整的分析报告

特定语言模式

C/C++

函数定义模式:

[return_type] [class::]function_name([parameters]) {
[\w\s:*,]*\{

日志模式:

  • LOG[DEIW]\(、HILOG[DEIW]\(、ALOG[DEIW]\(
  • __android_log_print
  • OHOS::HiviewDFX::HiLog::[Error|Warn|Info|Debug]
Java

函数定义模式:

(public|private|protected)?(\s+static)?\s+\w+\s+\w+\s*\(.*\)\s*(throws\s+[\w\s,]+)?\s*\{

日志模式:

  • Log\.[deiw]\(
  • Logger\.(error|warn|info|debug)\(
  • Timber\.[deiw]\(
Python

函数定义模式:

def\s+\w+\s*\(.*\)\s*->?\s*.*:

日志模式:

  • logger\.(error|warning|info|debug)\(
  • logging\.(error|warning|info|debug)\(
  • print\(
JavaScript/TypeScript

函数定义模式:

function\s+\w+\s*\(.*\)\s*\{
|\w+\s*\([^)]*\)\s*(=>|\{)

日志模式:

  • console\.(error|warn|info|log)\(
  • logger\.(error|warn|info|debug)\(

修复建议

针对日志缺失项

错误返回路径(必须修复):

// BEFORE:
if (remote == nullptr) {
    return ERR_NULL_OBJECT;  // ❌ No LOGE
}

// AFTER:
if (remote == nullptr) {
    HILOGE("FunctionName: remote is null, context=%{public}d", context);
    return ERR_NULL_OBJECT;
}

成功路径(应该修复):

// BEFORE:
int32_t CreateSession(...) {
    // ... initialization code
    return ERR_OK;  // ❌ No LOGI on success
}

// AFTER:
int32_t CreateSession(...) {
    // ... initialization code
    HILOGI("CreateSession: success, sessionId=%{public}d, name=%{public}s", id, name);
    return ERR_OK;
}
针对高频风险

移除高频 LOGI:

// BEFORE:
void OnPacketReceived(int socketId, const void* data, uint32_t len) {
    HILOGI("packet received: socket=%{public}d, len=%{public}u", socketId, len);  // ⚠️ Per-packet
    // ... process packet
}

// AFTER:
void OnPacketReceived(int socketId, const void* data, uint32_t len) {
    // Removed per-packet LOGI
    static std::atomic<uint64_t> packetCount{0};
    if (++packetCount % 1000 == 1) {
        HILOGI("Packet stats: count=%{public}llu, socket=%{public}d",
            packetCount.load(), socketId);
    }
    // ... process packet
}

对错误使用限流 LOGE:

// BEFORE:
void ProcessPacket(const Packet* pkt) {
    if (pkt == nullptr) {
        HILOGE("packet is null");  // ⚠️ Per-packet error
        return;
    }
}

// AFTER:
void ProcessPacket(const Packet* pkt) {
    if (pkt == nullptr) {
        static std::atomic<uint32_t> errorCount{0};
        if (++errorCount % 100 == 1) {
            HILOGE("ProcessPacket: null packet, count=%{public}u", errorCount.load());
        }
        return;
    }
}

输出格式

================================================================================
Log Coverage Analysis Report
================================================================================

Repository: <repository_path>
Analysis Date: <timestamp>
Files Analyzed: <count>

## Summary Statistics

| Metric | Count |
|--------|-------|
| Total Source Files | <number> |
| Total Functions | <number> |
| Functions Analyzed | <number> |
| Log Deficiencies | <number> |
| High-Frequency Risks | <number> |

## Log Deficiencies

### [High/Medium/Low] Priority

**File**: `<file_path>`
**Function**: `<function_name>`
**Lines**: `<line_range>`
**Issue**: `<description>`

**Evidence**:
```cpp
<code snippet>

影响: <说明对调试/故障排查的影响>

修复:

<fixed code>

高频风险

[高/中/低] 风险

文件:<file_path> 函数:<function_name> 行号:<line_range> 风险:

证据:

<code snippet>

分析: <说明为何属于高频>

修复:

<fixed code with throttling/statistics>

调用链分析

调用链:<chain_name>
<function_1>()
    ↓ [✓/✗/⚠️] <log_status>
<function_2>()
    ↓ [✓/✗/⚠️] <log_status>
<function_3>()
    ├─ [✓/✗/⚠️] branch_1
    ├─ [✓/✗/⚠️] branch_2
    └─ [✓/✗/⚠️] branch_3

图例:

  • ✓:包含所需的 LOGE/LOGI
  • ✗:缺少所需日志
  • ⚠️:存在高频日志风险

建议

立即采取的措施(P0)

<关键事项列表>

后续措施(P1)

<重要事项列表>

长期改进(P2)

<改进建议列表>

================================================================================


## Parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `--path` | No | Repository path (default: current directory) |
| `--exclude-tests` | No | Exclude test files (default: true) |
| `--lang` | No | Language filter (cpp, java, python, js, all) |
| `--output` | No | Output report path |

## Usage Examples

分析当前目录

/log-coverage-analyzer

分析指定仓库

/log-coverage-analyzer --path /path/to/repo

仅分析 C++ 代码

/log-coverage-analyzer --lang cpp --path /path/to/repo

在分析中包含测试文件

/log-coverage-analyzer --exclude-tests false

自定义输出位置

/log-coverage-analyzer --output /path/to/report.md


## Tips

- Use `Grep` with `output_mode: content` and `-B/-C` flags for context
- Use `Read` tool with `offset` and `limit` for large files
- For large repositories, focus on critical directories first
- High-frequency risks should be prioritized over minor log deficiencies
- Always include context (IDs, states, parameters) in LOGE messages

评论

支持 Markdown