diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..e69de29b diff --git a/src/main/groovy/com/avast/gradle/dockercompose/ComposeExecutor.groovy b/src/main/groovy/com/avast/gradle/dockercompose/ComposeExecutor.groovy index 2e0a917f..a10470e3 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/ComposeExecutor.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/ComposeExecutor.groovy @@ -19,6 +19,14 @@ class ComposeExecutor { this.logger = settings.project.logger } + void executeWithCustomOutputWithExitValue(OutputStream os, String... args) { + executeWithCustomOutput(os, false, args) + } + + void executeWithCustomOutputNoExitValue(OutputStream os, String... args) { + executeWithCustomOutput(os, true, args) + } + private void executeWithCustomOutput(OutputStream os, Boolean ignoreExitValue, String... args) { def ex = this.settings project.exec { ExecSpec e -> @@ -33,7 +41,10 @@ class ComposeExecutor { } finalArgs.addAll(args) e.commandLine finalArgs - e.standardOutput = os + if( null != os ) { + e.standardOutput = os + e.errorOutput = os + } e.ignoreExitValue = ignoreExitValue } } diff --git a/src/main/groovy/com/avast/gradle/dockercompose/ComposeSettings.groovy b/src/main/groovy/com/avast/gradle/dockercompose/ComposeSettings.groovy index fd6deeee..72551b8e 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/ComposeSettings.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/ComposeSettings.groovy @@ -3,6 +3,7 @@ package com.avast.gradle.dockercompose import com.avast.gradle.dockercompose.tasks.ComposeBuild import com.avast.gradle.dockercompose.tasks.ComposeDown import com.avast.gradle.dockercompose.tasks.ComposeDownForced +import com.avast.gradle.dockercompose.tasks.ComposeLogs import com.avast.gradle.dockercompose.tasks.ComposePull import com.avast.gradle.dockercompose.tasks.ComposePush import com.avast.gradle.dockercompose.tasks.ComposeUp @@ -24,6 +25,7 @@ class ComposeSettings { final ComposeDownForced downForcedTask final ComposeBuild buildTask final ComposePull pullTask + final ComposeLogs logsTask final ComposePush pushTask final Project project final DockerExecutor dockerExecutor @@ -69,6 +71,9 @@ class ComposeSettings { String dockerComposeWorkingDirectory = null Duration dockerComposeStopTimeout = Duration.ofSeconds(10) + File composeLogToFile = null + String containerLogToDir = null + ComposeSettings(Project project, String name = '') { this.project = project @@ -82,6 +87,8 @@ class ComposeSettings { downTask.settings = this downForcedTask = project.tasks.create(name ? "${name}ComposeDownForced" : 'composeDownForced', ComposeDownForced) downForcedTask.settings = this + logsTask = project.tasks.create(name ? "${name}ComposeLogs" : 'composeLogs', ComposeLogs) + logsTask.settings = this pushTask = project.tasks.create(name ? "${name}ComposePush" : 'composePush', ComposePush) pushTask.settings = this @@ -193,6 +200,14 @@ class ComposeSettings { captureContainersOutputToFile = file } + void setComposeLogToFile(CharSequence path) { + composeLogToFile = project.file(path) + } + + void setComposeLogToFile(File file) { + composeLogToFile = file + } + boolean removeOrphans() { composeExecutor.version >= VersionNumber.parse('1.7.0') && this.removeOrphans } diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDownForced.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDownForced.groovy index e70f8ecf..a09d8cfa 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDownForced.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeDownForced.groovy @@ -45,7 +45,13 @@ class ComposeDownForced extends DefaultTask { } args += settings.downAdditionalArgs } - settings.composeExecutor.execute(args) + def composeLog = null + if(settings.composeLogToFile) { + logger.debug "Logging docker-compose down to: ${settings.composeLogToFile}" + settings.composeLogToFile.parentFile.mkdirs() + composeLog = new FileOutputStream(settings.composeLogToFile) + } + settings.composeExecutor.executeWithCustomOutputWithExitValue(composeLog, args) } else { if (!settings.startedServices.empty) { settings.composeExecutor.execute(*['rm', '-f', *settings.startedServices]) diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeLogs.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeLogs.groovy new file mode 100644 index 00000000..b3106c0b --- /dev/null +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeLogs.groovy @@ -0,0 +1,32 @@ +package com.avast.gradle.dockercompose.tasks + +import com.avast.gradle.dockercompose.ComposeSettings +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.TaskAction + +class ComposeLogs extends DefaultTask { + + ComposeSettings settings + + ComposeLogs() { + group = 'docker' + description = 'Records log output from services in containers of docker-compose project' + } + + @TaskAction + void logs() { + + if( !settings.containerLogToDir ) { + println 'Not recording container logs: containerLogToDir not specified.' + return + } + + settings.composeExecutor.serviceNames.each { service -> + println "Extracting container log from service '${service}'" + new File(settings.containerLogToDir).mkdirs() + def logStream = new FileOutputStream("${settings.containerLogToDir}/${service}.log") + String[] args = ['logs', '-t', service] + settings.composeExecutor.executeWithCustomOutputWithExitValue(logStream, args) + } + } +} diff --git a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeUp.groovy b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeUp.groovy index 2781e643..f4c43a8c 100644 --- a/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeUp.groovy +++ b/src/main/groovy/com/avast/gradle/dockercompose/tasks/ComposeUp.groovy @@ -60,7 +60,13 @@ class ComposeUp extends DefaultTask { } args += settings.startedServices try { - settings.composeExecutor.execute(args) + def composeLog = null + if(settings.composeLogToFile) { + logger.debug "Logging docker-compose up to: ${settings.composeLogToFile}" + settings.composeLogToFile.parentFile.mkdirs() + composeLog = new FileOutputStream(settings.composeLogToFile) + } + settings.composeExecutor.executeWithCustomOutputWithExitValue(composeLog, args) startCapturing() def servicesToLoad = settings.startedServices ?: settings.composeExecutor.getServiceNames() servicesInfos = loadServicesInfo(servicesToLoad).collectEntries { [(it.name): (it)] } diff --git a/src/test/groovy/com/avast/gradle/dockercompose/DockerComposePluginTest.groovy b/src/test/groovy/com/avast/gradle/dockercompose/DockerComposePluginTest.groovy index 702bca2b..b5e76d58 100644 --- a/src/test/groovy/com/avast/gradle/dockercompose/DockerComposePluginTest.groovy +++ b/src/test/groovy/com/avast/gradle/dockercompose/DockerComposePluginTest.groovy @@ -3,6 +3,7 @@ package com.avast.gradle.dockercompose import com.avast.gradle.dockercompose.tasks.ComposeBuild import com.avast.gradle.dockercompose.tasks.ComposeDown import com.avast.gradle.dockercompose.tasks.ComposeDownForced +import com.avast.gradle.dockercompose.tasks.ComposeLogs import com.avast.gradle.dockercompose.tasks.ComposePull import com.avast.gradle.dockercompose.tasks.ComposePush import com.avast.gradle.dockercompose.tasks.ComposeUp @@ -26,6 +27,7 @@ class DockerComposePluginTest extends Specification { project.tasks.composePull instanceof ComposePull project.tasks.composePush instanceof ComposePush project.tasks.composeBuild instanceof ComposeBuild + project.tasks.composeLogs instanceof ComposeLogs project.extensions.findByName('dockerCompose') instanceof ComposeExtension } @@ -45,6 +47,7 @@ class DockerComposePluginTest extends Specification { project.tasks.nestedComposePull instanceof ComposePull project.tasks.composePush instanceof ComposePush project.tasks.nestedComposeBuild instanceof ComposeBuild + project.tasks.nestedComposeLogs instanceof ComposeLogs ComposeUp up = project.tasks.nestedComposeUp up.settings.useComposeFiles == ['test.yml'] } @@ -126,6 +129,7 @@ class DockerComposePluginTest extends Specification { project.tasks.integrationTestComposePull instanceof ComposePull project.tasks.integrationTestComposePush instanceof ComposePush project.tasks.integrationTestComposeBuild instanceof ComposeBuild + project.tasks.integrationTestComposeLogs instanceof ComposeLogs ComposeUp up = project.tasks.integrationTestComposeUp up.settings.useComposeFiles == ['test.yml'] task.dependsOn.contains(project.tasks.integrationTestComposeUp)