Automated Cognos Report Performance Measurement

By | 2015.11.16

Performance tuning is an important part of any Cognos report development project. A report that runs fast provides better user experience and therefore produces happier customers.

There are two main ways to time reports in Cognos, out of the box:

  1. Run the report and manually time with a stop watch, either physical or virtual
  2. Schedule the report to run and view the run history, comparing the report start time to the end time

Method #1 has several drawbacks. First, you have to watch the report while it runs so that you can stop the stopwatch when the results are returned. If a report takes a long time to run, which is often the case with reports we want to optimize, this is tedious. Secondly, it’s difficult to be consistent regarding when you initiate and then later stop the stopwatch. Look away from the report for a few seconds and you might miss the actual moment it returns which can lead to inaccurate and less than precise measurement.

Method #2 does provide consistent and precise measurement but is far from convenient. Development of reports within Report Studio is often an exercise in incremental change as you tweak the report and then run it quickly to determine the effectiveness of your modification. Having to schedule the report after each change slows down the development process and adds unnecessary tedium.

There has to be a better way.

Background

I was asked to give a talk on Cognos report performance tuning. I wanted to provide hands-on exercises that gave quick feedback to my students regarding the performance impact of various report design choices. At some point I realized that some modest JavaScript could be used to capture run time of a Report Studio report automatically, displaying the results on the report page with each run.

The advantages of this approach are many. With the report run time being reported automatically for each run the developer gets a natural sense of how the changes they make impact the run time of the report. Over time, they also get a better understanding of what types of changes can have the most severe impact on performance.

Imagine you’ve built a report and it has acceptable performance. You are about to release it but decide to make a last-minute change to the report to accommodate a new requirement. You run the report after making the change and the run time doubles from three seconds to six. You are made aware of this negative consequence because the timer script displays the run time automatically. Without this information, a human running the report interactively might not notice the extra three seconds of run time. Though a whopping 100% increase, the degraded performance might not be enough in real terms to be perceived. With the timer in place you can now take steps to mitigate the performance degradation before the report gets in the customer’s hands.

Introducing: The Cognos BI Timer

The Cognos BI Timer is two pieces of code to be inserted in HTML items within a Report Studio report. The first bit of code attaches a JavaScript event to the ‘Finish’ button of the prompt page. When fired, the event captures the exact date and time the report was initiated, to the millisecond. The second piece of code records the date and time when the report output page is rendered, calculates the time difference, formats the result, and displays the run time.

The Prompt Page Code

This first piece of code should be pasted in an HTML item and placed somewhere after the Finish button:

I’m not going to go over all of the JavaScript this time but it’s worth noting a few things:

I’ve built in the ability to set two performance thresholds. This allows you to style the run-time result based on how long the report takes to run. By default, there are three time buckets: 0-29 seconds, 30-59 seconds, and 60+ seconds. These thresholds can be tweaked by changing the assignment here. When the run time output is created a class of ‘rtok’, ‘rtwarning’, or ‘rtproblem’ is applied respectively. This allows for dynamic styling of the run-time output based on which bucket the report run falls in.

This part of the code looks for a ‘Finish’ button using some knowledge of how Cognos creates these buttons and attaches the cbit.startTimer() function to its click event.

This portion of the code should be put in its own ‘HTML Item’ object and placed after the ‘Finish’ button on the prompt page. With Cognos’ default prompt page configuration, this would be located in the footer like this:

footer

The Report Page Code

The second piece of code goes in an HTML item and should be placed somewhere on the report page itself:

Let’s go through this code.

This is the container that will contain our run time output. Note that the label is enclosed in its own span so it can be styled separately if desired.

These are all the styles available. For example, say you wanted the run time label to be orange. The #rtlabel selector would look like this:

If you wanted to apply a style to just the run time itself, you would use the #rt selector. To make the run time appear bigger while leaving the label alone:

Finally, we can style the individual time buckets separately. Remember earlier we established the default thresholds as 0-29, 30-59, and 60+ seconds. We can optionally style the run time depending on the bucket it falls in. Say we wanted a standard green, yellow, and red color scheme:

We can apply any number of styles to distinguish run times that fall within our threshold values.

We check to make sure that we haven’t already stored the stop time and store the current time if not. This check is done so that we don’t overwrite the initial stop time when you navigate pages in a multi-page report.

Having calculated the run time we can now append it to the div we defined in line 1.

For this code it doesn’t matter where you put it. Wherever it’s located is where the run time of the report will be displayed. A common place you might put it is in the report header:

header

Result

When we run the report, the precise moment we click the finish button on the prompt page is recorded by the prompt page code. The report page code records the moment when the report page is rendered and the difference is displayed wherever we have placed the report page code object.

run-time

Limitations

The report run time is only calculated based on the first page rendered. If you have a multi-page HTML report, time to render pages beyond the first one will be ignored. I tried to code in accumulation of time as you page down but unfortunately due to the way Cognos renders the navigation buttons I cannot attach events to them like I could the finish button on the prompt page.

A workaround is to set the number of rows per page on the data container to a very large number, larger than the maximum number of rows returned by your report. This will force Cognos to render the report all at once and allow you to get an accurate overall run time.

A bit of reverse-engineering was employed in order to reliably locate the finish button so that the timer start event could be attached. It’s possible that in future versions of Cognos BI, Cognos could change the way that finish buttons are identified. In that case this code will no longer work. Since it’s just a development tool I don’t think this is a major problem as if it doesn’t work you can simply pull out the code. Unfortunately, the Cognos JavaScript API provided in Cognos BI versions 10.2 and later does not give full access to Cognos buttons in JavaScript. A Cognos-supported way to detect button events would be very welcome as it could avoid this potential problem.

Note: After publishing this post it was brought to my attention that I didn’t discuss caching. It may be the case that local caching is enabled in your environment. If that is the case then you might see run times drop considerably when Cognos starts retrieving results from the cache instead of from the data source. To prevent this from happening during the development phase you can turn off local caching on a per-query basis by setting the query’s ‘Use Local Cache’ to ‘No’. Of course, it’s probably advisable to set this back to the default before releasing the report.

Thanks Anthony van Muyden for bringing this oversight to my attention. I appreciate it.

Conclusion

A good Cognos developer always has report performance in mind while developing reports. Unfortunately, existing methods to quantify report performance are tedious and often imprecise. By using relatively simple JavaScript code at the beginning of the development process, the user can be monitoring performance throughout development in a consistent and painless way. The result is heightened awareness of performance considerations and increased satisfaction from report stakeholders.

8 thoughts on “Automated Cognos Report Performance Measurement

  1. cognosdemystifiedAditya

    Hi Scott, very informative article. But in my case, the prompts are directly appearing from database, as they are defined in procedures. Is there any way, we can calculate the report time in these kind of reports?

    Reply
    1. Scott E. Johnson Post author

      Hi,

      There’s a workaround available. Here are the steps:

      1. Create a new prompt page
      2. Delete all objects except the Finish button.
      3. Add the prompt page code in an HTML Item to the right of the Finish button
      4. Modify the prompt page code by adding the following lines to the for loop at the end of the initialize function:

      buttons[i].style.visibility = ‘hidden’;
      window.setTimeout(function(button){button.click();},1,buttons[i]);

      So, the entire for loop should now look like this:

      When ran, finish button is hidden and a millisecond after the prompt page comes up the button is clicked, which initiates the timer and launches the report.

      Let me know if you have any issues.

      Scott

      Reply
  2. AKG

    Hi,
    This a very impressive and helpful blog. Can this script work if we don’t have a prompt page? I have a report which just report page and some prompts with default selection on it.
    Thanks & Regards

    Reply
    1. Scott E. Johnson Post author

      The only way I could see that working is if you created a blank prompt page. You could add a line of JavaScript to automatically submit the prompt page and store the time allowing the timing code to work. Most likely this would happen so fast the user wouldn’t notice it. Let me know if you want more information on this workaround.

      Reply
    2. Scott E. Johnson Post author

      Another person asked this same question and I came up with a workaround. See my response above to cognosdemystifiedAditya’s comment for details.

      Reply
  3. Anthony van Muyden

    This method does not take in consideration any caching that the server employs for reports. So the result between first run and second run can vary wildly.

    Reply
    1. Scott E. Johnson Post author

      You are correct. I recommend turning off caching on the query during testing. This can be done by setting the ‘Use Local Cache’ to ‘No’ during development. I’ll revise the post to mention this.

      Reply

Leave a Reply