I've recently just discovered the power of Tracing(no clue why it took this long). The theory and practice wasn't unknown to me just the resources available in .Net for doing so. Traditionally I would just log the parts of my programs that I needed to investigate until I got an answer to any problems or confusion. As of recent this task just doesn't give me enough information and is far too tedious as my application is too big now. There are not a lot of clear resources on much of this so I have a few questions:
If I add my own trace listener source to the trace.listeners collection will that trace listener receive the trace information that can be seen in the trace.axd page when tracing is enabled in the web.config of my application?
If so how would I go about creating said listener that can receive that input? I've created my own class that implements the trace listener class and I can't seem to get any other input to be logged other than my own? Have I misunderstood something?
If there is another way to log my application line by line without having to place my own logging, that would be very very helpful. Thank you.
If I add my own trace listener source to the trace.listeners
collection will that trace listener receive the trace information that
can be seen in the trace.axd page when tracing is enabled in the
web.config of my application?
You will be able to see anything written to Trace. The trace that is written to trace.axd is a bit different from a plain vanilla TraceSource, TraceListener, etc. The biggest difference is that it uses the Trace object, which is the .NET 1.1 way of doing trace. in .NET 2.0 & later, named TraceSources are introduced.
If you register a TraceSwitch, TraceSource and TraceListener in your web config, you can enable listening to any TraceSource that you know the name of, the WCF libraries are an example.
Other places document TraceSource and TraceListener and switches better than I can, e.g. http://blog.stephencleary.com/2010/12/simple-and-easy-tracing-in-net.html or https://msdn.microsoft.com/en-us/library/ms228984(v=vs.110).aspx
If so how would I go about creating said listener that can receive
that input? I've created my own class that implements the trace
listener class and I can't seem to get any other input to be logged
other than my own?
You can start by subclassing the ConsoleLogListener or a TextWriterTraceListener. This library has many tools for dealing with the rough edges of System.Diagnostics Trace. https://essentialdiagnostics.codeplex.com/
(Because the built in library has rough edges, expect to see a few people tell you to use some other logging library, there are many, but only System.Diagnostics is built in and always available)
If there is another way to log my application line by line without
having to place my own logging, that would be very very helpful.
This requires "code weaving" or Aspect oriented programming, where you use a tool to recompile your application and add things like logging or trace everywhere or where ever a certain attribute is found. PostSharp is one such application. Memory profiles sort of give you that line by line trace as a byproduct of showing you where your application is spending most of its time.
Related
I have a WebAPI .NET Framework 4.8 application which needs to make a RESTful GET request to another, third-party web service using a specific cipher. I found a code sample using the CurlThin NuGet packages in a response to this question, and then perused the little documentation on CurlThin I could find, along with taking a peek at the open source library code on GitHub. All examples and documentation talk about the need for an initial call to
CurlResources.Init();
This call only needs to be made a single time at the initialization stage to copy the appropriate DLLs to the application output folder.
I placed this call in my web app's Application_Start method, but cannot get past a NullReferenceException:
I fully expect that I am overlooking something simple that's been staring back at me for hours. Any guidance would be much appreciated.
I am trying to implement Log4Net file appender in asp.net. I have been successful implementing it. However I am not sure about correct architecture to implement it.
I can add a logger in each page and log information. However, I was thinking to centralize the logger class. May be implement a singleton pattern. But i was wondering what will happen if a request for same page comes from two different browsers. I can implement Thread Static and then every page instead of initializing their own logger would use this centralize logger class to log.
I suppose the log4net file appender or rolling file appender using a queue mechanism to write to the log file. Because only one handle of the file can be acquired to write to a file.
Can anyone help me in this regard. Am i going the right way or i will have issues down the road when there will be tens and hundreds of requests coming from different browsers.
I recommend not to use a singleton, but instead to use a logger for each controller and class that you want to log from. Loggers are cheap to create and cached by log4net - and even more so if you declare them as static within the class - and by having one per class you can change logging per class or namespace by changing the log4net configuration at runtime - say to enable some debug logging to aid diagnosing a problem in production, or to turn down some logging which is unexpectedly noisy. You can do this without recycling your app if you have your log config in a separate file.
Also if you're going to use file logging, make sure you use MinimalLock
I was profiling our ASP .NET application to try and reduce the CPU usage and fond some strange behaviour regarding NHibernate and log4net.
Over 50% of the time on our app is spent in the log4net GetLogger and CreateRepository methods, which are called from ExecuteReader in NHibernate. The screenshot below is a jetBrains dottrace hotspot analysis where the arrows point from a calling method to the called method.
The below screenshot is just a straight up list of slowest functions.As you can see the NHybridDataReader constructor calls GetLogger and it takes ages.
Clearly something fishy is going on, and I want to disable log4net completely in NHibernate as we use other logging functionality.
Our web.config has no entries in it regarding log4net, so how do I disable it? There are no log files being produced, and from the look of the method names, it hasn't actually got round to logging anything, but is merely trying to find the logger it should write stuff to.
Most confusing, can anyone help?
For an answer to your specific question (turning off use of log4net by NHibernate), look into the code the Logging.cs file for NHibernate. When I looked at it (granted, I looked at 3.0 alpha code, but I doubt it's much different than 2.x), in the static LoggerProvider constructor, it delegates to GetNHibernateLoggerClass to determine the class to utilize. If it doesn't get one, it uses a no-op based class. So if you look in the GetNHibernateLoggerClass method, you see that it first looks for an appsettings key called "nhibernate-logger", which you should be able to set to "NHibernate.NoLoggingLoggerFactory, NHibernate". You may also notice that lacking a defined key, it will automatically use log4net if it finds the log4net DLL in the search path (likely just the directory containing NHibernate DLL. So you may also want to try removing the log4net DLL itself and see what happens. Though the first solution is more explicit and the second more is more inferred, so I would use the first.
As a side note, this is a great example of why open source works so well. Being able to just look thru the source code to answer a question like this. In closed source, you'd either have to cheat and .NET reflector the code (which could be obfuscated), or pray that the owners heavily documented obscure points like this one.
BTW, this same source code file provides what would need if you want to take NHibernate's log messages and redirect them to your own logging solution, as you mentioned you had (implement the ILogger and ILoggerFactory interfaces and use the config setting).
As I see it, the screenshot you posted says that the time is actually spent on NHibernate running some query. log4net has nothing to do here. The real problem is that you seem to be executing some query 3529 times.
Set the logging level approproately for the NHibernate logger in your config file:
<logger name="NHibernate">
<level value="ERROR" />
</logger>
I believe it defaults to DEBUG and it does a lot of logging. I would not disable it entirely since you want to be informed of ERROR or FATAL events.
We are getting intermittent problems on a production server that we cannot recreate.
There are two very strange things about the issue. Firstly it's a method not found error on the constructor (ctor) for an exception handling helper class and secondly we have custom errors switched on for remote users and this property is being ignored.
The detail of the error is:
Server Error in '/MyWebsite' Application.
Method not found: 'Void MyExceptionHelperClass..ctor (System.Exception)'.
...
Exception Details: System.MissingMethodException: Method not found: 'Void MyExceptionHelperClass..ctor (System.Exception)'.
...
The stack trace is pretty unhelpful.
My thoughts are that there may be an out-of-memory error or something like that that is killing the page. When the exception handling code kicks in it tries to create an exception object which fails for the same reason giving this error.
However this is wild speculation. We are waiting for the event logs to see whether anything is amiss with the server but in the meantime does anyone have any thoughts or suggestions?
UPDATE:
It has proven difficult to get information out of the team responsible for the production servers but I have managed to find out that as far as load balancing is concerned, this site is currently only running on one server (this can be made to switch over onto another if necessary). Given that this is an intermittent problem and there is only one server involved, then I find it difficult to believe that this could be an assembly issue. Surely if it was then the problem would occur every time?
If you see this error happening on a site that has custom errors turned on, then the error is happening in the custom error handling routine itself.
From the look of the .NET error message it appears that your routine is expecting a constructor that accepts an exception by reference - your comment above shows a constructor that accepts by value.
Check carefully that there isn't a stale version of an assembly in your system somewhere. These can lurk in the Temporary ASP.NET Files folder; you'll need to do an "iisreset /stop" before you can clear them out.
In that regard it's always a good idea to make sure that AssemblyInfo.cs is set up to automatically stamp version numbers in some way. We have our version numbers tied to our source code repository system and CI build box so we can tell exactly what was in what assembly really easily.
I would use elmah: http://code.google.com/p/elmah/ to hopefully give you a bit more insight into the issue. It is free and can be used on an existing site without any recompilation. Try it - and post back if the issue is still happening.
As others have also mentioned, I would suspect that your site is somehow using an out of date version of an assembly. Something you could try doing is a full Precompile of your site before deploying to your production server. This ensures that ASP .Net doesn't dynamically compile the site on the fly, and therefore should mean that it's using completely up to date code throughout.
Do you have a no parameter public constructor defined for MyExceptionHelperClass in your code? Or is the class meant to only have static methods, in which case it should be a static class.
public class MyExceptionHelperClass()
{
public MyExceptionHelperClass() { }
}
Unfortunately, this may be one of those cases where the error message is of little to no value. In my experience, this general class of exception may be the result of either a configuration issue or bad logic aroung threading/app domains. For example, I have seen similar issues upon attempting to load the same assembly into an app domain more than once.
You mention that this is difficult to reproduce. If it's only happening on one server in the production farm it's more likely to be a config issue (with that machine). If it's happening on more than one server than it could be either config or threading.
It might be worth spending some time looking at the larger code base around the areas mentioned above. The root cause may not be in this class. Good luck!
I think it's a Framework issue with keeping compiled versions consistency. It's common to see same sort of errors while updating site sources repeatedly. Just try something like
net stop iisadmin /y && del /q /f /s "%systemroot%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\*.*" && iisreset
I encountered this exception today on a webforms page. I found a solution, but I'm not sure why it worked.
Nest the code behind in a 'Namespace [YourNamespace]' tag.
Add the namespace to the html Page tag's Inherits property in the aspx page 'Inherits="PathStart.YourNameSpace.ClassName"'.
Rebuild
Navigate to the page again and you should not encounter the exception.
After following the steps above I reverted the changes and did not re-encounter the exception.
I'm currently using Microsoft Code Contracts in an ASP.NET MVC application without any issues but I can not seem to get it quite running in a basic ASP.NET Web site. I'm not entirely sure it was made to work with this type of project (although it shouldn't matter) so I wanted to bring it up to everyone.
I can compile the contracts just fine but the code skips over them since I'm assuming it hasn't been enabled through the Properties Page like you would do in other project types (ie ASP.NET MVC). I've gone to the property page of the project (which displays a dialog instead of the typical properties page) in my ASP.NET web site but it does not yield the same menu options and as such, doesn't have a section devoted to Code Contracts.
Also, I have Microsoft Code Contracts properly enabled within a class library project that I use to separate my business logic from the web site. The contracts compile fine but when a contract is violated, it throws a rather uninformative "Exception of type 'System.ExecutionEngineException' was thrown" error with no inner exception. My contract specifies a message to display upon violation but it is nowhere within the exception. It simply halts the execution of the process (which I believe is the default functionality for Microsoft Code Contracts).
I can't find anywhere that explicitly states that a particular project type can or can't (or shouldn't) be used with Contracts so I just wanted to see if anyone has had this issue.
Thanks for any help!
I had the same problem and this is how I solved it:
In the Referenced Class Libraries, right click -> properties -> code contracts.
Make sure "perform contract checking" is checked. I had mine set to "Full"
Contract Reference Assembly: make sure it is set to "Build"
Save your changes.
In the Referenced Class Libraries that have no contracts in their code, set the Contract Reference Assembly to "Do Not Build".
Then in the MVC project, have the Code Contracts "perform contract checking" checked. I had mine set to "Full".
Hope that helps somebody.
This sounds less like a Contracts and more like a build/config issue. Have you tried to deploy a prebuilt website? Are you sure that your website code sees the contracts code? Is the ASP.NET runtime using the CLR 4.0, or does it see the earlier Microsoft.Contracts.dll? Etc.