SQL 代理作业日志 - 无法获取错误日志

Joh*_*ers 5 sql-server sql-server-agent log

我想将一些日志提取到报告中,以便获取夜间运行的 SQL_Agent_Jobs 状态。如果作业失败,那么我想在表中接收错误日志。我试图通过以下查询获取该信息:

DECLARE @job_id UNIQUEIDENTIFIER

SELECT 
    @job_id = job_id FROM msdb.dbo.sysjobs 
WHERE 
       [name] like '%JOB_1%'
    OR [name] like '%JOB_2%'
    OR [name] like '%JOB_3%'
    OR [name] like '%JOB_4%'
    OR [name] like '%JOB_5%'

;WITH Error_Output (job_id, error_log) AS
(
    SELECT 
        JS.job_id,
        CASE
        WHEN JSL.[log] IS NULL THEN JH.[Message]
        ELSE JSL.[log]
        END AS LogOutput
    FROM 
        msdb.dbo.sysjobsteps JS 
        INNER JOIN msdb.dbo.sysjobhistory JH 
            ON JS.job_id = JH.job_id AND JS.step_id = JH.step_id 
        LEFT OUTER JOIN msdb.dbo.sysjobstepslogs JSL
            ON JS.step_uid = JSL.step_uid
    WHERE 
        INSTANCE_ID >
        (SELECT 
            MIN(INSTANCE_ID)
        FROM 
            (SELECT top (2) 
                INSTANCE_ID, job_id
            FROM 
                msdb.dbo.sysjobhistory
            WHERE 
                job_id = @job_id
                AND STEP_ID = 0
            ORDER BY 
                INSTANCE_ID desc
            ) A
        )
        AND JS.step_id <> 0 
        AND JH.job_id = @job_id
        AND JH.run_status = 0
)
SELECT 
    sj.name AS [Job Name]
    ,MAX(sja.run_requested_date) AS [Start Date]
    ,MAX(sja.start_execution_date) AS [Effective Start Date]
    ,MAX(sja.stop_execution_date) AS [Effective End Date]
    ,DATEDIFF(MINUTE, MAX(sja.start_execution_date), MAX(sja.stop_execution_date)) as [Job Execution Time -  M]
    ,CASE WHEN error_log IS NULL THEN 'Job runs successfully' else error_log end as [Job Log]
FROM 
    msdb.dbo.sysjobactivity AS sja
    INNER JOIN msdb.dbo.sysjobs AS sj ON sja.job_id = sj.job_id
    LEFT OUTER JOIN Error_Output AS error ON error.job_id = sja.job_id AND error.job_id = sj.job_id
WHERE 
       [name] like '%JOB_1%'
    OR [name] like '%JOB_2%'
    OR [name] like '%JOB_3%'
    OR [name] like '%JOB_4%'
    OR [name] like '%JOB_5%'
GROUP BY 
    sj.name, error_log
Run Code Online (Sandbox Code Playgroud)

但是,我总是得到作业运行“作业运行成功”,并且我已经测试并发现作业执行失败。我什至将 SQL_Agent_Job 配置为在作业失败时接收电子邮件,并且我已收到电子邮件,并且查询中的状态不会更改为错误日志(失败)。

我做错了什么?

AMt*_*two 4

我写了一篇关于从 msdb 检索作业状态的文章,您可以在此处查看。该帖子中的代码不会从 中提取数据,但如果您要登录到该表,dbo.sysjobstepslogs则可以非常简单地扩展该代码以从中提取最后一条错误消息。dbo.sysjobstepslogs

默认情况下,作业步骤不会记录到 msdb。要将作业步骤配置为记录到dbo.sysjobstepslogs,您必须进入作业中每个步骤的作业步骤属性,访问“高级”选项卡,然后选择“记录到表”选项: JobStepProperties-高级-LogToTable

然后,您可以创建此表值函数来获取最新的作业状态。我已经修改了上面帖子中的代码,以便还从作业中提取最新的错误(如果可用):

 CREATE FUNCTION dbo.SqlAgentJob_GetStatus (@JobName sysname)
     RETURNS TABLE
 AS
 RETURN
 SELECT TOP 1
     JobName        = j.name,
     IsRunning      = CASE
                        WHEN ja.job_id IS NOT NULL
                            AND ja.stop_execution_date IS NULL
                          THEN 1 ELSE 0 
                        END,
     RequestSource  = ja.run_requested_source,
     LastRunTime    = ja.start_execution_date,
     NextRunTime    = ja.next_scheduled_run_date,
     LastJobStep    = js.step_name,
     RetryAttempt   = jh.retries_attempted,
     JobLastOutcome = CASE
                        WHEN ja.job_id IS NOT NULL
                            AND ja.stop_execution_date IS NULL THEN 'Running'
                        WHEN jh.run_status = 0 THEN 'Failed'
                        WHEN jh.run_status = 1 THEN 'Succeeded'
                        WHEN jh.run_status = 2 THEN 'Retry'
                        WHEN jh.run_status = 3 THEN 'Cancelled'
                      END,
     LastError = (SELECT TOP 1 jsl.log 
                 FROM msdb.dbo.sysjobstepslogs jsl 
                 WHERE jsl.step_uid = js.step_uid
                 AND jsl.date_modified >= ja.start_execution_date)
 FROM msdb.dbo.sysjobs j
 LEFT JOIN msdb.dbo.sysjobactivity ja 
     ON ja.job_id = j.job_id
        AND ja.run_requested_date IS NOT NULL
        AND ja.start_execution_date IS NOT NULL
 LEFT JOIN msdb.dbo.sysjobsteps js
     ON js.job_id = ja.job_id
        AND js.step_id = ja.last_executed_step_id
 LEFT JOIN msdb.dbo.sysjobhistory jh
     ON jh.job_id = j.job_id
        AND jh.instance_id = ja.job_history_id
 WHERE j.name = @JobName
 ORDER BY ja.start_execution_date DESC;
 GO
Run Code Online (Sandbox Code Playgroud)

最后,您可以利用 TVF 查询作业状态、最后运行的步骤、最后记录的错误等:

 --Specific jobs
 SELECT sts.*
 FROM msdb.dbo.sysjobs j
 CROSS APPLY dbo.SqlAgentJob_GetStatus (j.name) sts
 WHERE 
        j.[name] like '%JOB_1%'
     OR j.[name] like '%JOB_2%'
     OR j.[name] like '%JOB_3%'
     OR j.[name] like '%JOB_4%'
     OR j.[name] like '%JOB_5%';
 --Failed Jobs
 SELECT sts.*
 FROM msdb.dbo.sysjobs j
 CROSS APPLY dbo.SqlAgentJob_GetStatus (j.name) sts
 WHERE sts.JobLastOutcome <> 'Succeeded';
Run Code Online (Sandbox Code Playgroud)