Open Source .NET Development [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Open Source .NET Development [Electronic resources] - نسخه متنی

Brian Nantz

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


Configuration


Obviously, one of the keys to Log4Net's success is that it is so configurable. Log4Net's configurations tie together the Loggers, Appenders, Layouts, Levels, and Filters. This configurability can at first glace look very complex, but once you understand the basic classes in Log4Net, the configuration is intuitive and incredibly powerful.

Programmatic Configuration


Everything in Log4Net can be configured and built up programmatically. The minimal steps to get Log4Net working in a program are:


  • Create a Hierarchy

  • Create a Logger with an associated Level in that Hierarchy

  • Attach an Appender

  • Set an Optional Filter on the Appender

  • Set an Optional Layout for the Appender

  • Listing 8.8 shows this in C# code. If you are not specifying a Filter or a Layout, this makes the already simple code almost trivial.

    Listing 8.8. Configuring Log4Net Programmatically

    using log4net;
    using log4net.Appender;
    using log4net.spi;
    using log4net.Repository.Hierarchy;
    // Get the Hierarchy object that organizes the Loggers
    Hierarchy h = LogManager.GetLoggerRepository() as Hierarchy;
    // Get the specific Logger that you want to configure
    // either by name or select the root Logger
    Logger l = h.GetLogger("foo"); // or Logger l = h.Root;
    // Update the properties on the Logger

    l.Level = Level.DEBUG;
    l.AddAppender(new appender);
    // Get a named Appender from the Logger

    ConsoleAppender c = l.GetAppender("ConsoleAppender") as ConsoleAppender;
    // Change the console Appender to use the error stream
    c.Target = "Console.Error";
    // Tell the Appender to update
    c.ActivateOptions();

    Although this is not really complicated, it is certainly the wrong way to configure Log4Net in most scenarios. The problem in the code in Listing 8.8 is that everything is hard-coded. The Level will always be DEBUG and would need to be recompiled to be anything other than DEBUG. The same applies for the Appender, which would always be ConsoleAppender, which is not very useful in persisting information!

    Runtime Configuration


    A better way of configuring a Logger is to use a runtime configuration. This is supported in Log4Net by using a .NET configuration file. The CLI specification allows .NET applications to have an XML application configuration file. By default, this file is named the same as the application, with a .config added to the end of the filename. These configuration files are used in the runtime engine itself (a machine.config) and in ASP.NET (web.config). These configuration files are Hierarchical so that a value defined in machine.config will automatically be available to all other configuration files because machine.config is the root configuration file.

    There are several built-in config file sections that are useable in your code. The most familiar one is the appSettings section where you can store specific information for your applications. Config files are also extendable by using the IConfigurationSectionHandler interface, and you can define your own config file sections. This is what Log4Net has done, as you can see in Listing 8.9.

    Listing 8.9. Log4Net's Custom Configuration File Section

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <!-- Register the section handler for the log4net section -->
    <configSections>
    <section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
    </configSections>
    <!-- This section contains the log4net configuration settings -->
    <log4net>
    <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >

    <layout type="log4net.Layout.PatternLayout">

    <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />

    </layout>
    </appender>
    <!-- Setup the root category, add the appenders and set the default priority -->
    <root>

    <level value="INFO" />
    <appender-ref ref="EventLogAppender" />
    </root>
    </log4net>
    </configuration>

    Now the advantages of runtime configuration are a little clearer. The Appender is configured in Appendix D.

    When using a .NET config file, the configuration information is read in when the application is started. Any change to the configuration file would not be reflected until the program is restarted. Log4Net has gone a step further and allows configuration changes to be applied on-the-fly by adding this custom attribute to your AssemblyInfo.cs file:

    [assembly:log4net.Config.DOMConfigurator(ConfigFile="filename", ConfigFileExtension="ext",
    Watch="true")]

    This shows the true power and flexibility of Log4Net. A server application does not even have to be restarted to change the logging Level to log more detailed information.

    Configurations in a Smart Client


    In .NET, there is a new way to distribute Windows Forms applications from a centralized location, called Smart Clients, and have your application automatically update all clients when the assemblies at the centralized location are updated. In this scenario, you have to be aware that you are running with limited privileges and will not be able to use many of the Log4Net Appenders. In extending Log4Net, I will introduce a new Appender to log to the IsolatedFileStorage that can be used in this semi-trusted environment. Also be careful that when automatically downloading a client, .NET only downloads the config file once unless the .NET GAC cache is cleared. This means that the configuration information is not easily updatable. Even if you manually distribute the client code to all the client machines, the problem still remains of updating all the clients to log at a different Level. Normally you may not desire to do this and flood the system with messages, but if such a need arises, you could possibly fetch the configuration information from a database instead of a config file with a little custom work in the log4net.Configuration class.


      / 275