Thursday, November 18, 2004

Windows/.NET Event logging (with Internationalization/parameter features in a message file)

Event logging pre-.NET
When you access the event log using the standard NT API calls, the system stores a structure that contains (amongst other things) the message ID and any replacement strings ("inserts") for the message -- but it does not store the message text itself.
Reading from the log
When you read an entry from an event log, the system reads the stored message ID and replacement strings, gets the text of the message for the current locale from a MESSAGETABLE resource contained within the file specified in the EventMessageFile key in the registry, inserts the replacement strings, and returns you the formatted string.
As well as keeping the log file small (which improves performance when accessing the event log on a remote machine), just storing the message ID and replacement strings also means that the same message can be viewed in different languages as long as the client:Has the file installed that contains that locales MESSAGETABLE The local registry has been configured to tell NT where to find it The file containing the messages only has to be installed on the machine that is doing the reading and does not have to exist on the one that is doing the writing or the one that holds the log (they can all be different machines).
Event logging with .NET
Under .NET, message sources are registered with the EventMessageFile value always set to EventLogMessages.dll, which is installed in the GAC. This file has 65,535 entries, each of which contain a single string: %1In other words, for every possible event ID the entire format string is a placeholder that takes a single replacement string -- which is always the message that you pass to EventLog.WriteEntry()

  • The main drawbacks with this approach are:
    You have the responsibility of choosing the locale that should be used to format the message before writing it to the log and so all clients have to view the message in the same language
  • The log file is larger than necessary as it has to hold the full formatted string rather than just the message ID and replacement strings
  • If you want to view the entries written to a remote log on that machine, it must have the .NET runtime installed and the EventLogMessages.dll file registered in the remote computer's GAC.

Read on for the solution class at.... http://www.codeproject.com/csharp/eventlogex.asp

Thanks to the Author for this public code.

SQL Server: @@IDENTITY deadlock problem and fix

This interesting problem occurs only when there is a call to update after the insert and the @@IDENTITY value has to be locked, so there is a deadlock trying to get a hold of this value.

CREATE TABLE [test]
(
[a] [int] IDENTITY (1, 1) NOT NULL ,
[b] [varchar] (10) NULL ,
[c] [int] NULL ,
CONSTRAINT [PK__test] PRIMARY KEY CLUSTERED ( [a] )
)
GO

Here [a] and [c] have to have the same value.

So, this programmer goes ahead and adds a trigger to do this on the insert operation.


CREATE TRIGGER test_update ON dbo.test
FOR INSERT
AS
begin
update dbo.test set c = a
end;

And, the insert statement called by two threads(client processes) simultaneously is:

insert into test(b) VALUES ('test111')

This leads to a deadlock and this "Error Message:"
"Exception Transaction Process (PID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim.
Rerun the transaction"

The fix:
insert into test(b,c) VALUES ('test111',@@IDENTITY)

Notes: