Eden Ridgway's Blog

.Net and Web Development Information

  Home :: Contact :: Syndication  :: Login
  105 Posts :: 1 Stories :: 78 Comments :: 3 Trackbacks

Search

Article Categories

Archives

Post Categories

Development

General

I have been making a lot of changes to the CruiseControl Statistics replacement I released a while ago. Most significantly I changed it to use the Dojo charting library and divided the information into tabs. It now looks like this:

CCNetDojoStatisticsBuildReportGraph DojoHistoricBuildReportGraphs

CCNetStatisticsBuildTables

Reasons for the Changes

The reasons for these changes were as follows:
  1. The display was becoming cluttered with a lot of information that could be nicely separated into tabs.
  2. I can now defer the rendering of the tables and historic graphs until the point where the user actually wants to view them. This should dramatically reduce the load time on projects that have a lot of statistics.
  3. The dojo charting library is significantly more flexible than PlotKit and will allow for more freedom in future versions. I also expect that others may want graphs that use more than one plotter, like a combination bar and line chart.
  4. I will be able to tweak the charting library to do things like rotate the x-axis tick labels so that more of them can be placed on the axis.
Purpose of the Graphs

In my previous posts I forgot to explain why I wanted to do all of this in the first place. While having good looking graphs instead of an ugly table is great, what I really wanted to get the following from this, is the following:
  • Determine whether or not the development teams were following our development process and making certain their code compiles before checking in. A red flag for me is a project that is frequently broken. I chat to the team and determine the root cause and rectify it.
  • Being able to easily spot projects that are taking long or progressively longer to build and see how I can ensure that it stays at acceptable levels so that the team continue to use CruiseControl effectively.
  • Determine if the teams are fixing their FxCop violations and writing and using unit tests on their projects.
Other future benefits I would like to get from this are:
  • The addition of line counting statistics so I can see how much projects are being worked on and get a sense of code churn. Of course line counting is fraught with problems, but at least it's something.
  • Track project complexity and ensure that we keep it under control.
Installation

The installation instructions are the same as the previous version.

Works well in the following browsers: Internet Explorer FireFox
Has some rendering quirks in: Opera
Have not tested: WebKit/Safari


Downloads / Updates
  1. [Version 2.3 - 27 April 2007] - Changes:
    1. Significant restructuring of the graph configuration logic (now lives in a separate file).
    2. Removed the timeline logic of the graphs.
    3. Added coverage graphs (assumes that the coverage information is stored in the Coverage element). 
    4. Added tooltips to the graphs (there are problems in IE).
    5. Graph rendering is now queued with a "Loading..." message in the graph display area. This has helped improve the user experience on the History tab which can be quite slow when displaying a lot of data.
    6. Miscellaneous other changes in tick generation etc.
    7. Table cells of greater than 25 characters now wrap. The exception to this is when you have a word without any spaces that exceeds this and is obviously not wrapped. This sometimes happens in the "Build Error Message" column where the path to a file may be very long. I'm considering implementing a solution that splits these up based on a best guess separator (underscore, full stop, or slash).
    8. The successful/failed builds are color coded in the detailed table now.
  2. [Version 2.4 - 28 April 2007] - Changes:
    1. Fixed a problem that was caused when some statistics had coverage values and others didn't.
    2. Dramatically improved the performance of the summary logic and it now summarises data on demand. The performance problem here was due to the fact I was using the dojo ArrayList method in the distinct method. On a report with over 1.7MB of data this caused Internet Explorer (it doesn't happen in FF) to display the "A script on this page is causing Internet Explorer to run slowly" message. The performance tweaks have removed this problem, but I'm concerned that it may reappear when processing a much larger file. I created a test case with over 8.5MB of data and I didn't receive the message. However the rendering of the tables on such a report is a bit of a joke. I need to look at further improving the performance of the table rendering functions (I don't believe that doing it in the XSLT is going to render the benefit one would expect due to the amount of HTML the client ends up downloading).
    3. Split the detailed and summary tables on to separate tabs and now obviously only render them when the user wants to view the respective tab. However this is still too slow.
    4. Increased the time delay between the rendering of the graphs to 150ms.
  3. [Version 2.5 - 28 April 2007] - Changes:
    1. Fixed a bug in the tick mark generation that I introduced while making the changes above. Note that now sometimes the last tick mark on the y-axis does not render. I suspect that this is due to the wonders of JavaScript floating point maths (I still need to investigate this fully), but it is a relatively minor issue so I'm not that phased about it.
    2. Added the ability to drill down into the detail statistics from the summary table.
    3. Now only averages, counts, etc the successful builds (except the for the failed count of course :) ).
    4. Various code refactoring.
  4. [Version 2.6 - 18 May 2007] - Changes:
    1. Fixed a bug caused by unescaped string sequences in the JavaScript statistics object literal definition (i.e. \u was causing a hexidecimal value expected error in IE). Thank you Mo for reporting this.
  5. [Version 2.7 - 22 May 2007] - Changes:
    1. Have improved the manner in which the graphs are configured thereby making it easier for others to add their own custom settings. The details of how this is setup can be found here.
    2. Now can jump to the build from the detailed data table.
    3. Added pre-configured complexity and sloc graphs.

Concerns

  1. The Dojo getBorderBox method that the tab control uses is really slow. In some test cases it takes over 5 seconds in total.
  2. When switching out of the statistics page Internet Explorer (not FF) struggles and it can take a few seconds just to go back to the listing page. I'm wondering if this is caused by the Dojo framework in some way or by the graphs etc.
  3. Internet Explorer is significantly slower than FireFox and Opera. This is inline with the graph rendering performance results at http://www.ajaxperformance.com/?p=58.
  4. The detailed table rendering performance for projects with lots of builds. A possible solution to this is to introduce paging.

To Do
  1. Use a frameworks such as JsUnit and JSMock (maybe even J3Unit) to properly test the logic. The JavaScript Coverage Validator may also be of use.
  2. Cut down the size of the dojo toolkit distributed with the graphs as it takes quite some time to deploy and there is a lot unnecessary files in the deployment package at the moment.. Basically I need to create a modified build of the Dojo Toolkit that only includes the pieces that I am using.
  3. Find a solution to the single word greater than 25 characters problem in the details table which causes the columns to be very wide.
  4. Find a solution to the Internet Explorer tick tooltip problem. At the moment only the ticks for the last series rendered display tooltips. I believe this is because of the way the Graphing library nest each series inside of a div and layer them on top of each other, thereby preventing the data points on the underlying series to receive the events required to display the ticks.
  5. Possibly make the ticks a little more informative (requires modifications to the Dojo library). I could use the Dojo tooltip widget to display detailed build information or I could place the information to the right of the graph.
  6. Implement filtering in the historic build page that allows graphs to be filtered by date range. I'm a bit concerned about the performance impact of having one master filter that then causes all the graphs to be redrawn.
posted on Sunday, April 22, 2007 9:00 AM

Feedback

# re: Dojo Based CruiseControl Statistics Graphs 5/14/2007 2:07 AM David Keaveny
Awesome plug-in; the out-of-the box statistics are not pretty to look at, but these are a work of art, if a little slow. Keep up the good work.

# re: Dojo Based CruiseControl Statistics Graphs 5/27/2007 10:35 PM Morgan
This looks very nice, unfortunately its not working on my machine :(
I get an exception after installing it:
System.NullReferenceException: Object reference not set to an instance of an object.
Server stack trace:
at ThoughtWorks.CruiseControl.Core.CruiseServer.GetStatisticsDocument(String projectName)
at ThoughtWorks.CruiseControl.Core.CruiseManager.GetStatisticsDocument(String projectName)
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at ThoughtWorks.CruiseControl.Remote.ICruiseManager.GetStatisticsDocument(String projectName)
at ThoughtWorks.CruiseControl.WebDashboard.ServerConnection.ServerAggregatingCruiseManagerWrapper.GetStatisticsDocument(IProjectSpecifier projectSpecifier)
at ThoughtWorks.CruiseControl.WebDashboard.Plugins.Statistics.ProjectStatisticsPlugin.Execute(ICruiseRequest cruiseRequest)
at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.ServerCheckingProxyAction.Execute(ICruiseRequest cruiseRequest)
at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.ProjectCheckingProxyAction.Execute(ICruiseRequest cruiseRequest)
at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.CruiseActionProxyAction.Execute(IRequest request)
at ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise.ExceptionCatchingActionProxy.Execute(IRequest request)

Any chance you know what might be the issue?

# re: Dojo Based CruiseControl Statistics Graphs 6/7/2007 7:42 PM Eden Ridgway
Hi Morgan

Sorry for taking so long to get back to you, but for some reason your comment was flagged as spam. The error you see happens when there are no statistics. This is not caused by my statistics replacement. If you undo the config changes, you'll see that the error still appears. Hopefully the CruiseControl team fixes it in the next release.

Thanks
Eden

# re: Dojo Based CruiseControl Statistics Graphs 6/18/2007 8:11 PM Brian
Eden,

You did a fantastic job. I got it working and love it! I'm trying to make a couple modifications, and not having alot of success. We lable our builds with the typical 4 part versioning scheme (Major.Minor.Revision.Build). I'd really like the Recent Build Graphs to display the data from the current revision (i.e. 1.0.5.x where x represents the builds I'd like displayed). I'd also like the Summerized data to group by revision, instead of by day. I'm not a javascript expert. Just wondering if you have any tips for me. Thanks!

# re: Dojo Based CruiseControl Statistics Graphs 6/21/2007 6:20 AM Eden
Hi Brian

Thanks for the kind words. There are quite a few places where I've assumed that the summaries are grouped by day, so making your change is a little tricky (although I certainly see the value in it).

The main areas of logic that you would change are:
+ summariseStatistics - performs the core "group by day" logic by creating an object with each day that contains all the entries for that day.
+ generateDailySummaries - uses the summary configuration to group the statistics.

When I have a little more free time I may very well implement a configuration option that allows you to customize the manner in which the statistics are grouped.

Eden

# re: Dojo Based CruiseControl Statistics Graphs 6/22/2007 9:56 AM Warwick
Hi Eden-

Firstly, well done on an excellent extension to cruise control!

I'm trying to install it for CC.Net version 1.3.0.2912, and seem to be having some problems. I'm finding that despite having changed the projectStatisticsPlugin and unzipping the folder as specified, your stats page isn't showing up. All I get an ugly statistics page (might be the CC.Net Default) with only one build listed (the first one I did, despite having done several builds since installation).

Do you have any idea what this might be? Sorry its such a vague description!

Kind Regards,

Warwick

# re: Dojo Based CruiseControl Statistics Graphs 6/24/2007 9:10 AM Eden
Hi Warwick

Thanks for the great feedback.

I think the problem you've run in to is either due to CruiseControl caching the configuration information or caching the statistics stylesheet the first time the page is viewed. If you run IISReset from the command prompt, you should see the newly configured statistics replacement the next time you view the page.

Kind Regards
Eden

# re: Dojo Based CruiseControl Statistics Graphs 6/27/2007 6:25 PM Warwick
Hi Eden-

Thanks for the tip- that fixed it!

One more thing I notice now though, there's some strange caching going on- when I force a build and look at the statistics, despite refreshing / clearing the local cache, IIS resets, ccnet restarts etc., the graphs aren't updated straight away with the latest build ... it can take a long time before the last few builds appear.

Any ideas?

Thanks Eden- this is a fantastic tool and I hope you can come to some agreement with CC.Net to have it included in the regular distribution!

Cheers

Warwick

# re: Dojo Based CruiseControl Statistics Graphs 6/27/2007 6:37 PM Warwick
Hi again-

It is definitely the browser cache! Please ignore the question above.

Thanks

Warwick

# re: Dojo Based CruiseControl Statistics Graphs 7/5/2007 10:39 PM Igor Brejc
Hi Eden,

I've just installed v2.7 on my CCNet 1.3 and it works like a charm! Thanks very much for your effort.
One suggestion though: why don't you publish this excellent work on the CCNet contribution site (http://confluence.public.thoughtworks.org/display/CCNETCOMM/Contributions). This way more people will know about it (I learned about it accidentally).

Best regards,
Igor

# re: Dojo Based CruiseControl Statistics Graphs 7/12/2007 6:13 PM Drew Noakes
This is a fantastic addition to CCNet and I hope one that's incorporated into the core distribution. I agree with Igor -- you should publish this on the Confluence page he listed.

Thanks again,

Drew.

# re: Dojo Based CruiseControl Statistics Graphs 7/19/2007 2:14 PM Lee
Ive got cruisecontrol running and reporting nunit tests, running and importing fxcop output (finally!)

But im curious.. Where do the 'Average Statements' and 'Average Complexity' values get populated from??

# re: Dojo Based CruiseControl Statistics Graphs 7/19/2007 3:55 PM John Bell
Hi Eden,

This is an excellent addition to CruiseControl.NET - thanks for the hard work!

One question, I recently moved our unit tests over from NUnit to MSTest and now the number of tests run does not get plotted. Is there anything I can do about that?

thanks in advance,
John.

# re: Dojo Based CruiseControl Statistics Graphs 7/23/2007 6:10 AM Eden Ridgway
Hi Lee

The Average Statements and Average Complexity Statements would only be populated if you added custom statistics to your build. You could use a tools like SourceMonitor or NDepend to populate these.

Regards
Eden

# MSTest Statistics Population 7/23/2007 6:23 AM Eden Ridgway
Hi John

To replace the test statistics requires modification of your GraphConfiguration.js file. I wrote a guide about this at http://www.ridgway.co.za/archive/2007/05/21/adding-custom-graphs-to-the-cruisecontrol.net-statistics-replacement.aspx.

The general idea however is that you include the custom MSTest statistics in your report.xml file and then you replace the TestCount, TestFailures and TestIgnored attributes with your custom attributes.

Hope that helps.

Regards
Eden

# re: Dojo Based CruiseControl Statistics Graphs 7/26/2007 3:19 PM Drew Noakes
Hi Eden,

I'm looking at my 'number of builds per day' chart and thinking it'd be better if it were a stacked chart... i.e. the sum of red and green makes the total outline. Seeing the two lines crossing each other isn't quite as intuitive as seeing the two series stacked. The same would be true of tests passed/failed/ignored.

Can the Dojo library do this? Can we make this a simple configuration property? I'm willing to help out here but would appreciate some guidance.

All the best and thanks again for these fantastic charts.

Drew.

# re: MSTEst Statistics Population 7/27/2007 11:25 AM John Bell
Hi Eden,

Thanks for the feedback. After a little tinkering I realised the problem was that CruiseControl was not setting the TestCount, TestFailures and TestIgnored statistics in the report.xml file.

I looked at the cruise control MSTestSummary.xsl file to see how it got those stats and used the same principle.

By adding the following to ccnet.config I managed to get the appropariate statistics populated and I now have graphs for tests stats using MSTest:

<statistics>
<statisticList>
<statistic name="TestCount" xpath="count(/cruisecontrol/build/Tests/UnitTestResult[outcome=10]) + count(/cruisecontrol/build/Tests/UnitTestResult[outcome=1]) + count(/cruisecontrol/build/Tests/UnitTestResult[outcome=4])"/>
<statistic name="TestFailures" xpath="count(/cruisecontrol/build/Tests/UnitTestResult[outcome=1])"/>
<statistic name="TestIgnored" xpath="count(/cruisecontrol/build/Tests/UnitTestResult[outcome=4])"/>
</statisticList>
</statistics>

This can be added in addition to the standard <statistics/> tag which generates the default statistics.
Unfortunately to ignored stat doesn't work at present (which is the same with the MSTestSummary.xsl)
but its a start!

Thanks again for you excellent tool.
regards,
John.

# re: Dojo Based CruiseControl Statistics Graphs 7/28/2007 3:36 PM Damon Carr
Eden,

Excellent! I took the also critical tool CCStatistics from Grant Drake and upgraded it to work with CC.NET 1.3 as the latest build I could find was 1.2.X based. They broke the API on a few items so I had to recode a few aspects (but nothing was lost).

You can read more here:

http://damon.agilefactor.com/2007/07/cruisecontrolnet-ccstatistics-for-13.html

I specifically recommend your 'Dojo Based CruiseControl Statistics Graphs' to anyone using statistics.

The combination of :

1) Getting your historical data into the statistics format (report.xml) with additional items as required
2) Your amazing display improvement

make the statistics aspects of CruiseControl a must have instead of an interesting addition.

NOTE: Props to this post and the high quality of all posts from the South African .NET Developer portal (this pose is especially relevant:

http://dotnet.org.za/cjlotz/archive/2007/05/17/using-cruisecontrol-net-statistics-to-monitor-your-code-base.aspx).

Thanks,
Damon Carr


# re: Dojo Based CruiseControl Statistics Graphs 7/29/2007 10:32 AM Eden Ridgway
Hi Drew

In an older version of the Graphing replacement (one that used PlotKit) I simulated a stacked chart for the statistics, but it didn't look great so I abandoned it. But you are absolutely right, some of the graphs are much more useful as stacked plots, and fortunately the Dojo Charting library has native support for these :). So I've taken your advice and have implemented stacked plots which are configurable. Once I've worked out all the kinks I'll post the new version.

Thanks for the feedback.

Eden

# Fixing the y-axis minimum value 8/2/2007 3:54 PM Drew Noakes
Hi Eden,

I'm looking forward to stacked charts. Let me know if you want someone to test this -- I'll gladly help.

Also, it's be good to be able to pin the origin to a y-value of zero. Take build duration for example... currently the lowest value appears as zero unless you take the time to observe the marking on the y-axis. I tried to do this, but I don't think you can specify the minimum without also specifying the maximum. I'd like the max to be automatically adjusted while pinning the minimum to zero.

Hope that's helpful.

Drew.

# relative path in StatisticsGraphs.xsl to javascript 8/3/2007 5:26 PM Andrew Garner
Hi Eden,

Great package, this is definitely a great addition to our Continuous Integration build machine.

My current task is to embed the graphs into our program web site, to integrate them into the program report rather than having to link to the Cruise Control page. I have created an asp page to call the xsl and return the html fragment to embed in the program web page but unless I change the paths to the javascript files in the StatisticsGraphs.xsl, the graphs do not display.

I don't see how the javascript folder under the WebDashboard can be 4 folders up from where the working folder is. If I change the xsl paths to use something like ../javascript/dojo/dojo.js, the asp page display the graphs, Cruise Control does not.

I want to avoid replicate the xsl and javascript files and folders in two separate locations, which would be the easy way out. Having written a Cruise Control plugin to talk to our StarTeam MPX server I thought I was beginning to understand Cruise Control, but I don't see the reason for the depth of relative path to be ../../../../javascript. Can you shed any light on this?

Many thanks
Andrew

# re: Relative path in StatisticsGraphs.xsl to javascript 8/7/2007 8:55 AM Eden Ridgway
Hi Andrew

Thanks for the feedback and it is great to hear that it is being used outside of the standard CruiseControl site.

The reason that the relative path reference to the JavaScript files appears to be 4 levels up is due to the URL rewriting that CruiseControl does. If you take a look in the webdashboard web.config file you'll see that they have mapped .xml and .aspx requests to their custom handler: ThoughtWorks.CruiseControl.WebDashboard.MVC.ASPNET.HttpHandler. They then break apart the url information and use that to determine which plugin , etc. to load. In other words the request as it appears in the URL doesn't really map directly to a location on disk. However since the browser doesn't really know we end up with a strange relative path to get back to the root of the ccnet application path.

I suspect that you are unfortunately going to have to change the JavaScript path for your project site.

I hope that helps.

Eden

# CruiseControl Statistics 11/10/2009 9:16 AM
CruiseControl Statistics

Comments have been closed on this topic.