2012-10-23 36 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()