2012-10-23 37 views
34

跟踪Gradle构建脚本中任务花费多长时间的最优雅方式是什么?在最佳的情况下登录时直接相同或下一行的任务名称跟踪gradle脚本中每个任务的执行时间?

:buildSrc:testClasses (0.518 secs) 
:fooBar (28.652 secs) 
+7

如果使用'--profile'参数运行gradle,它会在'build/reports/profile'中生成一个报告,其中包含任务执行时间......这足够好吗? –

+0

这是一个很好的报告,但需要额外的一步来收集所有构建相关信息,最好是分析我们Jenkins gradle作业的人可以直接看到执行时间。反正Thx! – ngeek

回答

14

最简洁的解决方案是实现一个TaskExecutionListener(我相信你能处理的部分),并与gradle.taskGraph.addTaskExecutionListener注册。

+0

谢谢,这听起来很合适,我仍然唯一缺少的是如何为所有任务注册监听器。 – ngeek

+0

你只需要注册一个监听器,一次。 –

+3

这是我结束的片段:https://gist.github.com/3939407 – ngeek

70

只是想详细说明另一个答案:我们想做同样的事情,并在 构建结束时报告时间,所以缓慢的步骤是显而易见的(适当的各方感觉到一小部分但健康的耻辱,当他们放慢建设!)。

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 

类似下面的代码,或完成后回落到您的顶级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() 
+2

Thx,这是一个很好的答案。超级有用的开箱即用。 – Snicolas

+1

有没有什么办法可以像插件或我可以很容易地添加到构建脚本而不会污染脚本?或者有没有其他方式可以以更清洁的方式来完成这个时机?谢谢! – ag0rex

+1

它可以以某种方式显示总时间,包括应用程序的安装时间(到设备/模拟器)? –

14

我知道这是一个古老的问题,但我发现一个很酷的插件,可以完成任务计时。这就像@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' 
     } 
    } 
} 
+1

即使适用于新的DSL的东西! –

7

这是已被修改,删除公开访问gradle这个Clock类,它已被否决的用法jlevy's answer above的变化。

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 

类似下面的代码,或完成后回落到您的顶级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()