In my application, I've got the following logging strategy/appenders:
DebugAppender: If the root level is DEBUG, write every message that matches DEBUG to the default trace listener output
ConsoleAppender: If the application mode (global context property) is 'console', write every message above WARN to the console ouput
EventLogAppender: If the application mode (global context property) is 'service', write every message above ERRROR to the console output
RollingFileAppender: Write every message above INFO to a rolling flat file
This works very well throughout the whole application, until the very first line I'm starting the OWIN web host using the IAppBuilder interface. As soon as I invoke WebApp.Start, I noticed the following behavior:
Debug messages (ILogger.Debug) are getting written to the console output
Debug messages (ILogger.Debug) are getting written twice to the VS debug output
Upon further investigation, I figured out that OWIN silently attached an instance of System.Diagnostics.DefaultTraceListener and System.Diagnostics.TextWriterTraceListener to the default trace/debug ouput, which may be the root of the problem. However, declaring the DefaultTraceListener in app.config explicitly didn't help.
Is there any way I can configure OWIN to be less... sneaky?
You can remove the listener in startup code, eg:
Trace.Listeners.Remove("HostingTraceListener");
(Name from source code)
Related
I've got a small console application running TopShelf and using Serilog as the logging facility where I'd like to run OWIN inside. However as soon as I start the app builder, every log message gets duplicated via the trace listener and thus, printed out twice to the console.
// serilog sink configuration
new LoggerConfiguration()
.WriteTo.Trace()
...
.CreateLogger();
// topshelf
HostLogger.UseLogger(new SerilogLogWriterFactory.SerilogHostLoggerConfigurator());
I already found this answer here and included the following before I start the web host:
webHostOptions.Settings.Add(typeof (ITraceOutputFactory).FullName,
typeof (WebAppBuilder.NullTraceOutputFactory).AssemblyQualifiedName);
Trace.Listeners.Remove("HostingTraceListener");
The funny thing is: When I first started the application after inserting those lines, it worked (e.g. double messages were gone.). However after I cleaned my \bin directory, they started to appear again. What do?
Please check out this highly professional drawing I just made which should further explain the issue:
(zoom)
I've two problem using Nlog internal logging.
Firstly while starting I execute the following code:
LogManager.Configuration = new
NLog.Config.XmlLoggingConfiguration("NLog.debug.config", true);
LogManager.ReconfigExistingLoggers();
InternalLogger.LogToConsole = true;
InternalLogger.LogToConsoleError = true;
InternalLogger.LogLevel = LogLevel.Trace;
LogManager.ThrowExceptions = true;
InternalLogger.LogFile = Path.Combine(ConfigurationManager.AppPath, "Nlog.log");
My first problem is the logToconsole do not display in my Visual output. Is that normal ?
My second issue is when I try to log on C:\log.txt (to test internal log)
This should crash because Nlog cannot create files at the root of C:.
Unfortunaly It do not crash (and do not create the file) (it works with C:\test\log.txt for example).
Here my internal Nlog.log content:
2015-04-23 18:44:09.8593 Debug TestManager.Info Rejecting message
because of a filter. 2015-04-23 18:44:09.8593 Debug TestManager.Info
Rejecting message because of a filter. 2015-04-23 18:44:09.8593 Debug
TestManager.Info Rejecting message because of a filter. 2015-04-23
18:44:09.8593 Debug TestManager.Info Rejecting message because of a
filter. 2015-04-23 18:44:09.8593 Trace Opening C:test.log with
concurrentWrite=False
Rejected is normal (I've several targets)
So Why haven't I exception and no trace ?
Thanks a lot for the incoming help
NLog probably uses the conventional Console.WriteLine(…) method to send messages to console. It will not work in WinForms application because Console.WriteLine(…) does nothing in WinForms application by default. It only works, however, when you are debugging from Visual Studio since that provides a console window for Output
Try to call Win32 API function AllocConsole at the beginning of your application. It should create a console for your WinForms application and enable Console.WriteLine(…) function. Here you can find an example of the code that shows how to call AllocConsole. "See link for setting this up".
Also quoting Nlog github page on internal logging
There are 3 environment variables which control internal logging. You
can set those variables before running your program to enable internal
logging:
NLOG_INTERNAL_LOG_TO_CONSOLE - if this variable is found in the
environment, will outputs internal diagnostic information to the
console
For your second question, looking at your logs I believe you did not provide the path in correct format by escaping the backslash character
It should be like
fileName="C:\\logssamplefile.txt"
Please note that this worked for me
I have written some code in the application_start() method in my global.asax file. It does not get called when I deploy my application on IIS server. The code is accessible when I run it in the .NET framework.
I've tried to restart the application many times, but it's still not working.
I've also tried the suggestion from the following link.
Application_Start not firing?
There are few things you need to know before you are trying to debug Appplication_Start. There are -
One : When the code executes and why it is almost impossible to debug by attaching to it.
The application start method is executed when the application pool starts and your website is being started up for the first time. If you deploy new deliverables to IIS, then IIS might restart it itself, but there is no guarantee that it will. So, deploying new codes does not guarantee that it will restart the pool and he execution of application start. You should restart your application pool to guarantee execution of application start.
While debugging IIS applications, Visual Studio attaches itself to a process something named w3wp.exe or similart (I forgot the actual executable name), which is the worker process and only available after, remember after, your application pool is up and your site is up. So, in other words, if you are seeing this in service list, then the application start has already been executed and attaching to it will not give you a chance to debug it. It is kind of a tug of war with time.
So, in other words, it is kind of impossible to debug application start unless you are very very quick.
Two, the solution 1 - With Dev Server
Launch your application in visual studio with Asp.net development server or IIS express, then you will be able to debug. But if you really want to debug on IIS, then check the next section
Two, the solution 2 - With IIS
There is a library in the name System.Diagnostics, Debuggerand it has a nice way to call debugger in code. You can read it here - http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.break(v=vs.110).aspx
Modify you application start with this -
public void Application_Start(){
....... //other codes
Debugger.Break() or Debugger.Launch()
}
When this line executes, IIS will halt execution, and will show you a debugger selector window (similar to the one attached), keep your solution open in vs and select that vs from the list, will be able to debug as usual... :)
In case you are using windows 8 and the debugger does not launch, read this article to enable it -
http://blogs.msdn.com/b/mapo/archive/2013/11/07/debugger-launch-not-displaying-jit-debugger-selection-popup-on-windows-8-8-1.aspx
Three: A very important thing
I noticed that you said, you are adding db entries in Application_Start. You should keep in mind that, Application_Start does not have a HttpContext, ViewContext, So your db access code may fail for so many others reasons.
Make sure that the Global.asax file is actually deployed to the destination folder in the root. If the file is not present then the code behind you have written for Application_Start will never be called.
Also make sure the signature is correct
public class Global : System.Web.HttpApplication {
protected void Application_Start(object sender, EventArgs e) {/*do something here like logging so you know it was called*/}
}
If you are running Server 2008R2 (or earlier) and/or IIS 7.5, you might want to look into the Application Initialization module. This can be downloaded here:
www.iis.net/downloads/microsoft/application-initialization
With IIS versions prior to 8.0, the application start is not called until the first web request arrives. I'm reading your question as you want your application start to be fired before the first web request, yes?
Here is a fantastic guide to configuring this module (if it applies to you):
https://blogs.msdn.microsoft.com/benjaminperkins/2014/01/07/configure-the-iis-application-initialization-module/
The key takeaways is that you need to set your app pool to 'AlwaysRunning' instead of 'OnDemand'. You also need to set a preloadEnabled flag for your website. Once both of these are done, fire off an iisreset and you should see the results of your application start (look in the database since it's writing there).
Other answers are relevant as well, in that this is tough to debug and you're missing all the niceties you're used to such as a httpcontext in app start.
If you are running IIS 8.0 - you should still read the above link to configure preloading.
This did work for me:
Menu -> Build -> Clean Solution
Menu -> Build -> Rebuild Solution
Then, Application_Start() was fired only for the first time.
In my case in production environment App_global.asax.compiled was missing and all content of global.asax not fired.
I need my service to check for existence and structure of certain files during its startup and exit/fail/stop if some conditions aren't met.
I read this thread: What is the proper way for a Windows service to fail?
but it does not help.
I set the ServiceBase.ExitCode property non-zero and then call ServiceBase.Stop. But I get 5 event log entries. See below:
Starting service. (I log this event via code)
Config.xml file not found. (I log this ERROR event via code)
Service stopped successfully. (SCM logs this message)
Service started successfully. (SCM logs this message)
Service cannot be started. The handle is invalid (SCM logs this message)
As you see everything goes OK except for the last two entries. Why are they there? What can I do to properly shutdown the service during startup? Why doesn't SCM see the service as stopped/failed?
You don't provide enough code to really know, but I suspect you are trying to validate the service and stop it in either the constructor or the OnStart. The way I like to handle services is start my timer in the OnStart. In the first interval of the timer I can validate all the code, if its invalid close the Service. If its valid, reset the interval of the timer to how frequently I want it to run then set a bool that tells it not to check for validity of files again.
What is the return code you are using for your ExitCode? If it matches the corresponding windows ExitCode, then that is what will be recorded by SCM. I'm assuming you are returning a 6 for your ExitCode.
The other thing is if you can run on Default values do that, let Config.xml be missing and just record the problem in the EventLog. "Configuration file Missing"
If you really want it to just abort during OnStart, set your ExitCode and then Throw an Exception (InvalidArgumentException, InvalidOperationException) for example
This article also has some good advice. .NET: Which Exception to Throw When a Required Configuration Setting is Missing?
You are trying to start second instance of service (another service registered for the same .exe)
I have a C# console app called during the startup of a WebRole to perform customized instrumentation. I'd like for this program to be able to read the latest values from Service Config and act accordingly.
I've setup the startup script that calls my .EXE to run in elevated mode. I've added a reference to Azure's ServiceRuntime to the console app, however I'm getting the following error: role discovery data is unavailable
If you've put calling this executable as a start-up task in the .csdef, then the information you're asking for may not be available as the role has not yet been set up (see lifecycle of Web/Worker role).
This could also be the problem if you're calling the executable within OnStart in WebRole.cs - as IISConfigurator is called asynchronously with OnStart.
For the startup task, one work around for this is detailed at http://mvolo.com/configure-iis-websites-windows-azure-startup-tasks-appcmd/ (although it deals with changing IIS configuration).
For the WebRole issue, you could overload Run() and call your executable from there - possibly with retries like:
while (!RoleEnvironment.IsAvailable) {
Thread.Sleep(1000);
}
RunExecutable();