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.

· By perf-test.com Editorial · AI-assisted
loadrunnerc-scriptingcustomization

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.

Discussions coming soon.

Comments are powered by Giscus (GitHub Discussions). Enable them by configuring GISCUS in src/consts.ts — see giscus.app.