I have been trying to write Logs(Trace, Information & Exception) in Azure AppInsights using Log4Net instead of default api Telemetry client. When I run the application from VS2013 neither I get any error message nor am seeing logs in Azure portal.
Pleaes help me figure out this issue.
Note: Am using Log4net appender for AppIinsights.
Web.Config
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="aiAppender" />
</root>
<appender name="aiAppender" type="Microsoft.ApplicationInsights.Log4NetAppender.ApplicationInsightsAppender, Microsoft.ApplicationInsights.Log4NetAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message%newline" />
</layout>
</appender>
MVC Controller
public class HomeController : Controller
{
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public ActionResult Index()
{
//Trace.TraceInformation("Home accessed at : {0}", DateTime.UtcNow);
Log.Info(string.Format("Home accessed at : {0}", DateTime.UtcNow));
return View();
}
}
Regards,
Rajaram.
If you are not seeing any log4net output, i'm presuming you are missing some log4net startup code, like this:
log4net.Config.XmlConfigurator.Configure();
which you might want in your startup class / code somewhere. Without that, log4net doesn't know wo read the configuration that's in web.config.
In addition to the answer from #JohnGardner, you can instead add a line to your AssemblyInfo.cs file as so: -
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
There is more discussion on the two approaches in the following question: -
Configure Log4Net in web application
And in a comment in somewhere in that discussion is a link to the log4net FAQs that touches on the differences in the question "When should I log my first message?": -
https://logging.apache.org/log4net/release/faq.html#first-log
I found both of these to be of further use to me.
Related
We are using log4net for our application logging in azure.
We configured it according to this document , the logs are stored in
d:/home/LogFiles/Application/Log4netfile-[%processid].txt
we can download the files from https://xxxx.scm.azurewebsites.net/api/dump and I can also see them in Log stream, there it looks like this
2022-02-06T18:22:57 PID[29616] Verbose log4net: Adding appender named [FileAppender] to logger [root].
2022-02-06T18:22:57 PID[29616] Verbose log4net: Hierarchy Threshold []
2022-02-06T18:22:58 PID[29616] Verbose LOG4NET Fatal LOG4NET LOG4NET
2022-02-06T18:22:58 PID[29616] Verbose LOG4NET Debug Message Message
Line items like:
log4net: Adding appender named
are created by log4net during internal setup (using debug=true), and those show up in our AppServiceAppLogs, however, items which are genereted by the logger using:
Logger.Fatal("LOG4NET Fatal LOG4NET LOG4NET");
are visible in stream and files but they are not showing up in AppServiceLogs.
I tried multiple different appenders the only one which shows up in Log-Streams and in files is FileAppender (or RollingFileAppender), all others are not showing in LogStreams or (as expected) in the files.
Based on this https://learn.microsoft.com/en-us/azure/app-service/troubleshoot-diagnostic-logs#send-logs-to-azure-monitor I assume that everything writen to the files should be than sent to azure-monitor - but in our case this is not hapening. Could you provide some reference about implementation / code how the sending of the files is done, and which process does that ?
I am wandering is there anything which we could configure differently to get the log-items to end up in AppServiceLogs? Or should we use some other appender?
I am aware of the issue in AspNetTraceAppender and I am trying to avoid implementation of new appender.
There are a few things you can look into:
Call log4net configure before writing to your log file (only once is enough):
log4net.Config.XmlConfigurator();
or
log4net.Config.XmlConfigurator.Configure();
and then you can add flushing to your configuration:
<appender name="AzureTraceAppender" type="log4net.Appender.TraceAppender">
<param name="ImmediateFlush" value="true" />
<layout type="log4net.Layout.PatternLayout">
<!-- can be any pattern you like -->
<conversionPattern value="%logger - %message" />
</layout>
</appender>
Immediately, this will flush the message.
In Global.asax, To make log4net read your configuration.
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
// Initialize log4net.
log4net.Config.XmlConfigurator.Configure();
}
Make sure Azure Diagnostics has configured to all information needed for debugging.
After that, you can enable internal log4net debugging. Refer internal debugging on this log4net faq page. Standard it should log to your listener you have configured. To the trace element Add the autoflush="true" option . Or find directory on the worker role you can write to and access to read your logs.
I would like to utilize Log4Net on a Dynamics 365 solution (plugins, etc.)
Is this possible somehow - I cannot just deploy a config file I guess, but are there a feasible way to do it anyhow?
The dream of mine is to unify logging, to place logging in one place, no matter if it is plug-ins, integrations or other functionality...
Besides using a configuration file, Log4net can accept its configuration from other sources using eg. a Stream or XmlElement.
To do so, you'll have to use the Log4net api via XmlConfigurator.Configure.
It is important not to apply the XmlConfiguratorAttribute; it's either one or the other.
The example below shows how to apply a configuration via an XmlElement.
The content of this XmlElement can be retrieved from anywhere; hardcoded, an embedded resource file, a record from a dabase, etc.
In the xml configuration, you declare any loggers that can be used within your Dynamics 365 environment.
string xml = #"
<log4net>
<appender name='consoleAppender' type='log4net.Appender.ConsoleAppender' >
<layout type='log4net.Layout.PatternLayout'>
<conversionPattern value='%date | %logger | %level | %message | %exception%n' />
</layout>
</appender>
<root>
<level value='ALL' />
<appender-ref ref='consoleAppender' />
</root>
</log4net>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlElement config = doc.DocumentElement;
ILoggerRepository repository = log4net.LogManager.GetRepository(Assembly.GetCallingAssembly());
XmlConfigurator.Configure(repository, config);
ILog logger = LogManager.GetLogger("somelog");
logger.Debug("foobar");
I'm using ServiceStack and ServiceStack.Logging.Log4Net. With the minimum config in my AppHost file:
log4net.Config.XmlConfigurator.Configure();
LogManager.LogFactory = new Log4NetFactory(true);
Request handler not found exceptions (i.e. no route was matched) are magically picked up and logged. I don't want to log these exceptions, but I can't figure out how to exclude them.
I've tried setting a custom exception handler:
ExceptionHandler = _appExceptionLogger.OnAppHostException;
but it doesn't appear to get hit for these exceptions.
So I searched in the ServiceStack source code for the string that was being logged and found that it was being logged by a NotFoundHttpHandler class
This means that I can override the logging behaviour by adding a custom logger to my log4net config:
ServiceStack v3:
<logger name="ServiceStack.WebHost.Endpoints.Support.NotFoundHttpHandler">
<level value="OFF" />
</logger>
ServiceStack v4:
<logger name="ServiceStack.Host.Handlers.NotFoundHttpHandler">
<level value="OFF" />
</logger>
I am into the development of a core dll where I have a class library.I want to use log4net to enable logging for exceptions. I have an app.config file in the class library where i have given the settings for the log4net.However when I test the class library the log4net does'nt create logs until i add the app.config in the calling project inspite of the fact that i had added [assembly: log4net.Config.XmlConfigurator(Watch = true)] in the class libary's assemblyinfo.cs and I am using log4net.ILog logger = log4net.LogManager.GetLogger(typeof(ErrorHandler)) where ErrorHandler is the name of my class library's class where log4net's calling functions are handled.Any ideas on what is going wrong?
Secondly, what I want to acheive is the users of my dll will just pass the location where they want to create logs and whether they want to create logs in event viewer or log files from their app.config? They will not handle any other setting of log4net.
Any suggestions or code snippets for the first issue and the second problem?
Only the "main" app.config is active for a .Net application. Your library config file is simply ignored. Either you transfer your settings to the main config file or you use an external config file for log4net. You configure it then for instance like this (assuming you call it log4net.config):
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
Please note that the structure of the config file is a bit different:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="YourAppender" type="..." >
....
</appender>
<root>
<level value="ALL" />
<appender-ref ref="YourAppender" />
</root>
</log4net>
As for your second problem: I am not sure how flexible this has to be. Is it just switching from file appender to event log appender? Depending on your answer you may consider two prepare to configuration files (e.g. file.log4net and eventlog.log4net) and read the configuration as needed (in that case you cannot use the attribute: you call the Configure() method directly) or if your requirements are more complex you might even end up configuring log4net programatically.
Is there an appender in log4net that can allow a winform client to read a log4net log on another server without using a share? My application is hosted as a web service. I'm looking for an HTTP appender or something similar.
There is a GitHub project called PostLog that is a HttpAppender for log4net.
I think you could use the Remoting Appender, something like this:
<appender name="RemotingAppender" type="log4net.Appender.RemotingAppender" >
<sink value="http://localhost:8080/LoggingSink" />
<lossy value="false" />
<bufferSize value="95" />
<onlyFixPartialEventData value="true" />
</appender>
According to the docs:
This Appender is designed to deliver
events to a remote sink. That is any
object that implements the
RemotingAppender.IRemoteLoggingSink
interface. It delivers the events
using .NET remoting. The object to
deliver events to is specified by
setting the appenders Sink property.
There is also a UdpAppender and there is this open source client that can receive these messages:
http://log2console.codeplex.com/