Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Bjarne Fyrstenborg 1086 posts 2864 karma points MVP 2x c-trib
    Feb 14, 2018 @ 12:44
    Bjarne Fyrstenborg
    0

    Write log to custom separate file

    When using the static LogHelper class in Umbraco it writes by default to UmbracoTraceLog file. https://our.umbraco.org/apidocs/csharp/api/Umbraco.Core.Logging.LogHelper.html

    Sometimes to might want to write to a separate file, e.g. when importing stuff. Is there a way to use LogHelper to write to a different file in some parts of the code or have a similar class which wrap to custom logger?

    At the moment I have the following in /Config/log4net.config

    <appender name="ProductImportAppender" type="log4net.Appender.RollingFileAppender">
        <file type="log4net.Util.PatternString" value="App_Data\Logs\ProductImportLog.%property{log4net:HostName}.txt" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <maximumFileSize value="5MB" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
        </layout>
        <encoding value="utf-8" />
      </appender>
    
      <logger name="ProductImportLogger" additivity="false">
        <level value="ERROR"/>
        <appender-ref ref="ProductImportAppender"/>
      </logger>
    

    Then in my import class I have.

    private static readonly ILog _logger = LogManager.GetLogger("ProductImportLogger");
    
    ...
    
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(_baseUrl);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
        try
        {
            HttpResponseMessage response = await client.GetAsync("/GetProducts");
            if (response.IsSuccessStatusCode)
            {
                _logger.Info(string.Format("Successfully requesting product service. Returned Status Code: {0} {1}", (int)response.StatusCode, response.StatusCode));
    
                string jsondata = await response.Content.ReadAsStringAsync();
                return jsondata;
            }
            else
            {
                _logger.Error(string.Format("Error requesting product service. Returned Status Code: {0} {1}", (int)response.StatusCode, response.StatusCode));
            }
        }
        catch (HttpRequestException ex)
        {
            _logger.Error("Error requesting product service", ex);
        }
        //catch (TimeoutException ex)
        //{
        //    _logger.Error("Error request was timing out", ex);
        //}
        catch (TaskCanceledException ex)
        {
            _logger.Error("Error - request was cancelled", ex);
        }
    
        return "";
    }
    

    Can I somehow wrap the logger in a class similar to LogHelper so I don't need to call GetLogger() in the different files where I want to log details?

    /Bjarne

  • Anders Bjerner 386 posts 2174 karma points MVP 2x admin c-trib
    Feb 23, 2018 @ 19:44
    Anders Bjerner
    0

    You can handle this by only modifying the log4net configuration a bit, and then you can keep on using the static LogHelper class like you're used to.

    I've used this in the past, but I think something has changed a bit since then - so this may be a bit outdated. But from what I can see, it still works.

    When you set up a new Umbraco installation, your log4net.config file will have an appender element, that looks like this:

      <appender name="rollingFile" type="log4net.Appender.RollingFileAppender">
          <file type="log4net.Util.PatternString" value="App_Data\Logs\UmbracoTraceLog.%property{log4net:HostName}.txt" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <maximumFileSize value="5MB" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
        </layout>
        <encoding value="utf-8" />
      </appender>
    

    It's basically the configuration for the default logger. We can take a copy of that element to creator our own, but instead for calling it rollingFile, we could call it OurHestAppender like below:

      <appender name="OurHestAppender" type="Umbraco.Core.Logging.AsynchronousRollingFileAppender, Umbraco.Core">
        <file type="log4net.Util.PatternString" value="App_Data\Logs\OurHestLog.%property{log4net:HostName}.txt" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <maximumFileSize value="5MB" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
        </layout>
        <encoding value="utf-8" />
      </appender>
    

    Also notice that I've changed the type attribute to Umbraco.Core.Logging.AsynchronousRollingFileAppender, Umbraco.Core. I think this is necessary to get the namespace-based logic to work.

    You can then add a new logger element, that then uses the appender above:

      <logger name="Our.Hest">
        <level value="ALL" />
        <appender-ref ref="OurHestAppender" />
      </logger>
    

    With this in place, whenever you log something for a class within the Our.hest namespace, that information is logged to your custom log file ;)

    It appears that the same information is also appended to the main Umbraco log file. I don't think it used to be like that in the past, but I cant remember for sure.

    Anyways, with the changed list above, my entire log4net.config file then looks like:

    <?xml version="1.0"?>
    <log4net>
    
      <root>
        <priority value="Info"/>
        <appender-ref ref="AsynchronousLog4NetAppender" />
      </root>
    
      <appender name="rollingFile" type="log4net.Appender.RollingFileAppender">
          <file type="log4net.Util.PatternString" value="App_Data\Logs\UmbracoTraceLog.%property{log4net:HostName}.txt" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <maximumFileSize value="5MB" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
        </layout>
        <encoding value="utf-8" />
      </appender>
    
      <appender name="OurHestAppender" type="Umbraco.Core.Logging.AsynchronousRollingFileAppender, Umbraco.Core">
        <file type="log4net.Util.PatternString" value="App_Data\Logs\OurHestLog.%property{log4net:HostName}.txt" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <appendToFile value="true" />
        <rollingStyle value="Date" />
        <maximumFileSize value="5MB" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
        </layout>
        <encoding value="utf-8" />
      </appender>
    
      <appender name="AsynchronousLog4NetAppender" type="Log4Net.Async.ParallelForwardingAppender,Log4Net.Async">
        <appender-ref ref="rollingFile" />
      </appender>
    
      <!--Here you can change the way logging works for certain namespaces  -->
    
      <logger name="NHibernate">
        <level value="WARN" />
      </logger>
    
      <logger name="Our.Hest">
        <level value="ALL" />
        <appender-ref ref="OurHestAppender" />
      </logger>
    
    </log4net>
    
  • Bjarne Fyrstenborg 1086 posts 2864 karma points MVP 2x c-trib
    Feb 27, 2018 @ 10:38
    Bjarne Fyrstenborg
    0

    Hi Anders

    Thanks for the suggestions. Does that mean when using LogHelper only code inside the namespace Our.Hest is appended to the custom log file - would code inside the namespace Our.Hest.Unicorn also be appended to this log file or does it have the be the specific namespace?

    In my case I have MyProject.Library.Import where I want to use the custom log file. Futhermore I would also prefer it doesn't write to the Umbraco log file too as it doesn't in the code I posted.

Please Sign in or register to post replies

Write your reply to:

Draft