LoadRunner Functions and Custom C Code in VuGen Scripts
How to extend LoadRunner scripts with custom C code and the lr_* runtime API for logic the recorder and built-in functions can't express.
VuGen scripts are C code under the hood, and while recording plus correlation/parameterization covers most needs, some flows require custom logic that the recorder can’t generate on its own — conditional behavior, custom data transformation, or integration with something outside the recorded protocol.
The lr_* runtime API
LoadRunner’s lr_* functions are the standard runtime API available in any script, independent of protocol: lr_think_time() for pacing, lr_save_string() for manually storing a value into a parameter, lr_output_message()/lr_log_message() for custom logging, lr_start_transaction()/lr_end_transaction() for defining custom transaction boundaries around any block of code, and many more.
Custom transactions for meaningful reporting
Wrapping a logical business flow in lr_start_transaction("checkout") / lr_end_transaction("checkout", LR_AUTO) — even across multiple underlying protocol-level calls — gives you the same benefit as JMeter’s Transaction Controller: a single, meaningful row in Analysis reports instead of a pile of individual low-level requests. This is worth doing deliberately in every script, not just relying on whatever transaction boundaries the recorder happened to create automatically.
Conditional logic
Standard C control flow (if/else, loops) works directly in a VuGen script, letting you branch behavior based on a parameter value or a previous response — for example, only executing a “retry” block if a prior correlated value indicates failure, similar in purpose to JMeter’s If Controller but expressed as ordinary code rather than a GUI element.
Calling external libraries
VuGen supports calling external DLLs (Windows) or shared libraries for needs beyond what’s practical in pure C within the script itself — useful for specialized computation (custom cryptographic signing for an API, for instance) that’s easier to implement once in a proper library than to hand-write inline in every script that needs it.
A practical example: custom signature generation
char signature[256];
compute_hmac_signature(lr_eval_string("{requestBody}"), "secretKey", signature);
lr_save_string(signature, "requestSignature");
(With compute_hmac_signature implemented either inline or via an external library call.) The result is stored as a parameter ({requestSignature}) for use in subsequent protocol-level calls, the same pattern as JMeter’s JSR223 PreProcessor computing a value for later samplers to consume.
Debugging custom code
lr_output_message() writes to the script’s execution log, the most direct way to confirm custom logic is doing what you expect during Replay — check the log after any custom code change before assuming a scenario-scale run will behave correctly.
When to reach for custom code vs. built-in tools
Same principle as JMeter’s JSR223 guidance: prefer built-in VuGen/Correlation Studio/parameterization features when they cover the need, and reach for custom C code specifically for the genuinely custom logic those tools don’t express — keeping scripts maintainable for whoever works on them next.
Takeaway: the lr_* API and standard C give VuGen scripts real programming-language flexibility underneath the recorder — most useful for custom transactions (always worth adding deliberately) and the occasional genuinely custom logic a recorded flow alone can’t capture.
Comments are powered by Giscus (GitHub Discussions). Enable them by
configuring GISCUS in src/consts.ts — see
giscus.app.