在gradle脚本中跟踪每个任务的执行时间?

nge*_*eek 42 java groovy gradle jenkins

跟踪任务在gradle构建脚本中花费的时间的执行时间最优雅的方法是什么?在最佳情况下,记录与任务名称直接相同或下一行的时间

:buildSrc:testClasses (0.518 secs)
:fooBar (28.652 secs)
Run Code Online (Sandbox Code Playgroud)

jle*_*evy 85

只是详细说明另一个答案:我们想要做同样的事情,以及在构建结束时的报告时间,所以缓慢的步骤是显而易见的(当他们放慢速度时,适当的各方会感到一点点但又有点健康的羞耻感构建!).

BUILD SUCCESSFUL

Total time: 1 mins 37.973 secs
Task timings:
    579ms  :myproject-foo:clean
  15184ms  :myproject-bar:clean
   2839ms  :myproject-bar:compileJava
  10157ms  :myproject-bar:jar
    456ms  :myproject-foo:compileJava
    391ms  :myproject-foo:libs
    101ms  :myproject-foo:jar
    316ms  :myproject-bar:compileTestJava
    364ms  :myproject-foo:compileTestJava
  53353ms  :myproject-foo:test
   2146ms  :myproject-bar:test
   8348ms  :www/node:npmInstall
    687ms  :www/node:npmTest
Run Code Online (Sandbox Code Playgroud)

下面的代码可以放到您的顶层,build.gradle以便在执行期间或完成后报告时间.

// Log timings per task.
class TimingsListener implements TaskExecutionListener, BuildListener {
    private Clock clock
    private timings = []

    @Override
    void beforeExecute(Task task) {
        clock = new org.gradle.util.Clock()
    }

    @Override
    void afterExecute(Task task, TaskState taskState) {
        def ms = clock.timeInMs
        timings.add([ms, task.path])
        task.project.logger.warn "${task.path} took ${ms}ms"
    }

    @Override
    void buildFinished(BuildResult result) {
        println "Task timings:"
        for (timing in timings) {
            if (timing[0] >= 50) {
                printf "%7sms  %s\n", timing
            }
        }
    }

    @Override
    void buildStarted(Gradle gradle) {}

    @Override
    void projectsEvaluated(Gradle gradle) {}

    @Override
    void projectsLoaded(Gradle gradle) {}

    @Override
    void settingsEvaluated(Settings settings) {}
}

gradle.addListener new TimingsListener()
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这是一个很好的答案.超级开箱即用. (4认同)
  • 有什么办法可以像一个插件或一些我可以轻松添加到构建脚本而不污染脚本的东西吗?或者有没有其他方法可以以更干净的方式进行计时?谢谢! (4认同)

Pet*_*ser 17

最干净的解决方案是实现TaskExecutionListener(我确信你可以处理那个部分)并注册它gradle.taskGraph.addTaskExecutionListener.


And*_*Gil 17

我知道这是一个老问题,但我找到了一个很酷的插件来完成任务计时.这就像@jlevy的回答,但有更多的选择:https://github.com/passy/build-time-tracker-plugin

Pascal Hartig的这个插件会不断记录您的构建时间并提供CSV和条形图摘要.开发人员建议它用于监视一段时间内的构建时间,而不是--profile为您提供当前构建的快照.

这就是我目前使用它的方式:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "net.rdrei.android.buildtimetracker:gradle-plugin:0.7.+"
    }
}

apply plugin: "build-time-tracker"

buildtimetracker {
    reporters {
        summary {
            ordered false
            threshold 50
            barstyle 'unicode'
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*Jon 14

这是jlevy上面回答的变体,该变体已被修改以删除Clock已弃用的可公开访问的gradle 类的使用.

BUILD SUCCESSFUL

Total time: 1 mins 37.973 secs
Task timings:
    579ms  :myproject-foo:clean
  15184ms  :myproject-bar:clean
   2839ms  :myproject-bar:compileJava
  10157ms  :myproject-bar:jar
    456ms  :myproject-foo:compileJava
    391ms  :myproject-foo:libs
    101ms  :myproject-foo:jar
    316ms  :myproject-bar:compileTestJava
    364ms  :myproject-foo:compileTestJava
  53353ms  :myproject-foo:test
   2146ms  :myproject-bar:test
   8348ms  :www/node:npmInstall
    687ms  :www/node:npmTest
Run Code Online (Sandbox Code Playgroud)

下面的代码可以放到您的顶层,build.gradle以便在执行期间或完成后报告时间.

import java.util.concurrent.TimeUnit
// Log timings per task.
class TimingsListener implements TaskExecutionListener, BuildListener {
    private long startTime
    private timings = []

    @Override
    void beforeExecute(Task task) {
        startTime = System.nanoTime()
    }

    @Override
    void afterExecute(Task task, TaskState taskState) {
        def ms = TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
        timings.add([ms, task.path])
        task.project.logger.warn "${task.path} took ${ms}ms"
    }

    @Override
    void buildFinished(BuildResult result) {
        println "Task timings:"
        for (timing in timings) {
            if (timing[0] >= 50) {
                printf "%7sms  %s\n", timing
            }
        }
    }

    @Override
    void buildStarted(Gradle gradle) {}

    @Override
    void projectsEvaluated(Gradle gradle) {}

    @Override
    void projectsLoaded(Gradle gradle) {}

    @Override
    void settingsEvaluated(Settings settings) {}
}

gradle.addListener new TimingsListener()
Run Code Online (Sandbox Code Playgroud)


M. *_*tin 10

--profile标志将生成一份配置文件报告。生成的 HTML 文件包括一个“任务执行”选项卡,其中包含每个任务的计时。

$ gradle build --profile

BUILD SUCCESSFUL in 21s
6 actionable tasks: 6 executed

See the profiling report at: file:///path/to/gs-spring-boot/complete/build/reports/profile/profile-2021-08-09-16-22-40.html
A fine-grained performance profile is available: use the --scan option.
Run Code Online (Sandbox Code Playgroud)

这在在线命令行界面文档中有记录

在目录中生成高级性能报告$buildDir/reports/profile--scan是优选的。

任务执行输出

任务 期间 结果
20.046秒 (全部的)
:编译Java 9.221秒
:测试 6.492秒
:编译测试Java 3.161秒
:bootJarMainClassName 0.813秒
:bootJar 0.338秒
:罐 0.017秒
:流程资源 0.003秒 无源
:课程 0.001秒 没有工作
:集合 0秒 没有工作
:建造 0秒 没有工作
:查看 0秒 没有工作
:processTest资源 0秒 无源
:测试类 0秒 没有工作

Gradle 构建扫描

--profile选项及其文档都建议使用该--scan选项来生成构建扫描。这会生成扫描并将其发布到scans.gradle.com。除了将构建详细信息传输到 Gradle 构建扫描外部服务之外,还需要接受Gradle 服务条款

$ gradle build --scan

BUILD SUCCESSFUL in 0s
7 actionable tasks: 7 executed

Publishing a build scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service.
Do you accept these terms? [yes, no] yes

Gradle Terms of Service accepted.

Publishing build scan...
https://gradle.com/s/5u4w3gxeurtd2
Run Code Online (Sandbox Code Playgroud)

扫描输出

7 秒内执行了 4 个项目中的 61 个任务,其中避免了 10 个任务,节省了 4.231 秒

:buildSrc:编译Kotlin 3.584秒
:应用程序:测试 0.745秒
:列表:测试 0.742秒
:list:编译Java 0.062秒
:实用程序:编译Java 0.054秒
:app:启动脚本 0.049秒


Abh*_*kar 6

我从passy/build-time-tracker-plugin开始创建了一个插件不再主动维护。我的也打印 ASCII 条形图,并带有自定义选项。

\n

https://github.com/asarkar/build-time-tracker

\n
== Build time summary ==\n :commons:extractIncludeProto | 4.000s | 14% | \xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\n       :commons:compileKotlin | 2.000s |  7% | \xe2\x96\x88\xe2\x96\x88\n         :commons:compileJava | 6.000s | 21% | \xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\n:service-client:compileKotlin | 1.000s |  4% | \xe2\x96\x88\n        :webapp:compileKotlin | 1.000s |  4% | \xe2\x96\x88\n     :webapp:dockerBuildImage | 4.000s | 14% | \xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\n      :webapp:dockerPushImage | 4.000s | 14% | \xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88\n
Run Code Online (Sandbox Code Playgroud)\n