# Capturing task output

**URL:** <https://discuss.gradle.org/t/capturing-task-output/39992>\
**Category:** Help/Discuss\
**Created:** [May 19, 2021, 2:57am UTC](https://discuss.gradle.org/t/capturing-task-output/39992 "2021-05-19T02:57:07Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![trejkaz](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/trejkaz/32/3338_2.png) [@trejkaz](https://discuss.gradle.org/u/trejkaz)\
**Post date:** [May 19, 2021, 2:57am UTC](https://discuss.gradle.org/t/capturing-task-output/39992/1 "2021-05-19T02:57:07Z")

</div>

How can I capture output of a task?

In this case, I’d like to capture the output of JavaCompile so that I can produce reports on the warning count. (If anyone knows of an existing plugin to do that, that would be even better, but I’ve already searched and couldn’t find anything.)

What I _can’t_ do is replace System.out, because other tasks may be running in parallel.

---

<div class="post-metadata">

**Author:** ![Pierre1](https://avatars.discourse-cdn.com/v4/letter/p/a8b319/32.png) [@Pierre1](https://discuss.gradle.org/u/Pierre1)\
**Post date:** [May 20, 2021, 8:51am UTC](https://discuss.gradle.org/t/capturing-task-output/39992/2 "2021-05-20T08:51:31Z")

</div>

Hello,

The user doc has a section on integration third party tools logs with Gradle builds here:

[https://docs.gradle.org/current/userguide/logging.html#sec:external\_tools](https://docs.gradle.org/current/userguide/logging.html#sec:external_tools)

When looking at the javadoc of the [LoggingManager (Gradle API 7.0.2)](https://docs.gradle.org/current/javadoc/org/gradle/api/logging/LoggingManager.html) you’ll notice that one can do more than redirecting streams with the add listener methods:

```groovy
tasks.named('compileTestJava', JavaCompile).configure {
    def warnings = project.layout.buildDirectory.file('compileTestJava.stderr')
    logging.addStandardErrorListener((StandardOutputListener) { CharSequence message ->
        warnings.get().asFile << message
    })
    options.compilerArgs << '-Xlint:all'
}

```

The nice thing with this code is its simplicity. The less nice thing is that it requires to open/close the underlying output stream for each line I think. If performance is paramount, maybe something like that could be better:

```groovy
ext {
    warningFile = null
}

tasks.named('compileTestJava', JavaCompile).configure {
    logging.addStandardErrorListener((StandardOutputListener) { CharSequence message ->
        warningFile << message
    })
    options.compilerArgs << '-Xlint:all'
}

gradle.taskGraph.addTaskExecutionListener(new TaskExecutionListener (){

    void beforeExecute(Task task) {
        if (task.name == 'compileTestJava') { // or task instanceof AbstractCompile
            File file = project.file("${project.buildDir}/${task.name}.stderr")
            file.parentFile.mkdirs()
            warningFile = file.newWriter()
        }
    }

    void afterExecute(Task task, TaskState state) {
        if (task.name == 'compileTestJava') { // reuse same condition as in beforeExecute
            warningFile?.close()
        }
    }
})

```

Both approaches should net the same result in the end:

```bash
[/tmp/foo]$ gradle clean test

> Task :compileTestJava
/tmp/foo/src/test/java/FooTest.java:8: warning: [rawtypes] found raw type: List
        List list = new ArrayList();
        ^
  missing type arguments for generic class List<E>
  where E is a type-variable:
    E extends Object declared in interface List
/tmp/foo/src/test/java/FooTest.java:8: warning: [rawtypes] found raw type: ArrayList
        List list = new ArrayList();
                        ^
  missing type arguments for generic class ArrayList<E>
  where E is a type-variable:
    E extends Object declared in class ArrayList
2 warnings

BUILD SUCCESSFUL in 1s
3 actionable tasks: 2 executed, 1 up-to-date
[/tmp/foo]$ cat build/compileTestJava.stderr 
/tmp/foo/src/test/java/FooTest.java:8: warning: [rawtypes] found raw type: List
        List list = new ArrayList();
        ^
  missing type arguments for generic class List<E>
  where E is a type-variable:
    E extends Object declared in interface List
/tmp/foo/src/test/java/FooTest.java:8: warning: [rawtypes] found raw type: ArrayList
        List list = new ArrayList();
                        ^
  missing type arguments for generic class ArrayList<E>
  where E is a type-variable:
    E extends Object declared in class ArrayList
2 warnings

```
