问题
I got a log4net file in which I added the following : I want to be able to inject the RemoteAddress variable from my appSetting.json file via the startup.cs page. But I am getting the following error :
log4net:ERROR Could not create Appender [UdpAppender] of type [log4net.Appender.UdpAppender]. Reported error follows. log4net.Util.TypeConverters.ConversionNotSupportedException: Cannot convert from type [System.String] value [%propery{RemoteAddress}] to type [System.Net.IPAddress] ---> System.Net.Sockets.SocketException: No such host is known at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6) at System.Net.Dns.ResolveCallback(Object context)
The code in the log4net file -
<appender name="UdpAppender" type="log4net.Appender.UdpAppender">
<RemoteAddress value="%propery{RemoteAddress}" />
<RemotePort value="5005" />
<encoding value="utf-8"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %property{log4net:HostName} - %message%newline" />
</layout>
</appender>
I added in the startup file the following code -
//logging
XmlDocument log4NetConfig = new XmlDocument();
log4NetConfig.Load(File.OpenRead("log4net.config"));
var repo = log4net.LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));
log4net.GlobalContext.Properties["LogFileName"] = env.ContentRootPath + Configuration["AppSettings:Logging:LoggerPath"];
log4net.GlobalContext.Properties["RemoteAddress"] = System.Net.IPAddress.Parse(Configuration["AppSettings:Logging:RemoteAddress"]);
log4net.Config.XmlConfigurator.Configure(repo, log4NetConfig["log4net"]);
log4net.LogManager.GetLogger(typeof(Startup)).Info($"Invoice service started. environment={env.EnvironmentName}");
Is it not possible to add the remote Address dynamically? When I use the actual IP address in the log4net file instead of using "%propery{RemoteAddress}"
and log4net.GlobalContext.Properties["RemoteAddress"] = System.Net.IPAddress.Parse(Configuration["AppSettings:Logging:RemoteAddress"]);
it is working.
回答1:
This can be achieved via a custom type converter (via IConvertFrom).
You can reuse the implementation of Log4net's PatternString for the parsing of the context properties (here: %property{RemoteAddress}
).
The type converter looks like here below, parsing and converting the configured value to an IPAddress
.
public class IPAddressPatternConverter : IConvertFrom
{
public IPAddressPatternConverter()
{}
public Boolean CanConvertFrom(Type sourceType)
{
return typeof(String) == sourceType;
}
public Object ConvertFrom(Object source)
{
String pattern = (String)source;
PatternString patternString = new PatternString(pattern);
String value = patternString.Format();
return IPAddress.Parse(value);
}
}
At the start of your application you register it with Log4net's ConverterRegistry
via
log4net.Util.TypeConverters.ConverterRegistry.AddConverter(typeof(IPAddress), new IPAddressPatternConverter());
The xml configuration stays as-is:
(Notice to specify %property instead of %propery.)
<appender name="UdpAppender" type="log4net.Appender.UdpAppender">
<RemoteAddress value="%property{RemoteAddress}" />
<!-- Remaining settings. --->
</appender
You configure the actual IP address via the context property involved.
String ipAddress = "127.0.0.1";
log4net.GlobalContext.Properties["RemoteAddress"] = ipAddress;
来源:https://stackoverflow.com/questions/52813014/log4net-config-file-for-net-core-with-udp-append-remote-address-dynamically