Log messages going to previously created log file

2019-03-02 01:20发布

I am using enterprise library 5.0 logging in my asp.net site,
My web.config file is as follows:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true"/>
    </configSections>
    <loggingConfiguration name="FlatFileLogging" tracingEnabled="true"
        defaultCategory="General">
        <listeners>
            <add name="Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                fileName="C:\Logs\2013-06-28 14-21-53.log" header="" footer=""
                formatter="Text Formatter" traceOutputOptions="DateTime" />
        </listeners>
        <formatters>
            <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                template="{timestamp}, {severity}, {message}" name="Text Formatter" />
        </formatters>
        <categorySources>
            <add switchValue="All" name="General">
                <listeners>
                    <add name="Flat File Trace Listener" />
                </listeners>
            </add>
        </categorySources>
        <specialSources>
            <allEvents switchValue="All" name="All Events" />
            <notProcessed switchValue="All" name="Unprocessed Category" />
            <errors switchValue="All" name="Logging Errors &amp; Warnings">
                <listeners>
                    <add name="Flat File Trace Listener" />
                </listeners>
            </errors>
        </specialSources>
    </loggingConfiguration>
    <appSettings/>
    <connectionStrings/>
    <system.web>
        <compilation debug="true" targetFramework="4.0">
        </compilation>
        <authentication mode="Windows"/>
        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/></system.web>
</configuration>

I am changing log file path using following function:

public static void SetLogFilePath(string filePath)
{
    //string logdirectory = AppDomain.CurrentDomain.BaseDirectory + "Logs\\";
    //if (!Directory.Exists(logdirectory))
    //    Directory.CreateDirectory(logdirectory);
    //logFilePath = logdirectory + (string.IsNullOrWhiteSpace(txtBatchName.Text) ? "" : (txtBatchName.Text + " ")) + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".log";

    if (!File.Exists(filePath))
        File.Create(filePath);

    ConfigurationFileMap objConfigPath = new ConfigurationFileMap();

    // App config file path.
    string appPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
    objConfigPath.MachineConfigFilename = appPath;

    Configuration entLibConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");

    LoggingSettings loggingSettings = (LoggingSettings)entLibConfig.GetSection(LoggingSettings.SectionName);

    TraceListenerData traceListenerData = loggingSettings.TraceListeners.Get("Flat File Trace Listener");
    FlatFileTraceListenerData objFlatFileTraceListenerData = traceListenerData as FlatFileTraceListenerData;

    objFlatFileTraceListenerData.FileName = filePath;

    entLibConfig.Save();
}

Whenever I change log file path and send log messages to file, the logs do not go to newly created file. Log messages go to previously set file path. seems that new setting is not reflecting immediately.

string path = "C:\\Logs\\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".log";
SetLogFilePath(path);
Logger.Write(message, "General", 1, 0, System.Diagnostics.TraceEventType.Information); 

How to refresh the new settings to code immediately?

1条回答
【Aperson】
2楼-- · 2019-03-02 02:20

How do you define "immediately"? If you mean in the middle of the executing request then I don't think you can do that via configuration since the configuration will not be refreshed for that request.

Here's an implementation that seems to work for me based on the blog post Enterprise Library Programmatic Configuration. I don't write the config change back to disk but change it in memory instead.

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        EnterpriseLibraryContainer.Current.GetInstance<LogWriter>()
            .Write("test", "General");

        string path = "C:\\Logs\\anotherlogfile.log";
        SetLogFilePath(path);

        EnterpriseLibraryContainer.Current.GetInstance<LogWriter>()
            .Write("Another test", "General");
    }

    public void SetLogFilePath(string filePath)
    {
        ConfigurationFileMap objConfigPath = new ConfigurationFileMap();

        // App config file path.
        string appPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
        objConfigPath.MachineConfigFilename = appPath;

        Configuration entLibConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");

        LoggingSettings loggingSettings = (LoggingSettings)entLibConfig.GetSection(LoggingSettings.SectionName);

        TraceListenerData traceListenerData = loggingSettings.TraceListeners.Get("Flat File Trace Listener");
        FlatFileTraceListenerData objFlatFileTraceListenerData = traceListenerData as FlatFileTraceListenerData;

        objFlatFileTraceListenerData.FileName = filePath;

        IUnityContainer container = new UnityContainer();
        container.AddNewExtension<EnterpriseLibraryCoreExtension>();

        // Configurator will read Enterprise Library configuration 
        // and set up the container
        UnityContainerConfigurator configurator = new UnityContainerConfigurator(container);

        var loggingXmlConfigSource = new SerializableConfigurationSource();
        loggingXmlConfigSource.Add(LoggingSettings.SectionName, loggingSettings);

        // Configure the container with our own custom logging
        EnterpriseLibraryContainer.ConfigureContainer(configurator, loggingXmlConfigSource);

        // Wrap in ServiceLocator
        IServiceLocator locator = new UnityServiceLocator(container);

        // Release lock(s) on existing file(s)
        EnterpriseLibraryContainer.Current.GetInstance<LogWriter>().Dispose();

        // And set Enterprise Library to use it
        EnterpriseLibraryContainer.Current = locator;
    }
}

public class SerializableConfigurationSource : IConfigurationSource
{
    Dictionary<string, ConfigurationSection> sections = new Dictionary<string, ConfigurationSection>();

    public SerializableConfigurationSource()
    {
    }

    public ConfigurationSection GetSection(string sectionName)
    {
        ConfigurationSection configSection;

        if (sections.TryGetValue(sectionName, out configSection))
        {
            SerializableConfigurationSection section = configSection as SerializableConfigurationSection;

            if (section != null)
            {
                using (StringWriter xml = new StringWriter())
                using (XmlWriter xmlwriter = System.Xml.XmlWriter.Create(xml))
                {
                    section.WriteXml(xmlwriter);
                    xmlwriter.Flush();

                    MethodInfo methodInfo = section.GetType().GetMethod("DeserializeSection", BindingFlags.NonPublic | BindingFlags.Instance);
                    methodInfo.Invoke(section, new object[] { XDocument.Parse(xml.ToString()).CreateReader() });

                    return configSection;
                }
            }
        }

        return null;
    }

    public void Add(string sectionName, ConfigurationSection configurationSection)
    {
        sections[sectionName] = configurationSection;
    }

    public void AddSectionChangeHandler(string sectionName, ConfigurationChangedEventHandler handler)
    {
        throw new NotImplementedException();
    }

    public void Remove(string sectionName)
    {
        sections.Remove(sectionName);
    }

    public void RemoveSectionChangeHandler(string sectionName, ConfigurationChangedEventHandler handler)
    {
        throw new NotImplementedException();
    }

    public event EventHandler<ConfigurationSourceChangedEventArgs> SourceChanged;

    public void Dispose()
    {
    }
}
查看更多
登录 后发表回答