Gatling logback file ignored by gradle.build

I’m calling Gatling as a JavaExec task from a Gradle build script. The project follows traditional java structure (src/main and src/test at top levels), and I have placed my Gatling logback and other configuration files directly under src/test/resources (no conf folder anymore).

The gradle build script also has a sourceSets declaration in build.gradle, and I’ve added a custom task to print out location of each test classpath file. The println statements indicate that my files in test/resources are being found by the runtime classpath.

However, when I run the Gatling task (which is of type JavaExec), the logging level of my logback.xml is ignored by Gradle. For example I’ve set the logback file to “log failed request and response only”, but when I run the task, the console shows INFO statements for every single thing Gatling does. I think the host project is set at a more verbose level to support a requirement of operations for their monitoring tools, so it seems any fix I implement would need to be done from the Gatling side.

One thing I have noticed is when I run Gatling task, the console displays a series of warnings about “multiple classpath bindings” for slf4j. I have some a number of Gradle projects that use Gatling and others that do not. This warning only appears when Gatling is part of the project, so it makes me wonder if a Gatling dependency is triggering this conflict with the host project. It looks as if stronger measures are needed to isolate Gatling’s runtime configuration from the Gradle project’s runtime when sourcecode for both lives in the same project space.

What are my options for making my resource configuration files visible to io.gatling.app.Gatling?
I mentioned isolation because that seemed most natural, but there might be others, and I’m open to suggestions.

Hi Nadine,

Can you post the the code of your Gatling task here please ?

There is one not so funny thing about files in classpaths : Java pickups individual JARs in the classpath, but not individual ressources…
Meaning that you can have “-cp lib/foo.jar:lib/baz.jar” instead of “-cp lib/*” but you cannot have “-cp src/test/resources/logback.xml”.
Java only pickups resources in a folder, so your classpath must be “-cp foo.jar:bar.jar:src/test/resources”.

One the topic of isolation: isolating Gatling is possible, maybe desirable, but this would mean that you cannot share code between the “main” project and Gatling, should you need it.
But, as long as Gatling and its dependencies are scoped to be only test dependencies and therefore do not mess up with the “main” project, this should be safe.

Cheers,

Pierre

Hi Pierre:
The code for my Gradle task is here >

task gatlingPerformance(type: JavaExec, dependsOn: gatlingSmoke) {
description = ‘Runs a single gatling test as gradle task’
classpath = sourceSets.test.runtimeClasspath
main = “io.gatling.app.Gatling”
args = Eval.me("[’-s’, ‘simulations.BlueGreenSimulation’, " +

// set up Gatling tree so the jar can find things
“’-bf’, ‘src/test/resources/request-bodies’,” +
“’-df’, ‘src/test/resources/data’,” +
“’-sf’, ‘src/test/scala/simulations’,” +
“’-rf’, ‘${buildDir}/reports/gatling’]”
)

}

That’s not it : you don’t need to package your ressources in a JAR but make sure that the classpath does not contains each ressources individually, but the whole resources folder.

Java doesn’t pickup single files in the classpath, unless they’re JARs.

Some examples :

java -cp lib/foo.jar:lib/bar.jar:lib/quz.jar <mainClass>

=> Works : JARs are specified individually, but the’yre JARs, so this works.

java -cp lib/* <mainClass>

=> Works : this time, all JARs in the lib folder are picked up at one, rather than specifying them indivudually.

java -cp lib/*:conf/logback.xml:conf/gatling.conf <mainClass>

=> Doesn’t work : JARs in the lib folder are picked up, but conf/logback.xml and conf/gatling.conf won’t be : they’re individual files, but not JARs.

java -cp lib/*:conf <mainClass>

=> Works : this time, resources and not added to the classpath one by one, but all at once, by adding the whole conf folder to the classpath.

Just make sure, by printing out the classpath for example, that sourceSets.test.runtimeClasspath does not specify each resources file individually, but the whole resources folder instead.

Otherwise, you may need to add the resource folder explicitly to the classpath :

`

task gatlingPerformance(type: JavaExec, dependsOn: gatlingSmoke) {
description = ‘Runs a single gatling test as gradle task’
classpath = sourceSets.test.runtimeClasspath
classpath += sourceSets.test.resources
main = “io.gatling.app.Gatling”
args = Eval.me("[’-s’, ‘simulations.BlueGreenSimulation’, " +

// set up Gatling tree so the jar can find things
“’-bf’, ‘src/test/resources/request-bodies’,” +
“’-df’, ‘src/test/resources/data’,” +
“’-sf’, ‘src/test/scala/simulations’,” +
“’-rf’, ‘${buildDir}/reports/gatling’]”
)

}

`

BTW, I may miss something, but I believe that your resource folder configuration should rather be :

`

test {
resources {
srcDir = “src/test/resources”
}
}

`

But, as Gradle’s Scala Plugin add them automatically, it might not be a bad idea to rely on this plugin to setup sourceSets and compile your simulations and use Gatling’s -sbf option to specify the folder containing your compiled classes.
This way, Gradle handles your project, the compilation of the simulations and Gatling’s only task is to run your simulations.
As a matter of fact, that’s how I went when implementing the SBT plugin : let the build tool build, let Gatling fire at will :wink:

Hope this helps !

Cheers,

Pierre

Good catch on the classpath. In this particular project, I had been messing around with the sourceSets values and not restored it.

However, I will try removing it completely and letting the Scala plugin do its job

@Pierre Another question on this. What are the main issues with creating an official Gatling plugin for Gradle?

Would having a plugin help alleviate this issue?

There isn’t any real issues with creating an official Gradle plugin : I just need some time to learn a bit of Gradle and write the plugin :slight_smile:

Envoyé de mon iPhone

" I just need some time to learn a bit of Gradle and write the plugin :slight_smile: "

Don't we all!

In general, I like Gradle , but a few things about it infuriate me. This is one of them.

My configuration settings are still not being followed, but I've slacked off on working this until another logging issue gets resolved in our host project. I'm hoping the fix will also fix my problem.