Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

log scenario index and name, and transaction index and name #552

Merged
merged 2 commits into from
Aug 17, 2023

Conversation

jeremyandrews
Copy link
Member

@jeremyandrews jeremyandrews commented Aug 16, 2023

Fixes #551 by including the following details in the request log:

  • scenario_index
  • scenario_name
  • transaction_index (optional)
  • transaction_name (optional)

Adding this information to the request log caused the GooseRequestMetric to grow statistically larger than the other members of the GooseMetric enum. Clippy recommended boxing it because of this:

% cargo clippy
    Checking goose v0.17.1-dev (devel/goose)
warning: large size difference between variants
  --> src/metrics.rs:46:1
   |
46 | / pub enum GooseMetric {
47 | |     Request(GooseRequestMetric),
   | |     --------------------------- the largest variant contains at least 280 bytes
48 | |     Transaction(TransactionMetric),
   | |     ------------------------------ the second-largest variant contains at least 72 bytes
49 | |     Scenario(ScenarioMetric),
50 | | }
   | |_^ the entire enum is at least 280 bytes
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
   = note: `#[warn(clippy::large_enum_variant)]` on by default
help: consider boxing the large fields to reduce the total size of the enum
   |
47 |     Request(Box<GooseRequestMetric>),
   |             ~~~~~~~~~~~~~~~~~~~~~~~

warning: `goose` (lib) generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 1.92s

Because transaction_index is optional it is represented as a String in the log instead of as a usize (whereas scenario_index is represented as a usize as it's always guaranteed to be set). If empty, it will show up as "", whereas "0" indicates the first transaction in the scenario.

For example, a snippet from a CSV-formatted request log:

elapsed,scenario_index,scenario_name,transaction_index,transaction_name,raw,name,final_url,redirected,response_time,status_code,success,update,user,error,coordinated_omission_elapsed,user_cadence
1,0,loadtest,0,,"GooseRawRequest { method: Get, url: ""http://127.0.0.1:62805/"", headers: [], body: """" }",/,http://127.0.0.1:62805/,false,2,200,true,false,0,,0,0
3,0,loadtest,1,,"GooseRawRequest { method: Get, url: ""http://127.0.0.1:62805/error"", headers: [], body: """" }",/error,http://127.0.0.1:62805/error,false,0,503,false,false,0,503 Service Unavailable: /error,0,0
4,0,loadtest,0,,"GooseRawRequest { method: Get, url: ""http://127.0.0.1:62805/"", headers: [], body: """" }",/,http://127.0.0.1:62805/,false,0,200,true,false,0,,0,0

Or similarly, a snippet from a JSON-formatted request log:

{"coordinated_omission_elapsed":0,"elapsed":0,"error":"","final_url":"http://127.0.0.1:62811/","name":"/","raw":{"body":"","headers":[],"method":"Get","url":"http://127.0.0.1:62811/"},"redirected":false,"response_time":2,"scenario_index":0,"scenario_name":"loadtest","status_code":200,"success":true,"transaction_index":"0","transaction_name":"","update":false,"user":0,"user_cadence":0}
{"coordinated_omission_elapsed":0,"elapsed":3,"error":"503 Service Unavailable: /error","final_url":"http://127.0.0.1:62811/error","name":"/error","raw":{"body":"","headers":[],"method":"Get","url":"http://127.0.0.1:62811/error"},"redirected":false,"response_time":0,"scenario_index":0,"scenario_name":"loadtest","status_code":503,"success":false,"transaction_index":"1","transaction_name":"","update":false,"user":0,"user_cadence":0}
{"coordinated_omission_elapsed":0,"elapsed":4,"error":"","final_url":"http://127.0.0.1:62811/","name":"/","raw":{"body":"","headers":[],"method":"Get","url":"http://127.0.0.1:62811/"},"redirected":false,"response_time":0,"scenario_index":0,"scenario_name":"loadtest","status_code":200,"success":true,"transaction_index":"0","transaction_name":"","update":false,"user":0,"user_cadence":0}

A raw-formatted request log:

GooseRequestMetric { elapsed: 0, scenario_index: 0, scenario_name: "loadtest", transaction_index: "0", transaction_name: "", raw: GooseRawRequest { method: Get, url: "http://127.0.0.1:62816/", headers: [], body: "" }, name: "/", final_url: "http://127.0.0.1:62816/", redirected: false, response_time: 3, status_code: 200, success: true, update: false, user: 0, error: "", coordinated_omission_elapsed: 0, user_cadence: 0 }
GooseRequestMetric { elapsed: 4, scenario_index: 0, scenario_name: "loadtest", transaction_index: "1", transaction_name: "", raw: GooseRawRequest { method: Get, url: "http://127.0.0.1:62816/error", headers: [], body: "" }, name: "/error", final_url: "http://127.0.0.1:62816/error", redirected: false, response_time: 0, status_code: 503, success: false, update: false, user: 0, error: "503 Service Unavailable: /error", coordinated_omission_elapsed: 0, user_cadence: 0 }
GooseRequestMetric { elapsed: 4, scenario_index: 0, scenario_name: "loadtest", transaction_index: "0", transaction_name: "", raw: GooseRawRequest { method: Get, url: "http://127.0.0.1:62816/", headers: [], body: "" }, name: "/", final_url: "http://127.0.0.1:62816/", redirected: false, response_time: 0, status_code: 200, success: true, update: false, user: 0, error: "", coordinated_omission_elapsed: 0, user_cadence: 0 }

And finally, a pretty-formatted request log:

GooseRequestMetric {
    elapsed: 0,
    scenario_index: 0,
    scenario_name: "loadtest",
    transaction_index: "0",
    transaction_name: "",
    raw: GooseRawRequest {
        method: Get,
        url: "http://127.0.0.1:62808/",
        headers: [],
        body: "",
    },
    name: "/",
    final_url: "http://127.0.0.1:62808/",
    redirected: false,
    response_time: 2,
    status_code: 200,
    success: true,
    update: false,
    user: 0,
    error: "",
    coordinated_omission_elapsed: 0,
    user_cadence: 0,
}
GooseRequestMetric {
    elapsed: 3,
    scenario_index: 0,
    scenario_name: "loadtest",
    transaction_index: "1",
    transaction_name: "",
    raw: GooseRawRequest {
        method: Get,
        url: "http://127.0.0.1:62808/error",
        headers: [],
        body: "",
    },
    name: "/error",
    final_url: "http://127.0.0.1:62808/error",
    redirected: false,
    response_time: 0,
    status_code: 503,
    success: false,
    update: false,
    user: 0,
    error: "503 Service Unavailable: /error",
    coordinated_omission_elapsed: 0,
    user_cadence: 0,
}
GooseRequestMetric {
    elapsed: 4,
    scenario_index: 0,
    scenario_name: "loadtest",
    transaction_index: "0",
    transaction_name: "",
    raw: GooseRawRequest {
        method: Get,
        url: "http://127.0.0.1:62808/",
        headers: [],
        body: "",
    },
    name: "/",
    final_url: "http://127.0.0.1:62808/",
    redirected: false,
    response_time: 0,
    status_code: 200,
    success: true,
    update: false,
    user: 0,
    error: "",
    coordinated_omission_elapsed: 0,
    user_cadence: 0,
}

@jeremyandrews jeremyandrews changed the title scenario idx and name, and transation idx and name log scenario index and name, and transation index and name Aug 16, 2023
@jeremyandrews jeremyandrews changed the title log scenario index and name, and transation index and name log scenario index and name, and transaction index and name Aug 16, 2023
@@ -1806,7 +1829,7 @@ impl GooseUser {
// [`test_start`](../struct.GooseAttack.html#method.test_start),
// [`test_stop`](../struct.GooseAttack.html#method.test_stop), and during testing.
if let Some(metrics_channel) = self.metrics_channel.clone() {
if let Err(e) = metrics_channel.send(GooseMetric::Request(request_metric)) {
if let Err(e) = metrics_channel.send(GooseMetric::Request(Box::new(request_metric))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I neglected to document this:

% cargo clippy
    Checking goose v0.17.1-dev (devel/goose)
warning: large size difference between variants
  --> src/metrics.rs:46:1
   |
46 | / pub enum GooseMetric {
47 | |     Request(GooseRequestMetric),
   | |     --------------------------- the largest variant contains at least 280 bytes
48 | |     Transaction(TransactionMetric),
   | |     ------------------------------ the second-largest variant contains at least 72 bytes
49 | |     Scenario(ScenarioMetric),
50 | | }
   | |_^ the entire enum is at least 280 bytes
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
   = note: `#[warn(clippy::large_enum_variant)]` on by default
help: consider boxing the large fields to reduce the total size of the enum
   |
47 |     Request(Box<GooseRequestMetric>),
   |             ~~~~~~~~~~~~~~~~~~~~~~~

warning: `goose` (lib) generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 1.92s

Copy link
Collaborator

@LionsAd LionsAd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RTBM - Looks good to me

One potentially unrelated thing.

@jeremyandrews jeremyandrews merged commit 3b59cbb into tag1consulting:main Aug 17, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

difficult to map users to scenarios, and requests to transactions
2 participants