0

I have a Visual Studio 2015 extension, and would like to use log4net. However, I'm not getting any log messages, and not even internal debugging messages from log4net.

In the Package class I have:

  private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

and later in the Initialize method I have:

 if (!log4net.LogManager.GetRepository().Configured)
        {
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo("C:\\Program Files\\Sym\\bin\\Log4NetSettingsGlobal.xml"));
        }
        log.Debug("Package Initialize");

In the VSX project's app.config I have this:

 <configuration>
  <appSettings>   
    <add key="log4net.Internal.Debug" value="true"/>
  </appSettings>
  <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add name="textWriterTraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Program Files\Sym\Logging\Log4Net_Trace_VSX.txt"/>
      </listeners>
    </trace>
  </system.diagnostics>
...
 </configuration>

Nothing gets written to the text file above. Nothing gets written to the output window when I debug the extension in VS, that is, a second instance of VS is opened so that I can test the extension.

I added a DebugAppender too from this SO question. Still nothing in the output window.

What am I doing wrong?

Community
  • 1
  • 1
Igavshne
  • 699
  • 7
  • 33

1 Answers1

1

Based on your description, I create a simple custom command vsix project with log4net, without changing app.config file, it works.

Log4Net.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
  <log4net>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <!--log Path-->
      <param name= "File" value= "F:\App_Log\"/>
      <!--append log to file-->
      <param name= "AppendToFile" value= "true"/>
      <!--log keep days-->
      <param name= "MaxSizeRollBackups" value= "10"/>
      <param name= "StaticLogFileName" value= "false"/>
      <!--log farmat:2008-08-31.log-->
      <param name= "DatePattern" value= "yyyy-MM-dd&quot;.log&quot;"/>
      <param name= "RollingStyle" value= "Date"/>
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
      </layout>
    </appender>
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
      <mapping>
        <level value="ERROR" />
        <foreColor value="Red, HighIntensity" />
      </mapping>
      <mapping>
        <level value="Info" />
        <foreColor value="Green" />
      </mapping>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="Info" />
        <param name="LevelMax" value="Fatal" />
      </filter>
    </appender>
    <root>
      <!--(high) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (low) -->
      <level value="all" />
      <appender-ref ref="ColoredConsoleAppender"/>
      <appender-ref ref="RollingLogFileAppender"/>
    </root>
  </log4net>
</configuration>

Custom Command with log4net

using System;
using System.ComponentModel.Design;
using System.Globalization;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using log4net.Config;
using System.IO;
using log4net;

namespace CommandDemo
{
    /// <summary>
    /// Command handler
    /// </summary>
    internal sealed class FirstCommand
    {
        /// <summary>
        /// Command ID.
        /// </summary>
        public const int CommandId = 0x0100;

        /// <summary>
        /// Command menu group (command set GUID).
        /// </summary>
        public static readonly Guid CommandSet = new Guid("30f5b2c4-9c7f-4748-a1de-d6d03fe40eda");

        /// <summary>
        /// VS Package that provides this command, not null.
        /// </summary>
        private readonly Package package;

        private ILog logger;

        /// <summary>
        /// Initializes a new instance of the <see cref="FirstCommand"/> class.
        /// Adds our command handlers for menu (commands must exist in the command table file)
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        private FirstCommand(Package package)
        {
            InitLog4Net();
            logger = LogManager.GetLogger(typeof(FirstCommand));

            if (package == null)
            {
                throw new ArgumentNullException("package");
            }

            this.package = package;

            OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
            if (commandService != null)
            {
                var menuCommandID = new CommandID(CommandSet, CommandId);
                var menuItem = new MenuCommand(this.MenuItemCallback, menuCommandID);
                commandService.AddCommand(menuItem);
            }
        }

        /// <summary>
        /// Gets the instance of the command.
        /// </summary>
        public static FirstCommand Instance
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the service provider from the owner package.
        /// </summary>
        private IServiceProvider ServiceProvider
        {
            get
            {
                return this.package;
            }
        }

        /// <summary>
        /// Initializes the singleton instance of the command.
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        public static void Initialize(Package package)
        {
            Instance = new FirstCommand(package);
        }

        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private void MenuItemCallback(object sender, EventArgs e)
        {
            string message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.GetType().FullName);
            string title = "FirstCommand";

            logger.Debug("DebugInfo");
            //logger.Info("TestInfo");
            //logger.Warn("Testwarning");
            //logger.Error("Testexception");
            //logger.Fatal("Testerror");
            // Show a message box to prove we were here
            VsShellUtilities.ShowMessageBox(
                this.ServiceProvider,
                message,
                title,
                OLEMSGICON.OLEMSGICON_INFO,
                OLEMSGBUTTON.OLEMSGBUTTON_OK,
                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
        }


        private void InitLog4Net()
        {
            var logCfg = new FileInfo(@"C:\log4netconfigpath\log4net.config");
            XmlConfigurator.Configure(logCfg);
        }
    }
}
Zhanglong Wu - MSFT
  • 1,652
  • 1
  • 7
  • 8
  • I found that I didn't have the config file in the bin directory because I wrote a new installer and forgot to add it. Anyways, knowing that you could get it to work made me check everything again. Thanks, you helped me! – Igavshne Apr 07 '17 at 11:18