Saturday, March 21, 2015

How to get system/error messages with severity level lower than 19 logged to Application Log

Have you noticed that SQL Server does not send all messages to Application Log? The default setting does not send all messages, generally messages with severity level between 19 and 25 are automatically written but not all. The best way to check which messages that are getting logged, is checking sys.messages catalog view. This has all messages and the column is_event_logged indicates whether the messages will be logged or not.

Now, what if you need to get a message logged which is not get logged automatically? Good example is, a message related to deadlock. If you check this message, you will see that its is_event_logged is not set to 1.

  1. SELECT * FROM sys.messages   
  2. WHERE language_id = 1033 AND severity = 13;  


If required, this can be enabled for logging. It can be done using sp_altermessage stored procedure. Here is the way of doing it.

EXECUTE sp_altermessage 1205, 'WITH_LOG', 'True';

Now it is enabled. If you run the first code again, result will be just like this:


Let's test this. Below code generates a deadlock.

  1. USE master;  
  2. GO  
  3.   
  4. -- Create a sample database  
  5. IF EXISTS (SELECT * FROM sys.databases WHERE name = 'DeadlockTestDB')  
  6.  DROP DATABASE DeadlockTestDB;  
  7. GO  
  8.   
  9. CREATE DATABASE DeadlockTestDB;  
  10. GO  
  11.   
  12.   
  13. -- Add two tables and insert two records  
  14. USE DeadlockTestDB;  
  15. GO  
  16.   
  17. CREATE TABLE Table01 (Id int PRIMARY KEYName varchar(200));  
  18. GO  
  19. INSERT INTO Table01 VALUES (1, 'Table01 value');  
  20. GO  
  21.   
  22. CREATE TABLE Table02 (Id int PRIMARY KEYName varchar(200));  
  23. GO  
  24. INSERT INTO Table02 VALUES (100, 'Table02 value');  
  25. GO  
  26.   
  27.   
  28. -- Create two stored procedures.  
  29. -- This one updates a record in Table01, waits,   
  30. -- and updates Table02.  
  31. CREATE PROC UpdateTable01andTable02  
  32. AS  
  33. BEGIN  
  34.   
  35.  BEGIN TRAN  
  36.   
  37.   UPDATE Table01  
  38.    SET Name = 'Updated'  
  39.   WHERE Id = 1;  
  40.   
  41.   WAITFOR DELAY '00:00:10';  
  42.   
  43.   UPDATE Table02  
  44.    SET Name = 'Updated'  
  45.   WHERE Id = 100;  
  46.   
  47.  COMMIT TRAN  
  48. END;  
  49. GO  
  50.   
  51. -- This one updates a record in Table02 and Table01  
  52. CREATE PROC UpdateTable02andTable01  
  53. AS  
  54. BEGIN  
  55.   
  56.  BEGIN TRAN  
  57.   
  58.   UPDATE Table02  
  59.    SET Name = 'Updated - 2'  
  60.   WHERE Id = 100;  
  61.   
  62.   
  63.   UPDATE Table01  
  64.    SET Name = 'Updated -2'  
  65.   WHERE Id = 1;  
  66.   
  67.  COMMIT TRAN  
  68. END;  
  69. GO  
  70.   
  71. /*  
  72.   
  73. -- Open a new connection and run this code  
  74. USE DeadlockTestDB;  
  75. GO  
  76.   
  77. EXEC UpdateTable01andTable02;  
  78. GO  
  79.   
  80. -- Open another connection and run this.  
  81. -- Make sure this run just after you start the above execution  
  82. USE DeadlockTestDB;  
  83. GO  
  84.   
  85. EXEC UpdateTable02andTable01;  
  86. GO  
  87. */  

Once you get the code executed and received the deadlock error, open the Event Viewer and see. You should see something like this;


No comments: