I am using elmah to handle exceptions. Now my needs have been increased and I want to log some warnings after few statements like NLog.
Here i want to add data in SQL database. I also want to add one column in elmh table, which tells me which row is belongs to error and which belongs to warning, because I need to render them separately.
Eg. ElmahError.axd and ElmahWarn.axd.
I may need to override elmah class to achieve this, but is there any other library which gives both features, error handling and logging?
What is the best way to get this done?
If you want to log warnings in ELMAH, you will need to log it as an exception. You can create a custom exception named WarningException or something. With that said, ELMAH is created for errors and doesn't really fit well with other severities.
Adding custom data to ELMAH isn't possible either. Unless you fork the ELMAH source code and create a custom build of course. You will need to extend the Error class among others.
I'm the founder of the cloud-based error management system elmah.io. We support all severities known from other logging frameworks. With my experiences developing elmah.io, I will recommend you to use ELMAH what it's good for (logging errors) and combining it with a logging framework of choice. We use Serilog to get structured logging in Elasticsearch, but NLog, log4net etc. should do the job as well.
Related
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.
In the designer I get this error: "Error Creating Control: Object Reference Not Set to an instance of an object". The page itself runs fine. One of the objects, possibly an objectdatasource has to be failing at design time. But how to find which one?
The project was originally designed with a XSD for the data pointing to SQL Server queries. All based on typical Microsoft demonstrations which don't really take the product lifecycle into account.
I have had to refactor a number of things in the database, and the XSD designer doesn't automatically show you what you need to fix, you just have to run and get a runtime error. Obviously this means that some of the many individual adaptor methods are probably still incorrect, and I'm going through and updating them to match the new database model, and then tracking through the effects through all the bound controls and everything. And eventually, I may get away from a lot of this wizard-generated code and have something a bit more able to be statically checked by the compiler during the build.
But for now, how do I find out which object reference is the problem?
Problem appears to be due to a null Context in code in a base class which worked fine in VS 2008 which was being called in design-time
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.
Just got ELMAH running, and so far it seems great. I am wondering two things:
I am using ELMAH from multiple applications, all logging to the same table in MSSQL. Will I be able to drop the .axd file in any project to browse all the logs, or will I need a custom solution? (The latter seems more likely, so I can have filtering options, but I'm just trying to verify.)
Is elmah.axd somehow customizeable? I'd rather modify it than write my own, so that I could add the ApplicationName column to its listing.
We just released our ELMAH based exception reporting solution on codeplex: http://aspexceptionreporter.codeplex.com/
One of the features is that it logs errors of multiple web sites to a central location. The project includes a web site to view and search through the errors.
ELMAH, by default, is set up to figure out under which application it is running and will filter the displayed errors based on that application. So, as for your question 1, no, you won't be able to call the .axd from an app and see the errors for all apps. At least not without some extra work. See also this related question.
As for question 2, the default viewer is not designed to be "customized". By that, I mean there aren't any markup parameters you can give it to change the columns it displays. ELMAH itself is open source, though, so you can easily download the source and build a customized version. I would start by having a look at ErrorLogPage.cs, which is the class that "Renders an HTML page displaying a page of errors from the error log."
What method do you use to get a compile time error when the database schema changes occur in an ASP.NET project?
For example, if you have a GridView bound to a DataSource, I can only get runtime errors when a schema change occurs, not a compile time error. Intellisense works fine on the code behind using datasets, LINQ, etc, but I cant seem to get a compile time error on an ASP.NET page when I change the schema.
Any advice?
Create a unit test that verifies the correctness of you data access layer, and make sure it covers all your DB-related code. Not everything can be caught at compile time...
One way I can think of easily achieving this behavior would be to databind to a dynamic DAL. There are some tools that can help do this DAL generation, I'd recommend taking a look at SubSonic.
Once you have something like SubSonic in place you can bind to the resulting business objects. These business objects will automatically change in the case of a schema change in the database and this will break your binding code which will result in a compile time error.
Update
Assaf's recommendation to use Unit Tests is also a good idea. It doesn't solve your stated problem but it is definitely something that should be in place and is a great tool for flagging these type of problems.
We use a modest system (xml to c++) to create schemas from an independent description, this system also creates names for tables and columns that we use inside the code, when there is a change in the schema the names change, as the names we originally used are not there anymore and the compiler will flag an error.
You could probably configure a lot of the DAO generation tools to do something similar.
One solution would be to version your database and map an application build to a specific version (maybe in a properties file). In the entry point of your app, you can compare the expected version to the actual version and handle the error accordingly.
I'm not sure whats the equivalent in ASP.net of Migrations in Rails or dbdeploy in Java for versioning your database. But any DB versioning tool that makes schema changes incremental and versioned and tracks the version in a Version table will suit the purpose.
But if you want a compile time error while building your app, you might as well upgrade your schema to the latest version as part of your build process, avoiding the possibility of schema changes in the first place.