mcpField
L
log-coverage-analyzer

log-coverage-analyzer

github.com/openharmonyinsightTesting & quality3589 installsUpdated 11w ago
Repository

About log-coverage-analyzer

log-coverage-analyzer is a skill for developers reviewing logging in code repositories. It checks branches and error returns across call chains, flags logging risks in frequently called functions, and produces a Markdown report.

Key features

  1. 01Check branch logging across call chains
  2. 02Verify LOGE on error return paths
  3. 03Flag logs in high-frequency functions
  4. 04Classify deficiencies by priority
  5. 05Generate Markdown reports with fixes

Use cases

  1. 01Review logs on error paths
  2. 02Check frequent logging in network callbacks
  3. 03Audit success logs in multi-step operations
  4. 04Produce a logging analysis report

Install

Copy the command and run it in a terminal.

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

After installing, type/log-coverage-analyzerin Claude Code to confirm it loaded.

Details

From the project README

This skill performs comprehensive log coverage analysis for code repositories. It identifies logging deficiencies in call chains and detects high-frequency log risks that may impact performance.

Analysis Principles

Log Level Definitions
Log LevelBehaviorUse Case
LOGEAlways prints, never lostCritical - Must exist on all error return paths
LOGIAlways prints, may be lost if high-frequency triggered at same locationImportant - Success paths, key operations
LOGDOnly prints when debug switch enabledOptional - Debug information only
LOGWOnly prints when debug switch enabledOptional - Warning information only
Core Analysis Rules
  1. Log Coverage Rule: Each branch in a function call chain must have LOGE or LOGI level logging
  2. High-Frequency Risk Rule: Functions that may be called frequently (loops, timers, callbacks, event handlers) with LOGE/LOGI logs pose performance risks
  3. Error Path Rule: All error return paths MUST have LOGE logging
  4. Context Rule: All logs must include sufficient context information (IDs, states, parameters)

Execution Workflow

Step 00: Create Analysis Plan

Description: Create detailed analysis plan before starting

Actions:

  • Use TodoWrite tool to create task list
  • Plan analysis scope:
    • Source file discovery and filtering
    • Function call chain extraction
    • Log coverage analysis per branch
    • High-frequency risk detection
    • Report generation

Output: Analysis plan created via TodoWrite tool

Step 01: Discover Source Files

Description: Find all relevant source files in the repository

Actions:

  • Use Glob tool to find source files based on language patterns:
    • C/C++: **/*.cpp, **/*.cc, **/*.cxx, **/*.h, **/*.hpp
    • Java: **/*.java
    • Python: **/*.py
    • JavaScript/TypeScript: **/*.js, **/*.ts
    • Go: **/*.go
    • Rust: **/*.rs
  • Exclude test files if specified (patterns: **/test/**, **/tests/**, **/*_test.*)
  • Exclude build directories (patterns: **/build/**, **/out/**, **/target/**)

Output: List of source files to analyze

Step 02: Scan Logging Patterns

Description: Scan all source files for logging macros/functions

Actions:

  • Use Grep tool to find log statements with pattern:
    • Case-insensitive search for: LOG[DEIW], HILOG[DEIW], ALOG[DEIW]
    • Also search for: \.log[deiw]\(, Log\.[deiw], LOG\.
  • Count occurrences per file
  • Identify log level distribution

Output: Log statistics per file

Step 03: Extract Functions and Call Chains

Description: Parse source files to extract function definitions and call relationships

Actions:

  • For each source file:
    • Identify function definitions (various patterns per language)
    • Extract function bodies including all branches
    • Identify function calls within each function
    • Build call chain graph
  • Map branch conditions (if/else, switch/case, try/catch, early returns)

Output: Function list with call relationships

Step 04: Analyze Log Coverage per Branch

Description: Check each branch in call chains for required logging

Actions:

  • For each function in call chain:
    • Identify all branches:
      • Early returns
      • if/else branches
      • switch/case branches
      • try/catch blocks
      • loop exits with error conditions
    • Check each branch for LOGE or LOGI presence
    • Flag branches without required logging as Log Deficiency
    • Check error return paths specifically for LOGE

Deficiency Classification:

  • High Priority: Error return path without LOGE
  • Medium Priority: Success path without LOGI for multi-step operations
  • Low Priority: Branch without any logging (non-critical)

Output: List of log deficiencies with locations

Step 05: Detect High-Frequency Log Risks

Description: Identify functions with LOGE/LOGI that may be called frequently

Actions:

  • Identify high-frequency function patterns:
    • Network data callbacks (OnDataReceived, OnPacketReceived, OnMessage)
    • Timer callbacks (OnTimer, Tick, Update)
    • Event handlers (HandleEvent, ProcessEvent, OnEvent)
    • Loop operations (ProcessItem, HandlePacket, SendData)
    • Stream processing (ProcessStream, HandleFrame, EncodeFrame)
    • Message queue handlers (OnMessage, Dispatch)
  • For functions with LOGE/LOGI in these patterns:
    • Analyze call frequency potential
    • Classify risk level: High/Medium/Low
    • Flag as High-Frequency Risk

Risk Classification:

  • High Risk: Per-packet/per-frame LOGE/LOGI in data path
  • Medium Risk: Per-message LOGI in messaging path
  • Low Risk: Low-frequency callbacks with logs

Output: List of high-frequency risks with locations

Step 06: Generate Analysis Report

Description: Create comprehensive analysis report with all findings

Actions:

  • Generate Markdown report with:
    1. Summary statistics
    2. Log deficiencies with fix suggestions
    3. High-frequency risks with fix suggestions
    4. Call chain analysis
    5. Detailed code examples
  • Use Write tool to save report to log-coverage-report-YYYYMMDD-HHmmss.md

Output: Complete analysis report

Language-Specific Patterns

C/C++

Function Definition Patterns:

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

Log Patterns:

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

Function Definition Patterns:

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

Log Patterns:

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

Function Definition Patterns:

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

Log Patterns:

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

Function Definition Patterns:

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

Log Patterns:

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

Fix Recommendations

For Log Deficiencies

Error Return Path (Must Fix):

// 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;
}

Success Path (Should Fix):

// 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;
}
For High-Frequency Risks

Remove High-Frequency 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
}

Use Throttled LOGE for Errors:

// 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;
    }
}

Output Format

================================================================================
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>

Impact: <explain impact on debugging/troubleshooting>

Fix:

<fixed code>

High-Frequency Risks

[High/Medium/Low] Risk

File: <file_path> Function: <function_name> Lines: <line_range> Risk:

Evidence:

<code snippet>

Analysis:

Fix:

<fixed code with throttling/statistics>

Call Chain Analysis

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

Legend:

  • ✓ : Has required LOGE/LOGI
  • ✗ : Missing required logging
  • ⚠️ : Has high-frequency log risk

Recommendations

Immediate Actions (P0)
Follow-up Actions (P1)
Long-term Improvements (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

Analyze current directory

/log-coverage-analyzer

Analyze specific repository

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

Analyze C++ code only

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

Include test files in analysis

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

Custom output location

/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

Comments

Markdown supported