We are using log4net in our application. The real problem is the log messages not properly logged in Asynchronous method.
We have two applications First one is Console Application and another one is a .Net Web API.
We use Asynchronous logic in Console application. We are calling API service in that Console application through Asynchronous method. Log4net implemented in that API application also.
We have logged all the requests in that API service, but sometimes the log was not properly logged or skipped in the log file.
Ex: The Console application calling 1000 times in that API service. But the API service not writing all the requests, skipped 10 or 20 requests.
I have provided my API sample Code.
Any one please do the help.
Program.cs
------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using log4net;
using System.Reflection;
namespace Log4NetAsynchronous
{
class Program
{
public static async Task<int> Method1(int i)
{
return await Task.Run(() =>
{
Console.WriteLine("Method 1 ==> " + i.ToString() + "\n");
Logger.LogMsg("Method 1 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method1, Enums.LogType.INFO);
Logger.LogMsg("Method 1 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method1, Enums.LogType.DEBUG);
Logger.LogMsg("Method 1 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method1, Enums.LogType.ERROR);
Task.Delay(1500).Wait();
return 1;
});
}
public static async Task<int> Method2(int i)
{
return await Task.Run(() =>
{
Console.WriteLine("Method 2 ==> " + i.ToString() + "\n");
Logger.LogMsg("Method 2 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method2, Enums.LogType.INFO);
Logger.LogMsg("Method 2 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method2, Enums.LogType.DEBUG);
Logger.LogMsg("Method 2 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method2, Enums.LogType.ERROR);
Task.Delay(1500).Wait();
return 1;
});
}
public static async Task<int> Method3(int i)
{
return await Task.Run(() =>
{
Console.WriteLine("Method 3 ==> " + i.ToString() + "\n");
Logger.LogMsg("Method 3 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method3, Enums.LogType.INFO);
Logger.LogMsg("Method 3 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method3, Enums.LogType.DEBUG);
Logger.LogMsg("Method 3 -> Line Number: " + i.ToString() + Environment.NewLine, Enums.Methods.Method3, Enums.LogType.ERROR);
Task.Delay(1500).Wait();
return 1;
});
}
public static async Task<IEnumerable<int>> Invoke1()
{
var method1 = new List<Task<int>>();
for (int i = 1; i <= 3; i++)
{
method1.Add(Method1(i));
}
return await Task.WhenAll(method1);
}
public static async Task<IEnumerable<int>> Invoke2()
{
var method2 = new List<Task<int>>();
for (int i = 1; i <= 5; i++)
{
method2.Add(Method2(i));
}
return await Task.WhenAll(method2);
}
public static async Task<IEnumerable<int>> Invoke3()
{
var method3 = new List<Task<int>>();
for (int i = 1; i <= 5; i++)
{
method3.Add(Method3(i));
}
return await Task.WhenAll(method3);
}
static void Main(string[] args)
{
Console.WriteLine("Start");
var res1 = Invoke1();
var res2 = Invoke2();
var res3 = Invoke3();
Console.WriteLine("Succes");
Console.ReadKey();
}
}
}
--------------
Logger.cs
--------------
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Log4NetAsynchronous
{
public static class Logger
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static void LogMsg(string msg, Enums.Methods Methods, Enums.LogType logType)
{
string strLogFileName = String.Empty;
switch (Methods)
{
case Enums.Methods.Method1:
strLogFileName = "Method1";
break;
case Enums.Methods.Method2:
strLogFileName = "Method2";
break;
case Enums.Methods.Method3:
strLogFileName = "Method3";
break;
default:
strLogFileName = "Method1";
break;
}
log4net.GlobalContext.Properties["LogFileName"] = strLogFileName;
log4net.Config.XmlConfigurator.Configure();
ILog log = LogManager.GetLogger(typeof(Logger));
string timeStamp = string.Empty;
switch (logType)
{
case Enums.LogType.DEBUG:
log.Debug(msg);
break;
case Enums.LogType.INFO:
log.Info(msg);
break;
case Enums.LogType.ERROR:
log.Error(msg);
break;
default:
log.Info(msg);
break;
}
}
}
}
-----------------
Enums.cs
-----------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Log4NetAsynchronous
{
public class Enums
{
public enum Methods : int
{
Method1 = 1,
Method2 = 2,
Method3 = 3,
}
public enum LogType : int
{
DEBUG = 0,
INFO = 1,
WARN = 2,
ERROR = 3,
FATAL = 4,
LOGDBINFO = 5,
LOGSERVICEINFO = 6
}
}
}
<pre>App.config
--------------------
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<!--
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<!--
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="InfoLogAppender" />
<appender-ref ref="DebugLogAppender" />
<appender-ref ref="ErrorLogAppender" />
</root>
<appender name="InfoLogAppender" type="Log4NetAsynchronous.AsynchronousFileAppender">
<file type="log4net.Util.PatternString" value="D:\\Logs\\InfoLog\\%property{LogFileName}\\" />
<datePattern value="dd-MMM-yyyy'.log'" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<maximumFileSize value="10MB" />
<param name="StaticLogFileName" value="false"/>
<threshold value="INFO" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{dd/MMM/yyyy hh:mm:ss} [%level] - %message" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="INFO" />
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
</appender>
<appender name="DebugLogAppender" type="Log4NetAsynchronous.AsynchronousFileAppender">
<file type="log4net.Util.PatternString" value="D:\\Logs\\DebugLog\\%property{LogFileName}\\" />
<datePattern value="dd-MMM-yyyy'.log'" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<threshold value="DEBUG" />
<maximumFileSize value="10MB" />
<param name="StaticLogFileName" value="false"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{dd/MMM/yyyy hh:mm:ss} [%level] - %message" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="DEBUG" />
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
</appender>
<appender name="ErrorLogAppender" type="Log4NetAsynchronous.AsynchronousFileAppender">
<file type="log4net.Util.PatternString" value="D:\\Logs\\ErrorLog\\%property{LogFileName}\\" />
<datePattern value="dd-MMM-yyyy'.log'" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<threshold value="ERROR" />
<maximumFileSize value="10MB" />
<param name="StaticLogFileName" value="false"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{dd/MMM/yyyy hh:mm:ss} [%level] - %message" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<levelMax value="ERROR" />
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
</appender>
</log4net>
</configuration>
What I have tried:
Actually the same logic only we have implemented in our API.
This code also getting the same issue whatever I'm getting in our API application.
Thanks,
Rajesh