在Log4Net的配置文件中可以添加多个UdpAppender节点,用来向不同的UDP服务器发送日志。
但是,如果需要动态接收UDP日志呢,每个未知的客户端都可以接收Log4Net的UDP日志,那么就需要在软件中开启一个监听UDP消息的线程,接收到UDP主机的IP和端口后,动态添加UDP Server信息到Log4Net的配置中,这样Log4Net就能同时向多个UDP Server发送日志了。
由于是动态添加UDP Server,所以Log4Net的配置文件中就可以没有UdpAppender节点了(也可以配置几个固定的IP、端口),下面上主要代码。
1、软件中监听UDP Server消息的线程
/// <summary>
/// UDP Server发现线程回调函数
/// </summary>
private void RecvUdpServerMessage()
{
IPEndPoint remoteIp = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
try
{
byte[] bytRecv = _udpRecv.Receive(ref remoteIp);
string message = Encoding.UTF8.GetString(bytRecv, 0, bytRecv.Length);
message = message.Trim(); //类似"UDPServer:2018"
if (!message.StartsWith("UDPServer"))
{
continue;
}
var index = message.IndexOf(":", StringComparison.CurrentCulture);
if (index < 0)
{
continue;
}
//解析UDP端口
message = message.Substring(index + 1);
if (!int.TryParse(message, out var port))
{
continue;
}
remoteIp.Port = port;
UdpServerDiscovered?.Invoke(remoteIp);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
break;
}
}
}
2、UDP发现线程接收到消息后动态添加UdpAppender
/// <summary>
/// UDPServer发现回调
/// </summary>
/// <param name="remoteIp">远程UDP服务器IP信息对象</param>
private void OnUdpServerDiscovered(IPEndPoint remoteIp)
{
if (!_listUdpServer.Contains(remoteIp))
{
try
{
//创建UdpAppender
var appender = new log4net.Appender.UdpAppender()
{
Name = remoteIp.ToString(),
LocalPort = _localUdpPort++,
Encoding = Encoding.UTF8,
Layout = new log4net.Layout.PatternLayout(log4net.Layout.PatternLayout.DetailConversionPattern),
RemoteAddress = remoteIp.Address,
RemotePort = remoteIp.Port
};
appender.AddFilter(new log4net.Filter.LevelRangeFilter()
{
LevelMin = log4net.Core.Level.Debug,
LevelMax = log4net.Core.Level.Fatal
});
appender.ActivateOptions();
//添加UdpAppender
var root = ((log4net.Repository.Hierarchy.Hierarchy)log4net.LogManager.GetRepository()).Root;
root.CloseNestedAppenders();
root.AddAppender(appender);
_listUdpServer.Add(remoteIp);
UdpServerDiscovered?.Invoke(_listUdpServer);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}