J'essaie d'implémenter une journalisation à l'échelle du système, qui consignerait toutes les exécutions de procédure stockée ayant échoué dans notre dabatase et j'examinerais les événements étendus.La requête de journalisation SQL Server a échoué requêtes
Je l'ai fait quelques recherches et il semble assez facile à capturer des déclarations a échoué en utilisant le code suivant:
--Create an extended event session
CREATE EVENT SESSION what_queries_are_failing ON SERVER
ADD EVENT sqlserver.error_reported (
ACTION (sqlserver.sql_text
, sqlserver.tsql_stack
, sqlserver.database_id
, sqlserver.username
)
WHERE ([severity] > 10)
)
ADD TARGET package0.asynchronous_file_target (
SET filename = 'C:\XEventSessions\what_queries_are_failing.xel'
, metadatafile = 'C:\XEventSessions\what_queries_are_failing.xem'
, max_file_size = 5
, max_rollover_files = 5
)
WITH (MAX_DISPATCH_LATENCY = 5 SECONDS)
GO
-- Start the session
ALTER EVENT SESSION what_queries_are_failing ON SERVER STATE = START
GO
;WITH events_cte
AS (
SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), CURRENT_TIMESTAMP), xevents.event_data.value('(event/@timestamp)[1]', 'datetime2')) AS [err_timestamp]
, xevents.event_data.value('(event/data[@name="severity"]/value)[1]', 'bigint') AS [err_severity]
, xevents.event_data.value('(event/data[@name="error_number"]/value)[1]', 'bigint') AS [err_number]
, xevents.event_data.value('(event/data[@name="message"]/value)[1]', 'nvarchar(512)') AS [err_message]
, xevents.event_data.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS [sql_text]
, xevents.event_data
FROM sys.fn_xe_file_target_read_file('S:\XEventSessions\what_queries_are_failing*.xel', 'S:\XEventSessions\what_queries_are_failing*.xem', NULL, NULL)
CROSS APPLY (
SELECT CAST(event_data AS XML) AS event_data
) AS xevents
)
SELECT *
FROM events_cte
ORDER BY err_timestamp;
Cependant, je voudrais enregistrer immédiatement instruction a échoué dans une table, nous allons l'appeler mais je Logs.Errors
ne pouvait pas trouver un moyen de le faire et la méthode supérieure devrait fonctionner comme un travail planifié.
En ce moment, nos procédures ressemblent à ce que:
CREATE PROCEDURE [dbo].[MyProcedure]
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
SELECT 1;
END TRY
BEGIN CATCH
EXECUTE Logs.PrintError;
EXECUTE Logs.LogError;
END CATCH
END
Lorsque la procédure Logs.LogError
fait usage de DBCC INPUTBUFFER();
mais il ne tient pas compte des paramètres, juste la procédure exacte qui a été exécuté. C'est tout ce que je peux obtenir de lui:
+----------------------------+-----------+-----------+------------------------------+
| ErrorMessage | EventType | Parameter | Statement |
+----------------------------+-----------+-----------+------------------------------+
| Incorrect syntax near '.'. | RPC Event | 0 | DbName.dbo.FailedProcedure;1 |
+----------------------------+-----------+-----------+------------------------------+
Je suis à la recherche d'un moyen de rendre le travail soit DBCC INPUTBUFFER()
en le forçant à capturer tout ou déclaration XE pour insérer des enregistrements directement dans une table, si cela est possible.
Toutes les questions - faites le moi savoir.
Pouvez-vous s'il vous plaît donner des détails sur 'il la méthode supérieure devrait travailler comme prévu job.' – TheGameiswar
@TheGameiswar Bien sûr. J'avais à l'esprit que les événements étendus pourraient s'exécuter en arrière-plan et stocker des informations de requêtes échouées dans un fichier donné. Ensuite, basé sur un horaire (disons toutes les heures), je pourrais lire ce fichier et insérer des enregistrements dans la table 'Logs.Errors'. Cela a-t-il plus de sens maintenant? –
Vous n'avez pas besoin d'exécuter des événements étendus démarrer et arrêter des événements en tant que travail, une fois que vous l'avez démarré, il s'exécute en arrière-plan – TheGameiswar