Multi-threaded utility that logs some audit trails
DO NOT LOCK ON EMPTY STRING

In .NET every string is stored only once in the AppDomain so if you are locking on empty string everything will stop until you release the lock.

The correct syncroot can be:

private readonly object _flag = new object();


And yes you should use double check locking. The other thing is thati would use a ConcurrentQueue instead of SynchronizedCollection.