Reputation: 23
I have following function which does text logging but I keep getting below error then and there. Its not coming every time but only sometime and that too at IIS level. IIS Apppool is stopped after this error.
An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/2/ROOT/OrderHelpDesk
Process ID: 81044
Exception: System.UnauthorizedAccessException
Message: Access to the path '\Ser-file\ErrorLog\2018-09\09_27_2018.txt' is denied.
StackTrace: at OrderHelpDesk.DAL.LogMessage(String Message) at OrderHelpDesk.ViewPendingOrderDetails.AutoGenMailToCSRProcessed(Entity objEntity) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()
public void LogMessage(string Message)
{
Entity objEntity = new Entity();
StreamWriter sw = null;
try
{
objEntity.LogMessage = string.Format("\r\n{0:MM/dd/yyyy hh:mm:ss tt} : {1}", DateTime.Now, Message);
objEntity.LogFilePath = ConfigurationManager.AppSettings.Get("ErrorLogPath");
objEntity.LogFolderName = string.Format("{0:yyyy-MM}", DateTime.Now);
objEntity.LogFilePath = objEntity.LogFilePath + objEntity.LogFolderName;
if (!Directory.Exists(objEntity.LogFilePath))
{
Directory.CreateDirectory(objEntity.LogFilePath);
}
sw = File.AppendText(objEntity.LogFilePath + "\\" + string.Format("{0:MM_dd_yyyy}", DateTime.Now) + ".txt");
sw.WriteLine(objEntity.LogMessage);
}
catch (Exception Ex)
{
throw Ex;
}
finally
{
sw.Close();
}
}
Upvotes: 0
Views: 1570
Reputation: 9461
Use already implemented logging libraries like NLog.
if you can't
This happens because LogMessage can be called simultaneously by several threads. In this case one thread will get log file, while the other will get AccessDenied and your pool will crash because sw is null, but you call sw.Close(). Use synchronization primitives and using construction (or check sw for null sw?.Close()):
static object locker = new object();
public void LogMessage(string Message)
{
lock (locker)
{
Entity objEntity = new Entity();
objEntity.LogMessage = string.Format("\r\n{0:MM/dd/yyyy hh:mm:ss tt} : {1}", DateTime.Now, Message);
objEntity.LogFilePath = ConfigurationManager.AppSettings.Get("ErrorLogPath");
objEntity.LogFolderName = string.Format("{0:yyyy-MM}", DateTime.Now);
objEntity.LogFilePath = objEntity.LogFilePath + objEntity.LogFolderName;
if (!Directory.Exists(objEntity.LogFilePath))
{
Directory.CreateDirectory(objEntity.LogFilePath);
}
using (StreamWriter sw = File.AppendText(objEntity.LogFilePath + "\\" + string.Format("{0:MM_dd_yyyy}", DateTime.Now) + ".txt"))
{
sw.WriteLine(objEntity.LogMessage);
}
}
}
Upvotes: 3