Làm cách nào để SQL Server gửi email cho tôi chi tiết lỗi khi công việc thất bại?


14

SQL Server cho phép bạn định cấu hình một công việc để gửi thông báo qua email khi thất bại. Đây là một cách đơn giản và hiệu quả để theo dõi công việc của bạn. Tuy nhiên, những cảnh báo này không bao gồm bất kỳ chi tiết nào - chỉ là thông báo thành công hay thất bại.

Nếu một công việc thất bại, đây là một email thông báo thông thường sẽ như thế nào:

JOB RUN:        'DBA - Consistency Check Databases' was run on 8/14/2011 at 12:00:04 AM
DURATION:       0 hours, 0 minutes, 0 seconds
STATUS:         Failed
MESSAGES:       The job failed.  The Job was invoked by Schedule 2 (Nightly Before 
                Backup 12AM).  The last step to run was step 1 (Check Databases).

Để xác định nguyên nhân lỗi, bạn phải điều hướng đến phiên bản trong SQL Server Management Studio, tìm công việc và xem lịch sử thực hiện của nó. Trong một môi trường rộng lớn có thể là một nỗi đau khi phải liên tục làm điều này.

Email cảnh báo lý tưởng sẽ bao gồm lý do thất bại trả trước và cho phép bạn đi thẳng vào giải pháp.

Tôi quen thuộc với giải pháp này cho vấn đề này. Co ai co kinh nghiệm vê việc nay không? Hạn chế của nó là:

  1. bạn phải thêm một bước mới mỗi công việc bạn có, và
  2. bạn phải cầu nguyện rằng không ai làm phiền cảnh báo, spDBA_job_notification

Có ai đã đưa ra một giải pháp tốt hơn?

Câu trả lời:


10

Một cái gì đó bạn có thể làm đó chỉ là một ý nghĩ, loại bỏ ý tưởng ...

Tạo một công việc duy nhất kiểm tra định kỳ bảng công việc trong msdb để xem liệu có bất kỳ công việc nào hiển thị là không thành công hay không, điều đó có thể được thực hiện với truy vấn T-SQL tốt . Sau đó, bạn có thể vào bảng sysjobsteps và xem liệu nhật ký đầu ra có được thiết lập cho công việc không. Có một thủ tục được lưu trữ gửi một email đính kèm tập tin đó vào nó. Bạn sẽ có thể thấy chính xác những gì công việc đã làm từ đầu đến thất bại mà không cần phải chạm vào máy chủ.

Sau đó, cũng có thể có tập lệnh PowerShell kiểm tra lỗi nhật ký sự kiện. Nó cho phép bạn lọc ra một chút khá tốt để có được chính xác loại tin nhắn bạn đang tìm kiếm. Bạn có thể thiết lập công việc đó dưới dạng công việc Tác nhân SQL để chạy định kỳ. Sau đó, trong tập lệnh PowerShell, hãy sử dụng lệnh ghép ngắn email để gửi tin nhắn nếu nó tìm thấy.

Những ý tưởng xa vời ở đây, chỉ là một số tôi nghĩ về.


3

Tôi có kinh nghiệm với ý tưởng đã nói ở trên . Điều đó tốt, nhưng một ý tưởng tốt hơn sẽ là làm điều gì đó như Shawn nói.

Những gì chúng tôi đã làm là tạo ra một công việc chạy cứ sau 5 phút và quét các bảng MSDB về các thất bại công việc. Đối với mỗi công việc bị lỗi, chúng tôi sẽ chạy SP spDBA_job_notification với ID riêng của nó, vì vậy SP sẽ quét các bước lịch sử MSDB để tìm lỗi và gửi email tất cả. Từ tài liệu SP: "Quy trình được lưu trữ sử dụng ID công việc để truy vấn các bảng tác nhân msdb cho thông báo lỗi gần đây nhất cho công việc đó."

Vì vậy, thay vì chỉ thay đổi mọi công việc, tốt hơn là tạo một công việc duy nhất làm tất cả ;-).

Một ý tưởng khác là đặt tất cả các công việc để ghi vào Windows Event Viewer trong trường hợp có lỗi / lỗi và đọc từ đó với Proc xp_ReadErrorLog mở rộng hoặc một công cụ tự động, nếu bạn đã có trong mạng của mình. Ví dụ: chúng tôi đã sử dụng HPOV để kiểm tra mọi sự cố hệ thống và có thể định cấu hình cảnh báo đơn giản cho tất cả các lỗi của trình xem sự kiện (không cần bất kỳ công việc hoặc quy trình tùy chỉnh nào).


2

Hãy thử điều này và chỉ cần cắm các biến của bạn khi cần trong TSQL. Chìa khóa ở đây là đặt đây là bước cuối cùng của mỗi công việc tác nhân SQL riêng lẻ, nhưng mỗi bước công việc ở trên nó cần phải đi đến BƯỚC TIẾP dù đó là FAILURE hay THÀNH CÔNG ... Phần lớn tôi làm việc tốt làm báo cáo bất kỳ vấn đề bạn chạy qua. Chúng tôi đang sử dụng SQL Server 2008 R2, vì vậy đây là nơi nó được sử dụng hiện tại tôi đã thiết lập nó.

SELECT  step_name, message
FROM    msdb.dbo.sysjobhistory
WHERE   instance_id > COALESCE((SELECT MAX(instance_id) FROM msdb.dbo.sysjobhistory
                                WHERE job_id = $(ESCAPE_SQUOTE(JOBID)) AND step_id = 0), 0)
        AND job_id = $(ESCAPE_SQUOTE(JOBID))
        AND run_status <> 1 -- success

IF      @@ROWCOUNT <> 0
BEGIN
        RAISERROR('*** SQL Agent Job Prior Step Failure Occurred ***', 16, 1)

DECLARE @job_name NVARCHAR(256) = (SELECT name FROM msdb.dbo.sysjobs WHERE job_id = $(ESCAPE_SQUOTE(JOBID)))
DECLARE @email_profile NVARCHAR(256) = 'SQLServer Alerts'
DECLARE @emailrecipients NVARCHAR(500) = 'EmailAddr@email.com'
DECLARE @subject NVARCHAR(MAX) = 'SQL Server Agent Job Failure Report: ' + @@SERVERNAME
DECLARE @msgbodynontable NVARCHAR(MAX) = 'SQL Server Agent Job Failure Report For: "' + @job_name + '"'

--Dump report data to a temp table to be put into XML formatted HTML table to email out
SELECT sjh.[server]
    ,sj.NAME
    ,sjh.step_id
    ,sjh.[message]
    ,sjh.run_date
    ,sjh.run_time
INTO #TempJobFailRpt
FROM msdb..sysjobhistory sjh
INNER JOIN msdb..sysjobs sj ON (sj.job_id = sjh.job_id)
WHERE run_date = convert(INT, convert(VARCHAR(8), getdate(), 112))
    AND run_status != 4 -- Do not show status of 4 meaning in progress steps
    AND run_status != 1 -- Do not show status of 1 meaning success
    AND NAME = @job_name
ORDER BY run_date

IF EXISTS (
        SELECT *
        FROM #TempJobFailRpt
        )
BEGIN

-----Build report to HTML formatted email using FOR XML PATH
DECLARE @tableHTML NVARCHAR(MAX) = '
<html>
<body>
    <H1>' + @msgbodynontable + '</H1>
        <table border="1" style=
        "background-color: #C0C0C0; border-collapse: collapse">
        <caption style="font-weight: bold">
            ****** 
            Failure occurred in the SQL Agent job named: ''' + @job_name + ''' in at least one of the steps. 
            Below is the job failure history detail for ALL runs of this job today without needing to connect to SSMS to check.
            ******
        </caption>

<tr>
    <th style="width:25%; text-decoration: underline">SQL Instance</th>
    <th style="text-decoration: underline">Job Name</th>
    <th style="text-decoration: underline">Step</th>
    <th style="text-decoration: underline">Message Text</th>
    <th style="text-decoration: underline">Job Run Date</th>
    <th style="text-decoration: underline">Job Run Time</th>
</tr>' + CAST((
            SELECT td = [server]
                ,''
                ,td = NAME
                ,''
                ,td = step_id
                ,''
                ,td = [message]
                ,''
                ,td = run_date
                ,''
                ,td = run_time
            FROM #TempJobFailRpt a
            ORDER BY run_date
            FOR XML PATH('tr')
                ,TYPE
                ,ELEMENTS XSINIL
            ) AS NVARCHAR(MAX)) + '
    </table>
</body>
</html>';

EXEC msdb.dbo.sp_send_dbmail @profile_name = @email_profile
    ,@recipients = @emailrecipients
    ,@subject = @subject
    ,@body = @tableHTML
    ,@body_format = 'HTML'

--Drop Temp table
    DROP TABLE #TempJobFailRpt
END
ELSE
BEGIN
    PRINT '*** No Records Generated ***' 
    DROP TABLE #TempJobFailRpt
END
END

Tôi biết đây là một chủ đề cũ, nhưng giải pháp của @Crazy Ivan thực hiện một điều trị - Tôi có thể xác nhận nó hoạt động trên SQL Server 2012
Michael
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.