I am trying to incorporate log4net into my web application. I have already done so with the newer portion based on .net mvc, but am having trouble incorporating it into the web forms based portion of my app. I have looked around for an example and have not come across one.
In order to narrow my question down, let's assume I know how to configure my web.config file. My questions are:
(1) I have considered placing the actual call to log4net in a "Global.asax" file as well as placing it in my base page (on which all other pages are built). Should I be placing the actual code in either of these places, and if not where should I put the code?
(2) My understanding of the code is that I need to instantiate a log, and then have that log log stuff when I want to it (the specifics of log being taken care of by web.config), but I don't know what that code should actually look like. So, what code should I actually be placing in my file? (example would be appreciated)
Thanks
just place the code where you need it.
to initiate i just use this line in every page i need it...
static Logger log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
so the logger gets the name of the current class including full namespace.
i also use the logger in global.asax for example error logging
protected void Application_Error(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
sb.Append("Unhandled error occured in application. Sender: ");
sb.AppendLine(Request.RawUrl);
sb.Append("Query: ");
sb.AppendLine(Request.QueryString.ToString());
Exception ex = Server.GetLastError().GetBaseException();
log.Error(sb.ToString(), ex);
Server.ClearError();
Response.Redirect("~/Error.aspx");
}
but i seperate the log config from the web.config. it's easier for me and you don't have to handle so big files. i also think that the application is not restartet, when you change the log config file. if you update the web.config the application is always restartet as far as i know.
to accomplish this you just need to add following to the web.config
in add
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
than add this line somewhere in the web.config
<log4net configSource="log.config"/>
and then the file "log.config" has all the listeners configured. but don't forget to copy the file to your production/test environment. otherwise you may get strange error messages.
hth
Placing it in the base page sounds like a good idea, then when instantiating using GetLogger you can pass in the page you're logging for (being as specific as possible about where your log calls are coming from really helps debugging). You'll also need a call to .Configure after instantiating which is what always catches me out (need to import Log4Net.Configure for this)
Place your listener config in web.config and define min/max levels via LevelRangeFilter (DEBUG is lowest, FATAL is highest).
Usage is pretty simple - you just log with the required level, EG: log.Info, log.InfoFormat, log.Error, log.ErrorFormat (the formats just work like String.Format) - anything below the minimum configured logging level will be ignored so you can put as much logging in as you like.
Have you also checked out Elmah? This allows you to track unhandled exceptions. http://code.google.com/p/elmah/
Let me share with my experience of using logger. Usually I use it with IOC container, i.e. Windsor.
So initialization of logger I make in Global.asax file, as it is runned once per app, and berore all requests. This is proper place to initialize logger.
As for the place where you should call the log, there isn't any recommendation. You should call where you need.
If you are logging some events based on page lifecycle, of course you should use logger in page code behind file. But if you want to trace your components, better extract logics in separate library and use logger within it.
Related
I would like to configure the NLog.config file(.net framework web app) to log some specific properties of exception.
I want only type,stackTrace and message.
I read this layout render
${exception:format=String:innerFormat=String:maxInnerExceptionLevel=Integer:innerExceptionSeparator=String
:separator=String:exceptionDataSeparator=string}
but I cannot understand how to log only these properties that I want.
Strange that other reply was removed, since it was completely correct. Let me write it one more time. The examples below can also be found on the Wiki-page that you have found yourself.
Renders Exception-Message:
${exception:Format=Message}
Renders Exception-Type:
${exception:Format=Type}
Renders Exception-StackTrace:
${exception:Format=StackTrace}
They can also be combined:
${exception:Format=Message,Type}
If you have issues with unexpected output, then you are probably victim of not properly deploying the updated NLog.config.
I have a class library that has a function with this code:
this.apikey = ConfigurationManager.AppSettings["ApiKey"];
When I call this function in a console application, it says AppSettings has no keys. also it states the connection string is aspnet... whereas mine is sqlserver. So it is certainly not reading my library app config even though Im calling that in a library function.
Is this normal or am I doing something wrong?
I was hoping to avoid having to make and parse an xml and reinvent the wheel.
Thanks
Is this normal or am I doing something wrong?
It is normal and you are doing something wrong.
A library does not, usually, have its own configuration - it is subject to the configuration of the running application.
If you add your appSettings and connectionStrings to the application configuration all will work.
In other words, when an application loads and the libraries it uses are loaded, the application configuration is read - no other configuration file is read. When calling the static methods of ConfigurationManager, the loaded configuration is what's in effect.
There are ways to load specific configuration files, but that's not the default behaviour.
You are certainly wrong at some place. May be you have written your keys in different section than the appSettings. Just check it, and if it is correct then , you will need to reinvent the wheel as below:
XDocument.Load(HttpContext.Current.Server.MapPath("~/web.config"));
Be sure to add System.Web namespace to your project before using HttpContext
I need to create a Error logging project from scratch in C#.
I would like to save to a file with several levels, this logging project I am taking as an assignment from which I can learn many things and want to build it as small loggin utility for now.
I saw few loggin project which has singleton pattern and a config file having some entries and also in the consuming application config - some references of logger proj interface are there
can some one please give me an idea as how can I create a new logger
proj from scratch and what is the purpose of having entries in
config ?
pseudo code for logger project or any link
Thanks in advance.
Instead of implementing your own logging mechanism you may want to check whether existing components are an option. For example log4net is a frequently used framework that people use for .NET based projects.
Also, the Logging Application Block from Microsoft:
http://msdn.microsoft.com/en-us/library/ff632023.aspx
http://msdn.microsoft.com/en-us/library/ff664569(v=PandP.50).aspx
There are several key elements you need to consider before making one from scratch. Just to name what comes to my head :
How do you want to log? Do you want to save logs to a file, in a database, to send mails, just to have the logs shown in a console?
If you persist the logs, do you want to log everything, forever, or you want a "rolling" X lines to be kept, the rest discarded?
Do you want to have several level of logs? For example, you could log some things Info, Warning, Error, Critical Error, etc.
Do you want your logging library to support custom formatting for the logs?
As for the question about the config, it's really something you want to do. If you're talking about the app.config files, it allows you to can change the configuration of your application without rebuilding it. It can also provide some default parameters the user can override. By user, I mean another developer using your library.
I am doing something unusual.
I have an application, it runs as a windows service.
what it does is that, it monitor one folder, when ever there is some new file put into that folder, the application will do something to the file.
Whenever there is an error when processing one file. I need to create a text file, and put the error/exception information into that text file. (later i can do something with this file)
so there is something like this
FileWatch, when there is a new file, do following :
try
{
processing file
}
catch(Exception ex)
{
MyLogger write exception message into one new text file
}
So far how i did it is that. I create a class for example MyLogger, whenever i new one MyLogger, it creates a text file (the name matters, need to be a specific format), and there is one method in side MyLogger "WriteError(string message)", it writes text into that file.
Since i used log4net in my application. Do you think i should modify my logger, to extend some class from log4net, so that i can get some benefit? (not sure what kind of benefit i will get, but log4net is a good logging framework, the way it handle text file might have thing that i do not aware)
Thanks
log4net or any other generic logger is helpful if
1) you want to have a consistent logging facility in many places across your application; and/or
2) you want the ability to customize logging format, level and so on.
From your description it sounds like there is a single point in your app where you need to log the exception in a specific way. If this is correct, you will probably gain no benefit from creating a custom logger - just write a method that logs exception to a file in the way you need.
If I misunderstood you, and there is a need for generic logger (that is, either 1) or 2) above is true), extending log4net by inheriting a logger or creating a wrapper is fine.
I've created log4net wrappers before. I find it handy to start this way as you don't always know what the logging requirements are at the start of a project. My rule has been that the log4net library can only be referenced from my own "logging" namespace. This way, the application code only calls the wrapper, and the wrapper is the only point of contact to the log4net functionality.
In the long run, it's probably worth investing in building your own logger. If you encapsulate log4net properly, you should be able to make this upgrade rather easily, without having to change your code.
Why not use Trace Listeners from the .NET framework? They provide many of the benefits of a logging network, without the need to incorporate an external framework.
Benefits include centralized log management and the ability to direct the output logs to one or more sources such as a console window, text file, or the Windows Event Log.
You should spend some time creating your own logger that does exactly what you want. This would be the best way. Is also fairly easy and you have full control on the customization so you can make the output look and feel as in log4net. You could Google for logging sample and start modifying that one.
I am not sure if I would use a log framework for this purpose. I have the impression that writing this text file in the exception case is part of your business process. Logging serves a different purpose that can be turned off without affecting business processes...
Currently I have a static class that I use as my logging module. I’ve added the class to my visual studio solution. Within the class I’ve specified the name and location of the log file to use.
Which lets me do stuff like this – which I like and want.
Logger.Information(“Page_Load”,”controls loaded correctly”);
I’d like to refactor the code and move the logging functionality into a separately compiled assembly, if I did this I would then need to pass in the log file name and location to save the files too.
However I don’t want to have to supply this information every time I call the ‘Logging’ method, this would be bad...
Logger.Informtaion(“Page_Load”,”controls loaded correctly”,”logfile.txt”,”c:\temp”);
Is there any way I can supply this information without having to specify it within each page or via the method call.
For sure. The simplest thing would be to add a single key to the web.config file, which your class looks at by using the ConfigurationManager.
<configuration>
<appSettings>
<add key="logfile" value="c:\log.txt" />
</appSettings>
<system.web>
...
</system.web>
</configuration>
string logfile = ConfigurationManager.AppSettings["logfile"]
If your logging class is more complex than just one or two configuration options, consider building a ConfigurationSection class to go along with it, which would allow you to create your own section in the web.config.
The configuration approach is good for this type of thing, because then you avoid hard-coding the logfile path into your application code (such as passing it into a static initialization method), which would require a recompile if you needed to change the logging path. However, you should only need to look up the logfile path once, upon creation of your logging class.
I feel obliged to ask if you've investigated using TraceListener and the System.Diagnostics namespace with its built-in logging (as opposed to rolling your own). It's quite extensible.
Have you considered making your logger non-static? Perhaps a singleton? This is the classic example for an appropriate use of the Singleton pattern.
Sure,
Create an initialize method on your static class and pass the file into the initialize mentod. Then call the method at application start.