我们在应用程序中使用log4net。真正的问题是日志消息未正确以异步方法记录。
我们有两个应用程序,第一个是控制台应用程序,另一个是.Net Web API。
我们在控制台应用程序中使用异步逻辑。我们正在通过异步方法在该控制台应用程序中调用API服务。在该API应用程序中也实现了Log4net。
我们已经在该API服务中记录了所有请求,但是有时未正确记录或跳过了日志文件中的日志。
Ex:控制台应用程序在该API服务中调用1000次。但是API服务无法写入所有请求,因此跳过了10或20个请求。
任何人都可以帮忙。
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
}
}
}
App.config
--------------------
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<!--log4net config section registration-->
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<!--log4net config (configurations) section-->
<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>