« LoadRunner - Copying Parameters Between Scripts | Main
Thursday
Apr192012

LoadRunner - Changing Log Options at Runtime

Script debugging can take too long when the output log is large and takes a long time to generate.

 Has This Ever Happened to You?

  • Working on a script with a lot of steps and a lot of data returned by the server.
  • You run the script in vugen and run-time errors are reported.
  • The script ran for 10 minutes, 40% through the steps and is on line 80,000 of the log file.

You could look at the log, isolate and fix the error and rerun the script.  If you are lucky, all is good now.  What is more likely is that another 10 minutes go by and another run-time error occurs.  You look at the log and you have only executed 20 more lines than the last run.  Ugghhh!  This can be repeated, but could end up taking a lot of time to work through the entire script.  Instead, how can we do this better?

 What We Want to Do

  • Reduce the logging on the first ‘x’ lines of the script that work fine.
  • Turn on full logging for the part of the script that we want to investigate.
  • Optionally reduce logging when we are done.

Remember to turn on full logging far enough back from the error location to give you the data you need to debug the script.

Step 1

Set run-time settings to standard logging only to start.  You could also use the extended log with ‘Parameter substitution’ only.  This will give you some feedback on the state of the iteration run.  You can also verify that the parameters you are using are what you are expecting.

Step 2

Create the following function to manage the logging options.  For simplicity, this function could be put in the vuser_init section.  As well, it could exist in an include (.h) file to be shared amongst many scripts.

int iDebugLevel = -1;

#define SMLLC_DEFINE_LOG_DEFAULT   0
#define SMLLC_DEFINE_LOG_ALL       1
#define SMLLC_DEFINE_LOG_OFF       2

void SMLLC_SetLogging (int iLogLevel)
{
    int iCurrentDebugLevel = lr_get_debug_message();

    if (iDebugLevel == -1)
    {
        iDebugLevel = iCurrentDebugLevel;  // only set once, so it is not overwritten
    }

    // If the script is being run in a scenario, this function is ignored.
    // We don’t have to worry about removing these calls before running a load test.

    if (strcmp (lr_get_master_host_name(), "None") == 0)
    {
        switch (iLogLevel)
        {
            case SMLLC_DEFINE_LOG_DEFAULT:
                lr_set_debug_message(iCurrentDebugLevel, LR_SWITCH_OFF);
                lr_set_debug_message(iDebugLevel, LR_SWITCH_ON);
            break;

            case SMLLC_DEFINE_LOG_ALL:
                lr_set_debug_message(iCurrentDebugLevel, LR_SWITCH_OFF);
                lr_set_debug_message(LR_MSG_CLASS_EXTENDED_LOG |
                    LR_MSG_CLASS_RESULT_DATA |
                    LR_MSG_CLASS_FULL_TRACE |
                    LR_MSG_CLASS_PARAMETERS,
                    LR_SWITCH_ON);
            break;

            case SMLLC_DEFINE_LOG_OFF:
                lr_set_debug_message(iCurrentDebugLevel, LR_SWITCH_OFF);
                lr_set_debug_message(LR_MSG_CLASS_DISABLE_LOG,LR_SWITCH_ON);
            break;

            default:
                lr_error_message("Unknown log level : %i", iLogLevel);
            break;
        }
    }
}

Step 3

Add calls to the script where you want to control/change the logging.

SMLLC_SetLogging(SMLLC_DEFINE_LOG_OFF);     // Turns off logging completely.
SMLLC_SetLogging(SMLLC_DEFINE_LOG_ALL);     // Turns on all the extended logging options.
SMLLC_SetLogging(SMLLC_DEFINE_LOG_DEFAULT); // Resets logging options to the original.

Step 4

These function calls can now be used in your script.  You could do the following:

vuser_init()
{
    SMLLC_SetLogging(SMLLC_DEFINE_LOG_OFF);     // Turn off logging completely.

    // Initialization code, start app, login, ....
    return 0;
}

Action()
{
    // Business steps, ...

    SMLLC_SetLogging(SMLLC_DEFINE_LOG_ALL);     // Turn on all logging so we can debug.

    // More business steps, ...

    SMLLC_SetLogging(SMLLC_DEFINE_LOG_DEFAULT); // Reset logging options.

    // More business steps, ...
    return 0;
}

Future Considerations

 Possible Changes

  • Use a macro instead of a function.
  • To be more granular, instead of using defined constants for parameters to SMLLC_SetLogging, use the actual desired logging level values.
  • Create a SMLLC_DEFINE_LOG_MIN to force a minimum amount of logging.  Could have this overwrite the default logging levels.
  • If you want to use this in a scenario run, comment/remove the strcmp() line in the function.
  • I only care about these 3 log levels: DEFAULT (runtime settings value), OFF (no logging), ALL (all possible logging).

Conclusion

We can now adjust the logging for LoadRunner scripts at runtime.

Reader Comments (3)

Amazing. Exactly what I was looking for. I used this techique for a slightly different purpose and it worked well for me. I was writing a script that generated some information on the fly and I wanted to know what those values were even when there was no error. I could see how could get all of the information in a huge log file or the information if there was an error, but I wanted to get just a few snippets into a log always with each run. This did the trick nicely. Thanks Eddie.

May 7, 2012 | Unregistered CommenterShawn Faunce

Loving your new blog Eddie! Keep putting stuff like this out and don't stop!!!!

May 8, 2012 | Unregistered CommenterScott Moore

Excellent blog entry! It is very clear, concise, and helpful for those “tricky” scripting issues that we all encounter. This solution makes full logging much easier to navigate. Great job Ed. You are the maniac!

May 9, 2012 | Unregistered CommenterSean Gregory

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>