Visualforce Page Metrics in Summer 17
Introduction
The Summer 17 release of Salesforce introduces the concept of Visualforce Page Metrics via the SOAP API. This new feature allows you to analyse how many page views your Visualforce pages received on a particular day. This strikes me as really useful functionality - I create a lot of Visualforce pages (although more Lightning Component based these days), to allow users to manage multiple objects on a single page for example. After I’ve gone to the effort of building the page I’m always curious as to whether anyone is actually using it!
SOAP Only
A slight downside to this feature is that the information is only available via the SOAP API. The release notes give an example of using the Salesforce Workbench, but ideally I’d like a Visualforce page to display this information without leaving my Salesforce org. Luckily, as I’ve observed in previous blog posts, the Ajax Toolkit provides a JavaScript wrapper around the SOAP API that can be accessed from Visualforce.
Sample Page
In my example page I’m grouping the information by date and listing the pages that were accessed in order of popularity. There’s not much information in the page as yet because I’m executing this from a sandbox, so the page may get unwieldy in a production environment and need some pagination or filter criteria.
Show me the code
Once the Ajax Toolkit is setup, the following query is executed to retrieve all metrics:
var result = sforce.connection.query( "SELECT ApexPageId,DailyPageViewCount,Id,MetricsDate FROM VisualforceAccessMetrics " + "ORDER BY MetricsDate desc, DailyPageViewCount desc");
The results of the query can then be turned into an iterator and the records extracted - I’m storing these as an array in an object with a property per date:
var it = new sforce.QueryResultIterator(result); while(it.hasNext()) { var record = it.next(); var dEle=metricByDate[record.MetricsDate]; if (!dEle) { dEle=[]; metricByDate[record.MetricsDate]=dEle; } // add to the metrics organised by date dEle.push(record); }
This allows me to display the metrics by Visualforce page id, but that isn’t overly useful, so I query the Visualforce pages from the system and store them in an object with a property per id - analogous to an Apex map:
result = sforce.connection.query( "Select Id, Name from ApexPage order by Name desc"); it = new sforce.QueryResultIterator(result); var pageNamesById={}; while(it.hasNext()) { var record = it.next(); pageNamesById[record.Id]=record.Name; }
I can then iterate the date properties and output details of the Visualforce page metrics for those dates:
for (var dt in metricByDate) { if (metricByDate.hasOwnProperty(dt)) { var recs=metricByDate[dt]; output+='<tr><th colspan="3" style="text-align:center; font-size:1.2em;">' + dt + '</td></tr>'; output+='<tr><th>Page</th><th>Date</th><th>Views</th></tr>'; for (var idx=0, len=recs.length; idx<len; idx++) { var rec=recs[idx]; var name=pageNamesById[rec.ApexPageId]; output+='<tr><td>' + name + '</td>'; output+='<td>' + rec.MetricsDate + '</td>'; output+='<td>' + rec.DailyPageViewCount + '</td></tr>'; } } }
You can see the full code at this gist.
Thanks for the example code! I ran the SOQL in developer console in sandbox environments and got results, but in a production environment I get "sObject type 'VisualforceAccessMetrics' is not supported". Could this be explained by the fact that I have a system admin profile in the sandboxes but not in production? Or is there another issue I should consider?
ReplyDeleteOn the first query
ReplyDeleteSELECT ApexPageId,DailyPageViewCount...
why can't you change that to
SELECT ApexPage.Name,DailyPageViewCount...
and then skip the second query?
This is great. Very useful. Thank you! :)
ReplyDelete