web-dev-qa-db-fra.com

Suivre le temps d'exécution par tâche dans le script Gradle?

Quel est le moyen le plus élégant de suivre les temps d’exécution sur la durée d’une tâche dans un script de construction gradle? Dans un cas optimal, enregistrez l'heure directement identique ou la ligne suivante du nom de la tâche

:buildSrc:testClasses (0.518 secs)
:fooBar (28.652 secs)
37
ngeek

La solution la plus propre consiste à implémenter un TaskExecutionListener (je suis sûr que vous pouvez gérer cette partie) et l'enregistrer avec gradle.taskGraph.addTaskExecutionListener.

16
Peter Niederwieser

Juste pour préciser l’autre réponse: nous voulions faire la même chose, ainsi qu’un rapport à la fin du , Donc les étapes lentes sont évidentes (et les parties concernées se sentent un peu petites mais en bonne santé). honte quand ils ralentissent la construction!).

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

Quelque chose comme le code ci-dessous peut être déposé dans votre build.gradle de niveau supérieur pour signaler les temps au cours de l'exécution ou à la fin.

// 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()
77
jlevy

Je sais que c’est une vieille question, mais j’ai trouvé un plugin intéressant qui effectue le chronométrage des tâches. C'est comme @jlevy répondre, mais avec quelques options supplémentaires disponibles: https://github.com/passy/build-time-tracker-plugin

Ce plugin de Pascal Hartig enregistre en permanence vos temps de construction et fournit des résumés CSV et histogrammes. Le développeur le recommande pour surveiller vos temps de génération au fil du temps, par rapport à --profile qui vous donne un instantané de la construction actuelle.

Voici comment je l'utilise actuellement:

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'
        }
    }
}
15
André Gil

Ceci est une variante de la réponse de jlevy ci-dessus qui a été modifiée pour supprimer l'utilisation de la classe gradable Clock de niveau accessible au public, qui a été obsolète.

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

Quelque chose comme le code ci-dessous peut être déposé dans votre build.gradle de niveau supérieur pour signaler les temps au cours de l'exécution ou à la fin.

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()
13
Jon

Un tri simple rendrait la solution de @ jlevy encore meilleure.
En outre, pour une application de production typique, le seuil de 50 ms est trop bas.
Nous nous intéressons généralement aux tâches qui prennent plus d'une seconde.
project/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(new Tuple2<Integer, String>(ms, task.path))
        task.project.logger.warn "${task.path} took ${ms}ms"
    }

    @Override
    void buildFinished(BuildResult result) {
        println "Task timings:"
        def tmp = timings.toSorted(new Comparator<Tuple2<Integer, String>>() {
            @Override
            int compare(Tuple2<Integer, String> o, Tuple2<Integer, String> t1) {
                return o.first - t1.first
            }
        })
        for (timing in tmp) {
            if (timing.first >= 1000) {
                printf "%ss  %s\n", timing.first / 1000, timing.second
            }
        }
    }

    @Override
    void buildStarted(Gradle gradle) {}

    @Override
    void projectsEvaluated(Gradle gradle) {}

    @Override
    void projectsLoaded(Gradle gradle) {}

    @Override
    void settingsEvaluated(Settings settings) {}
}

gradle.addListener new TimingsListener()

Sortie du terminal: 

BUILD SUCCESSFUL in 14m 33s
948 actionable tasks: 419 executed, 476 from cache, 53 up-to-date
Task timings:
1.036s  :cbl-config:mergeMyAppDebugResources
1.187s  :express:bundleMyAppDebug
1.199s  :country:testMyAppDebugUnitTest
1.214s  :core-for-test:extractMyAppDebugAnnotations
1.242s  :analytics:testMyAppDebugUnitTest
1.308s  :express:extractMyAppDebugAnnotations
1.33s  :availability:dataBindingExportBuildInfoMyAppDebug
1.357s  :app:transformNativeLibsWithStripDebugSymbolForMyAppDebug
1.405s  :hermes:generateMyAppDebugBuildConfig
1.56s  :availability:testMyAppDebugUnitTest
1.65s  :app:javaPreCompileMyAppDebugUnitTest
1.749s  :chat:compileMyAppDebugJavaWithJavac
1.858s  :cbl-config-for-test:compileMyAppDebugJavaWithJavac
2.027s  :cbl-config:compileMyAppDebugJavaWithJavac
2.056s  :analytics-for-test:compileMyAppDebugJavaWithJavac
2.447s  :crypto:compileMyAppDebugJavaWithJavac
2.45s  :crypto:testMyAppDebugUnitTest
2.47s  :chat:javaPreCompileMyAppDebugUnitTest
2.639s  :crypto-for-test:dataBindingExportBuildInfoMyAppDebug
2.683s  :test-utils:compileMyAppDebugJavaWithJavac
3.056s  :crypto:lintMyAppDebug
3.227s  :app:transformNativeLibsWithMergeJniLibsForMyAppDebug
3.272s  :express:testMyAppDebugUnitTest
3.394s  :crypto:mergeMyAppDebugResources
3.426s  :core:testMyAppDebugUnitTest
4.299s  :multicity:testMyAppDebugUnitTest
4.333s  :app:packageMyAppDebug
4.584s  :availability-for-test:compileMyAppDebugJavaWithJavac
4.672s  :app:transformResourcesWithMergeJavaResForMyAppDebug
4.786s  :map:lintMyAppDebug
5.309s  :country:lintMyAppDebug
5.332s  :job:lintMyAppDebug
5.389s  :map:testMyAppDebugUnitTest
6.04s  :express:lintMyAppDebug
6.584s  :hermes:lintMyAppDebug
6.707s  :app:transformClassesWithMultidexlistForMyAppDebug
7.052s  :multicity:lintMyAppDebug
8.044s  :multicity:compileMyAppDebugJavaWithJavac
8.87s  :app:transformDexArchiveWithDexMergerForMyAppDebug
9.371s  :uikit:testMyAppDebugUnitTest
9.429s  :availability:lintMyAppDebug
13.12s  :app:compileMyAppDebugUnitTestKotlin
16.276s  :hermes:testMyAppDebugUnitTest
16.898s  :chat:testMyAppDebugUnitTest
17.174s  :job:testMyAppDebugUnitTest
36.008s  :grab-junior:testMyAppDebugUnitTest
96.88s  :app:compileMyAppDebugJavaWithJavac
125.693s  :app:lintMyAppDebug
145.538s  :app:transformClassesWithDexBuilderForMyAppDebug
182.752s  :app:testMyAppDebugUnitTest
0
ericn