how to query SSISDB to find out the errors in the packages?
I have a handful of queries I use. The general concepts are that the table with the information is catalog.operation_messages
and you are interested in events with a 120 (error) type.
Depending on how robust of a query you want to build out, the following two derived tables might also be of interest.
--- http://technet.microsoft.com/en-us/library/ff877994.aspx
-- This query translates the message_type from SSISDB.catalog.operation_messages
-- into useful text
SELECT
D.message_type
, D.message_desc
FROM
(
VALUES
(-1,'Unknown')
, (120,'Error')
, (110,'Warning')
, (70,'Information')
, (10,'Pre-validate')
, (20,'Post-validate')
, (30,'Pre-execute')
, (40,'Post-execute')
, (60,'Progress')
, (50,'StatusChange')
, (100,'QueryCancel')
, (130,'TaskFailed')
, (90,'Diagnostic')
, (200,'Custom')
, (140,'DiagnosticEx Whenever an Execute Package task executes a child package, it logs this event. The event message consists of the parameter values passed to child packages. The value of the message column for DiagnosticEx is XML text.')
, (400,'NonDiagnostic')
, (80,'VariableValueChanged')
) D (message_type, message_desc);
-- Where was the error message generated?
SELECT
D.message_source_type
, D.message_source_desc
FROM
(
VALUES
(10,'Entry APIs, such as T-SQL and CLR Stored procedures')
, (20,'External process used to run package (ISServerExec.exe)')
, (30,'Package-level objects')
, (40,'Control Flow tasks')
, (50,'Control Flow containers')
, (60,'Data Flow task')
) D (message_source_type, message_source_desc);
I use queries like this to find information about the errors. Maybe I only care about what the errors were (query 1). Other times, I want to know all the activities of all the operations that failed (query 2). Generally, I'm lazy and want to see all the information about the last failing operation (query 3 and note the caveat).
-- http://msdn.microsoft.com/en-us/library/ff877994.aspx
-- Find all error messages
SELECT
OM.operation_message_id
, OM.operation_id
, OM.message_time
, OM.message_type
, OM.message_source_type
, OM.message
, OM.extended_info_id
FROM
catalog.operation_messages AS OM
WHERE
OM.message_type = 120;
-- Generate all the messages associated to failing operations
SELECT
OM.operation_message_id
, OM.operation_id
, OM.message_time
, OM.message_type
, OM.message_source_type
, OM.message
, OM.extended_info_id
FROM
catalog.operation_messages AS OM
INNER JOIN
(
-- Find failing operations
SELECT DISTINCT
OM.operation_id
FROM
catalog.operation_messages AS OM
WHERE
OM.message_type = 120
) D
ON D.operation_id = OM.operation_id;
-- Find all messages associated to the last failing run
SELECT
OM.operation_message_id
, OM.operation_id
, OM.message_time
, OM.message_type
, OM.message_source_type
, OM.message
, OM.extended_info_id
FROM
catalog.operation_messages AS OM
WHERE
OM.operation_id =
(
-- Find the last failing operation
-- lazy assumption that biggest operation
-- id is last. Could be incorrect if a long
-- running process fails after a quick process
-- has also failed
SELECT
MAX(OM.operation_id)
FROM
catalog.operation_messages AS OM
WHERE
OM.message_type = 120
);
Perhaps I'm lazy and don't want to go look this information up in the event of a failure, much as your team appears to have done. I have a SQL Agent job that runs on demand and I have jobs that run SSIS packages set to run that job in the event of failure.
DECLARE
@profile_name sysname = 'SQLAdmins'
, @recipients varchar(max) = '[email protected]'
, @copy_recipients varchar(max) = NULL
, @blind_copy_recipients varchar(max) = NULL
, @subject nvarchar(255) = 'failed package test'
, @body nvarchar(max) = 'Stuff has failed, fix please'
, @body_format varchar(20) = NULL
, @importance varchar(6) = 'NORMAL'
, @sensitivity varchar(12) = 'NORMAL'
, @file_attachments nvarchar(max) = NULL
, @query nvarchar(max) = N'
SELECT
O.object_name AS FailingPackageName
, O.object_id
, O.caller_name
, O.server_name
, O.operation_id
, OM.message_time
, EM.message_desc
, D.message_source_desc
, OM.message
FROM
SSISDB.catalog.operation_messages AS OM
INNER JOIN
SSISDB.catalog.operations AS O
ON O.operation_id = OM.operation_id
INNER JOIN
(
VALUES
(-1,''Unknown'')
, (120,''Error'')
, (110,''Warning'')
, (70,''Information'')
, (10,''Pre-validate'')
, (20,''Post-validate'')
, (30,''Pre-execute'')
, (40,''Post-execute'')
, (60,''Progress'')
, (50,''StatusChange'')
, (100,''QueryCancel'')
, (130,''TaskFailed'')
, (90,''Diagnostic'')
, (200,''Custom'')
, (140,''DiagnosticEx Whenever an Execute Package task executes a child package, it logs this event. The event message consists of the parameter values passed to child packages. The value of the message column for DiagnosticEx is XML text.'')
, (400,''NonDiagnostic'')
, (80,''VariableValueChanged'')
) EM (message_type, message_desc)
ON EM.message_type = OM.message_type
INNER JOIN
(
VALUES
(10,''Entry APIs, such as T-SQL and CLR Stored procedures'')
, (20,''External process used to run package (ISServerExec.exe)'')
, (30,''Package-level objects'')
, (40,''Control Flow tasks'')
, (50,''Control Flow containers'')
, (60,''Data Flow task'')
) D (message_source_type, message_source_desc)
ON D.message_source_type = OM.message_source_type
WHERE
OM.operation_id =
(
SELECT
MAX(OM.operation_id)
FROM
SSISDB.catalog.operation_messages AS OM
WHERE
OM.message_type = 120
)
AND OM.message_type IN (120, 130);
'
, @execute_query_database sysname = NULL
, @attach_query_result_as_file bit = 0
, @query_attachment_filename nvarchar(260) = NULL
, @query_result_header bit = 1
, @query_result_width int = 256
, @query_result_separator char(1) = char(13)
, @exclude_query_output bit = 0
, @append_query_error bit = 0
, @query_no_truncate bit = 0
, @query_result_no_padding bit = 0
, @mailitem_id int = NULL
, @from_address varchar(max) = NULL
, @reply_to varchar(max) = NULL;
-- Send email about the failure
EXECUTE msdb.dbo.sp_send_dbmail
@profile_name
, @recipients
, @copy_recipients
, @blind_copy_recipients
, @subject
, @body
, @body_format
, @importance
, @sensitivity
, @file_attachments
, @query
, @execute_query_database
, @attach_query_result_as_file
, @query_attachment_filename
, @query_result_header
, @query_result_width
, @query_result_separator
, @exclude_query_output
, @append_query_error
, @query_no_truncate
, @query_result_no_padding
, @mailitem_id OUTPUT
, @from_address
, @reply_to;
Adjust as you like
You can use:
SELECT OPR.object_name
, MSG.message_time
, MSG.message
FROM catalog.operation_messages AS MSG
INNER JOIN catalog.operations AS OPR
ON OPR.operation_id = MSG.operation_id
WHERE MSG.message_type = 120
This will give you only the error messages from SSIS package executions.
Here is one query I created to find the job error message from the SSISDB:
DECLARE @DATE DATE = GETDATE() - 7 -- This is to restrict the data for last 7 days, used in ON condition
SELECT O.Operation_Id -- Not much of use
,E.Folder_Name AS Project_Name
,E.Project_name AS SSIS_Project_Name
,EM.Package_Name
,CONVERT(DATETIME, O.start_time) AS Start_Time
,CONVERT(DATETIME, O.end_time) AS End_Time
,OM.message as [Error_Message]
,EM.Event_Name
,EM.Message_Source_Name AS Component_Name
,EM.Subcomponent_Name AS Sub_Component_Name
,E.Environment_Name
,CASE E.Use32BitRunTime
WHEN 1
THEN 'Yes'
ELSE 'NO'
END Use32BitRunTime
,EM.Package_Path
,E.Executed_as_name AS Executed_By
FROM [SSISDB].[internal].[operations] AS O
INNER JOIN [SSISDB].[internal].[event_messages] AS EM
ON o.start_time >= @date -- Restrict data by date
AND EM.operation_id = O.operation_id
-- Edit: I change the alias from OMs to OM here:
INNER JOIN [SSISDB].[internal].[operation_messages] AS OM
ON EM.operation_id = OM.operation_id
INNER JOIN [SSISDB].[internal].[executions] AS E
ON OM.Operation_id = E.EXECUTION_ID
WHERE OM.Message_Type = 120 -- 120 means Error
AND EM.event_name = 'OnError'
-- This is something i'm not sure right now but SSIS.Pipeline just adding duplicates so I'm removing it.
AND ISNULL(EM.subcomponent_name, '') <> 'SSIS.Pipeline'
ORDER BY EM.operation_id DESC
For the detail explanation please the: how to query SSISDB to find out the errors in the packages?