4. Monitoring Execution History
Execution history helps identify performance bottlenecks, unused reports, and operational issues.
Execution logs answer questions such as:
- Which reports ran today?
- Which executions failed?
- How long do reports take to run?
- Which reports are rarely or never used?
Latest Report Executions
The following query retrieves detailed execution information:
SELECT
InstanceName,
C.Name as ReportName,
COALESCE(CASE(ReportAction)WHEN 11 THEN AdditionalInfo.value('(AdditionalInfo/SourceReportUri)[1]', 'nvarchar(max)')
ELSE C.Path END, 'Unknown') AS ItemPath,
--UserName,
--ExecutionId,
CASE(RequestType)
WHEN 0 THEN 'Interactive'
WHEN 1 THEN 'Subscription'
WHEN 2 THEN 'Refresh Cache'
ELSE 'Unknown'
END AS RequestType,
-- SubscriptionId,
Format,
Parameters,
CASE(ReportAction)
WHEN 1 THEN 'Render'
WHEN 2 THEN 'BookmarkNavigation'
WHEN 3 THEN 'DocumentMapNavigation'
WHEN 4 THEN 'DrillThrough'
WHEN 5 THEN 'FindString'
WHEN 6 THEN 'GetDocumentMap'
WHEN 7 THEN 'Toggle'
WHEN 8 THEN 'Sort'
WHEN 9 THEN 'Execute'
WHEN 10 THEN 'RenderEdit'
WHEN 11 THEN 'ExecuteDataShapeQuery'
WHEN 12 THEN 'RenderMobileReport'
ELSE 'Unknown'
END AS ItemAction,
TimeStart,
TimeEnd,
TimeDataRetrieval,
TimeProcessing,
TimeRendering,
CASE(Source)
WHEN 1 THEN 'Live'
WHEN 2 THEN 'Cache'
WHEN 3 THEN 'Snapshot'
WHEN 4 THEN 'History'
WHEN 5 THEN 'AdHoc'
WHEN 6 THEN 'Session'
WHEN 7 THEN 'Rdce'
ELSE 'Unknown'
END AS Source,
Status,
ByteCount,
[RowCount],
AdditionalInfo
FROM ExecutionLogStorage EL WITH(NOLOCK)
LEFT OUTER JOIN Catalog C WITH(NOLOCK) ON (EL.ReportID = C.ItemID)
- TimeDataRetrieval, TimeProcessing, and TimeRendering help isolate bottlenecks.
- Status identifies success or failure.
- RequestType describe is report executed interactive by user or with subscription
- Format – render output format
- AdditionalInfo in xml form help you understand information about scalability time, memory usage, processing, pagination, etc.
<AdditionalInfo>
<ProcessingEngine>2</ProcessingEngine>
<ScalabilityTime>
<Pagination>0</Pagination>
<Processing>0</Processing>
</ScalabilityTime>
<EstimatedMemoryUsageKB>
<Pagination>5</Pagination>
<Processing>78661</Processing>
</EstimatedMemoryUsageKB>
<DataExtension>
<SQL>1</SQL>
</DataExtension>
<Connections>
<Connection>
<ConnectionOpenTime>261</ConnectionOpenTime>
<DataSets>
<DataSet>
<Name>Main</Name>
<RowsRead>48658</RowsRead>
<TotalTimeDataRetrieval>4167</TotalTimeDataRetrieval>
<ExecuteReaderTime>4165</ExecuteReaderTime>
</DataSet>
</DataSets>
</Connection>
</Connections>
</AdditionalInfo>
Reports Not Executed in the Last 90 Days
This query identifies reports that have not been executed for an extended period and helps identify candidates for cleanup or archival. Output provides you additional information who and how it was executed for last time (interactive, per subscription, etc.)
Of course you can choose your own number of days:
SELECT DISTINCT a.*, l.UserName
FROM (
SELECT c.[name] as reportName,
SUBSTRING(SUBSTRING(path, CHARINDEX('/', path) + 1, LEN(path)),0,
CHARINDEX('/',SUBSTRING(path, CHARINDEX('/', path) + 1, LEN(path)))) Folder,
CASE(RequestType)
WHEN 0 THEN 'Interactive'
WHEN 1 THEN 'Subscription'
WHEN 2 THEN 'Refresh Cache'
ELSE 'Unknown' END AS RequestType,
MAX(l.TimeStart) lastRunDate
FROM Catalog c
INNER JOIN ExecutionLogStorage l ON l.ReportID = c.ItemID
WHERE c.Type NOT IN (1,3,5,8)
AND l.ReportAction IN(1,13)
GROUP BY c.[name],
SUBSTRING(SUBSTRING(path, CHARINDEX('/', path) + 1, LEN(path)),0,
CHARINDEX('/',SUBSTRING(path, CHARINDEX('/', path) + 1, LEN(path)))),
CASE(RequestType) WHEN 0 THEN 'Interactive' WHEN 1 THEN 'Subscription'
WHEN 2 THEN 'Refresh Cache' ELSE 'Unknown' END
HAVING MAX(l.TimeStart) < getdate() - 90
) a
INNER JOIN ExecutionLogStorage l ON l.TimeStart = a.lastRunDate;
Failed Executions Today
To quickly identify failures, use the following query (one of my daily reports about reports):
SELECT
c.Path AS ReportPath,
c.Name AS ReportName,
a.Status,
a.UserName,
a.Parameters,
a.TimeStart,
a.TimeEnd,
a.TimeDataRetrieval,
a.TimeProcessing,
a.ByteCount,
a.[RowCount]
FROM dbo.ExecutionLog AS a WITH(NOLOCK)
INNER JOIN dbo.Catalog AS c WITH(NOLOCK) ON a.ReportID = c.ItemID
WHERE CAST(TimeStart AS DATE) = CAST(GETDATE() AS DATE)
AND [Status] NOT IN ('rsSuccess');