DEV Community

Query Filter
Query Filter

Posted on

bridge6

import java.text.DecimalFormat

task generateProfilerReport {
    group = "Verification"
    description = "Aggregates profiler data with configurable latency flags and coverage summary."

    def csvFile = file("$buildDir/profiler-results/profiler_combined_report.csv")
    def targetsFile = file("${projectDir}/profiler_targets.txt") 
    def reportFile = file("$buildDir/profiler-results/performance_summary.txt")

    doLast {
        // --- Configuration Logic ---
        // Usage: ./gradlew generateProfilerReport -Pthreshold=50
        def thresholdStr = project.findProperty("threshold") ?: "100"
        double threshold = thresholdStr.toDouble()

        if (!targetsFile.exists()) {
            throw new GradleException("Target list not found at ${targetsFile.absolutePath}")
        }

        def aggregated = [:]
        targetsFile.eachLine { line ->
            def trimmed = line.trim()
            if (!trimmed.isEmpty() && !trimmed.startsWith("#")) {
                aggregated[trimmed] = [0L, 0.0d] 
            }
        }

        if (csvFile.exists()) {
            csvFile.eachLine { line, index ->
                if (index <= 1 || line.trim().isEmpty()) return
                def parts = line.split(',')
                if (parts.length >= 5) {
                    def methodWithClass = parts[1]
                    def calls = parts[2].toLong()
                    def totalMs = parts[4].toDouble()

                    if (aggregated.containsKey(methodWithClass)) {
                        def current = aggregated[methodWithClass]
                        aggregated[methodWithClass] = [current[0] + calls, current[1] + totalMs]
                    } else {
                        aggregated[methodWithClass] = [calls, totalMs]
                    }
                }
            }
        }

        int totalTargets = aggregated.size()
        int executedTargets = aggregated.values().count { it[0] > 0 }
        double coveragePercent = totalTargets > 0 ? (executedTargets / (double)totalTargets) * 100 : 0

        def sortedResults = aggregated.entrySet().sort { a, b -> 
            b.value[1] <=> a.value[1] ?: b.value[0] <=> a.value[0] ?: a.key <=> b.key 
        }

        def reportHeader = """
================================================================================
PROFILER FULL REPORT: ${new Date().format('yyyy-MM-dd HH:mm:ss')}
Threshold: > ${threshold}ms | Source: ${csvFile.exists() ? csvFile.name : "NO DATA FOUND"}
================================================================================
${String.format("%-55s | %8s | %10s | %10s | %s", "Method Name", "Calls", "Total MS", "Avg MS", "Flag")}
--------------------------------------------------------------------------------"""

        StringBuilder reportBody = new StringBuilder()
        sortedResults.each { entry ->
            def method = entry.key
            def calls = entry.value[0]
            def totalMs = entry.value[1]
            def avgMs = (calls > 0) ? (totalMs / calls) : 0.0d
            def flag = (avgMs > threshold) ? "⚠️ SLOW" : ""

            reportBody.append(String.format("%-55s | %8d | %10.2f | %10.4f | %s\n", 
                method, calls, totalMs, avgMs, flag))
        }

        def summaryFooter = """
--------------------------------------------------------------------------------
COVERAGE SUMMARY:
Total Methods Tracked: ${totalTargets}
Methods Executed:      ${executedTargets}
Coverage Percentage:   ${String.format("%.2f", coveragePercent)}%
================================================================================"""

        def finalReport = reportHeader + "\n" + reportBody.toString() + summaryFooter

        println finalReport
        reportFile.parentFile.mkdirs()
        reportFile.text = finalReport
        println "\n[REPORT]: Saved to ${reportFile.absolutePath}"
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)