Logging details on failure response or status is not 200

Hi,

In a test scenario, I will pass some query parameters for a webservice call. And in the scenario I will use the status check as follows:

scnAAA = scenario(“Scenario AAA”).
repeat(10) {
feed(csvFeederL).

exec(
http(“Doing step AAA”).
get(“serviceX/funA”).
headers(sendHeadersServiceX).
queryParam(p1, “${p1}”).
queryParam(p2, currentTimeStr).
queryParam(p3, “T1S”).
check(status.is(200)).

check (new MyValidations("${requiredKeysLen}")))

In the above scenario, I am setting parameters to webservice url. The problem is with check(status.is(200).

After this check, if the response not found or status not 200, then the rest of the activities are will not be executed. I am not able to capture the reason for failure in the logs.

I want to do something like this:

if( status is not 200 || or no response at all){
Log.info ("Failed for params p1, p2. p3)
}

I am not able to do the above check.

Appreciate if anyone can help me as I am new to galtiling.

Thanks,
Hanumesh

Hi,

https://github.com/excilys/gatling/wiki/Configuration#wiki-config-files

See logback.xml file for enabling debug logs.

Regards,

Stéphane

Hi Stephane,

Thanks for your response. For my debugging purposes I can do that. But I am writing the specific processing details of data, which has failed, to enabling identifying the exact failure case.
For instance, I am adding one more column in simulations.log file, which records the specific case (Ex. key parameter) for which record fails. I later use this file for communicating the failure cases.

When I want to introspect myself, I do enable DEBUG option from logback.xml

I am writing functional tests, which should log information on specific failure cases in either my logFile or simulations.log file which I process futher. But when the response status is 404 for example, my service method returns me null, and due to the check status.is(200), I am not able to log, the failures.

I wanted to write my own check where I can log information, when the response code is not 200.

Thankss,

Hanumesh

Writing your own Checks would require some Scala skills. Are you confident with this?

Another solution would be to use Gatling 2’s HttpProtocol.extraInfoExtractor whose signature is (Status, Session, Request, Response) => List[Any], so you can dump whatever you want depending on Status.

Writing your own Checks would require some Scala skills. Are you confident with this?

Another solution would be to use Gatling 2’s HttpProtocol.extraInfoExtractor whose signature is (Status, Session, Request, Response) => List[Any], so you can dump whatever you want depending on Status.

Yes… I am familiar with Scala. ( and Gatling 1.4.6). I am trying something like this as well:

scnAAA = scenario(“Scenario AAA”).
repeat(10) {
feed(csvFeederL).

exec(
http(“Doing step AAA”).
get(“serviceX/funA”).
headers(sendHeadersServiceX).
queryParam(p1, “${p1}”).
queryParam(p2, currentTimeStr).
queryParam(p3, “T1S”).
check(new CheckStatus(“${p1}”)).

//check(status.is(200)).

check (new MyValidations(“${requiredKeysLen}”)))

class CheckStatus(pid: EvaluatableString) extends HttpCheck(contentId, ChkStatus.matcher, None, CompletePageReceived)

object ChkStatus {
val matcher = new Matcher[ExtendedResponse, String] {

def apply(feedValue: Session => String, session: Session, response: ExtendedResponse) = {

var pid = feedValue(session)

println("pid: XXXXXXXXXXXXXXXXXXXXXX " + pid)

val body = response.getResponseBody(configuration.simulation.encoding)
if (body != null) {
println("XXXXXXXXXXX: body not null - success "+ body)
Success(Some(“Encoding check passed!”))
} else {
printLogFile("No response. Operation failed for pid: " + pid)
println("No response. Operation failed for pid: : " + pid)

Failure("check failed (Not 200) for pid: " + pid)
}

}
}
}

But my log file dont have entries like ‘No response. Operation failed for pid: 1010
Even Simulation.log will have msg as follows:
Check ‘is’ failed, found 404 but expected 200
But missing the key identifier pid (1010).

Can you suggest any workaround for this?

Thanks,
Hanumesh

First, I’m impressed you could dig into this part of the code. That’s not something very clean in Gatling 1 and it has gone under major refactoring in Gatling 2.

In your sample, check(status.is(200)) is commented, yet you say you got a “Check ‘is’ failed, found 404 but expected 200”. Are you sure the 2 informations are in sync?

If check(status.is(200)) is commented, you should get a found 404 but expected 200 to 210 (or something close). The reason is that if there’s not status check, Gatling automatically adds one (https://github.com/excilys/gatling/wiki/Checks#wiki-status).
In Gatling 1, this is implemented by checking if there’s a check on StatusReceived. Note that your custom check is on CompletePageReceived.

If you want to get rid of this, you can add a status.whatever check: you’ll have a defined status check, yet it will never fail, so that your custom check that happens later on CompletePageReceived will be reached.

Cheers,

Stéphane

Sorry , I need to correct.
if I place check(status.is(200) instead, then the log records as “Check ‘is’ failed, found 404 but expected 200

I tried if I can do adding additional identifier to the above log in my own function.
So I commented check(status.is(200)) and added my own function check(new CheckStatus("${p1}")).

But in either case, the result is the same, i.e, when there is no response(failure case) the control is not coming to Failure part (Failure("check failed (Not 200) for pid: " + pid))

And I am not able to refer status inside my function (CheckStatus) nor can pass status when there is no response.

And now I realize as you indicated, Gatling is adding status check implicitly, which is the reason, its not invoking my function at all but already skipped due to internal status check.

Just curious to know, when is the internal status check invoked? If its at the last and when no status check is found, then it should have executed my function statusCheck(), which is not the case but.

And I cant pass status check to my function as response itself is null. So can you advice what should I do?

Thanks,
Hanumesh

The default status check is added when the Simulation is loaded and the scenario built: https://github.com/excilys/gatling/blob/1.5.1/gatling-http/src/main/scala/com/excilys/ebi/gatling/http/action/HttpRequestActionBuilder.scala#L41

Checks are resolved in an ordered way: Status, Headers … Body. A failure interrupts the chain.

I still don’t understand when you say “response itself is null”. Is it the response, or the response’s body?

response body is null.

Did you try adding a status.whatever check as I suggested?
Be also aware that by default, if there’s no CompletePageReceived check, chuncks are discarded early, so the response body is null: https://github.com/excilys/gatling/wiki/HTTP#wiki-custom-dump disableResponseChunksDiscarding

I used the following alternative way to make it work:

scnAAA = scenario(“Scenario AAA”).
repeat(10) {
feed(csvFeederL).
exec(
http(“Doing step AAA”).
get(“serviceX/funA”).
headers(sendHeadersServiceX).
queryParam(p1, “${p1}”).
queryParam(p2, currentTimeStr).
queryParam(p3, “T1S”).
check(status.lessThan(600)). // continue whatever be the status code
check(new CheckStatus("${p1}")). // do my validation and record the logs
check(status.is(200)). //This check is to bypass the next check if status is not 200
check (new MyValidation2("${requiredKeysLen}")).
check (new MyValidation3("${requiredKeysLen}")))

The drawback with the above approach:
An extra check check(status.lessThan(600))

Thanks,
Hanumesh

Hi Hanumesh and Stephane,

I am new to Gatling I have exp in load runner and Jmeter. I am looking for the same concept. If my login transaction(response contain success) is passed . or it will fail the login transaction ineed to print the “username”, “curenttime”,vuserid, Can you pls help on this?

I guess this can help sou.
https://james-willett.com/2018/05/debug-gatling/

Thanks, the given link is very useful

Hi Falvio,

How to pass the unique userid for my script.
For example, I run for 10 users for 1 hour.i have 10 user id in my csv file. if the first user takes first user id (2nd iteration also take 1 userid ), 2nd user takes 2 userid …10 users takes 10 userid . Please help on this how to set this

import scala.concurrent.duration._

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import com.redis._
import io.gatling.redis.feeder.RedisFeeder

class RecordedSimulation extends Simulation {
val redisPool = new RedisClientPool(“localhost”, 6379)

val feeder = RedisFeeder(redisPool, “userid”)

val httpProtocol = http
.baseURL(“http://xxxxxxxxxxxxxxxxxxxx”)
.inferHtmlResources(BlackList("""..js""", “”"..css""", “”"..gif""", “”"..jpeg""", “”"..jpg""", “”"..ico""", “”"..woff""", “”"..(t|o)tf""", “”"..png"""), WhiteList())
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,
/*;q=0.8")
.acceptEncodingHeader(“gzip, deflate”)
.acceptLanguageHeader(“en-US,en;q=0.5”)
.userAgentHeader(“Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0”)

val headers_0 = Map(“Upgrade-Insecure-Requests” → “1”,

“Accept” → “/”,
“Pragma” → “no-cache”,
“X-Content-Type-Options” → “nosniff”,
“X-Frame-Options” → “DENY”,
“Upgrade-Insecure-Requests” → “1”,
“Content-Type” → “application/x-www-form-urlencoded”,
“Accept-Encoding” → “gzip,deflate”,
“Accept-Language” → “en-US,en;q=0.9”,
“X-XSS-Protection” → “1”)

val headers_1 = Map(
“Accept” → “/”,
“Pragma” → “no-cache”,
“X-Content-Type-Options” → “nosniff”,
“X-Frame-Options” → “DENY”,
“Upgrade-Insecure-Requests” → “1”,
“Content-Type” → “application/x-www-form-urlencoded”,
“Accept-Encoding” → “gzip,deflate”,
“Accept-Language” → “en-US,en;q=0.9”,
“X-XSS-Protection” → “1”)

val uri1 = “http://detectportal.firefox.com/success.txt
val uri2 = “http://xxxxxxx:xxxx/SampleApplication”
val userCredentials = csv(“User.csv”).queue //.circular //.random //.record(

val scn = scenario(“RecordedSimulation”)

// AppLaunch
.exec(http(“AppLaunch”)
.get("/SampleApplication/login")
.headers(headers_0)
.check(

.resources(http(“AppLaunch”)
.get(uri2 + “”)
.headers(headers_1)))
.pause(16)

.
// Login
.feed(userCredentials)
.exec(http(“Login”)
.post("/SampleApplication/login")
.headers(headers_0)
.formParam(“ssoId”, “${userid}”)
.formParam(“password”,"${password}")
.formParam("_csrf", “${personId}”))
.pause(48)

What you need to do is compose your requests into objects. You can see how in
AdvancedSimulationStep04.scala file that come with gatling, Look for the simulations directory.