tag1consulting / goose

Load testing framework, inspired by Locust
https://tag1.com/goose
Apache License 2.0
799 stars 71 forks source link

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

Closed jeremyandrews closed 1 year ago

jeremyandrews commented 1 year ago

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

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,
}