@manhng

Welcome to my blog!

Simplest way to support logging from a VSTO AddIn

June 23, 2020 10:46

Simplest way to support logging from a VSTO AddIn (edit)

1) Using System.IO.File.Write to a Text file

https://johandorper.com/log/thread-safe-file-writing-csharp

https://jonlabelle.com/snippets/view/csharp/thread-safe-file-writing-in-csharp

https://www.c-sharpcorner.com/UploadFile/1d42da/readerwriterlockslim-class-in-C-Sharp-threading/

System.IO.File.AppendAllText(Filepath, Text);

2) Using Log4net

https://stackoverflow.com/questions/28541528/simplest-way-to-support-logging-from-a-vsto-addin

https://docs.microsoft.com/en-us/visualstudio/vsto/deploying-an-office-solution-by-using-windows-installer?redirectedfrom=MSDN&view=vs-2017

Folder Path:

%ProgramData%

%AppData%

File Path:

C:\Users\nvmanh\AppData\Roaming\MyAddIn_DATA\MyAddIn_Rolling.log

Member:

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

Constructor:

log4net.Config.XmlConfigurator.Configure();

AssemblyInfo.cs: 

[assembly: log4net.Config.XmlConfigurator(Watch=true)]

It is relatively straightforward to setup log4net to handle simple (or complex) logging requirements. The log4net Tutorial on CodeProject provides a useful reference.

  1. Install log4net to your project using the NuGet Package Manager or Package Manager Console if you prefer.
  2. Add an App.config file if you don't have one already (right-click your project, select Add > New Item... and select Application Configuration File from Visual C# Items).
  3. Edit the App.config file to look something like this (replacing MyAddIn appropriately in the <file /> tag):

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
      </configSections>
      <log4net>
        <root>
          <level value="ALL"/> 
          <appender-ref ref="RollingFileAppender"/>
        </root>
        <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
          <file value="${APPDATA}\MyAddIn_DATA\MyAddIn_Rolling.log" />
          <appendToFile value="true" />
          <rollingStyle value="Size" />
          <maxSizeRollBackups value="5" />
          <maximumFileSize value="5MB" />
          <staticLogFileName value="true" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
          </layout>
        </appender>
      </log4net>
    </configuration>

    Log files will be saved to the user's roaming AppData (%appdata%) folder, keeping up to 5 rolling log files which do not exceed 5MB each.

  4. Add the following line to ThisAddIn_Startup() in ThisAddIn.cs (you will need to add a using log4net; directive):

    log4net.Config.XmlConfigurator.Configure();
  5. Add the following statement to any class which needs to implement logging:

    private static readonly log4net.ILog log = 
        log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  6. Events can then be logged using the log.Info, log.Warn, log.Error, log.Fatal and other methods provided by log4net.

You may get schema warning messages because log4net does not include a schema, and Visual Studio cannot then validate the config section. In that case, download the schema file from http://csharptest.net/downloads/schema/log4net.xsd to somewhere accessible. The location C:\Program Files\Microsoft Visual Studio 10.0\Xml\Schemas has been suggested elsewhere.

Select your App.config file in Visual Studio, and click into the editor. You should get an XML menu item. From there, select Schemas... and add the log4net.xsd file from where you saved it.

Note that you can also use log4net to log to the Event Viewer but you will run into the same permission issues raised in the initial question.

Simple Logger (NLog)

November 8, 2019 13:42

Simple Logger with NLog (edit)

Logger.cs

public static class Utils
{
    public static void WriteLog(string msg)
    {
        try
        {
            //Path log folder
            string folder = GetDesktopFolder();

            //Path log file
            string path = folder + "\\MyApp.log";

            // This text is added only once to the file.
            if (!File.Exists(path))
            {
                // Create a file to write to.
                using (StreamWriter sw = File.CreateText(path))
                {
                    sw.WriteLine(msg);
                }
            }

            // This text is always added, making the file longer over time
            // if it is not deleted.
            using (StreamWriter sw = File.AppendText(path))
            {
                sw.WriteLine(msg);
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine("Exception: " + e.ToString());
        }
        finally
        {
            Debug.WriteLine("Executing finally block.");
        }
    }

    public static string GetDesktopFolder()
    {
        string strDesktopFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        return strDesktopFolderPath;
    }
}

Program.cs

try
{
    Utils.WriteLog("Program called.");
    Utils.WriteLog(string.Format("Start time: {0}", (start != null ? start.ToString() : "NULL")));
    Utils.WriteLog(string.Format("End time: {0}", (end != null ? end.ToString() : "NULL")));
}
catch
{

}

NLog in ASP.NET Web API 2.1

https://code-maze.com/net-core-web-development-part3/

https://www.c-sharpcorner.com/article/introduction-to-nlog-with-asp-net-core2/

https://github.com/jignesht24/Aspnetcore/tree/master/Logging%20with%20.net%20core%202.0/Using%20Nlog

https://dotnetthoughts.net/using-nlog-in-aspnet-core/

https://edi.wang/post/2017/11/1/use-nlog-aspnet-20

https://www.c-sharpcorner.com/article/introduction-to-nlog-with-asp-net-core2/ (NLog with .NET Core)

  1. Install-Package NLog
  2. Install-Package NLog.Web.AspNetCore

 <PackageReference Include="NLog.Web.AspNetCore" Version="4.5.4" />

<PackageReference Include="NLog" Version="4.5.4" />

1./ File nlog.config

<?xml version="1.0"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Warn"
internalLogFile="c:\temp\internal-nlog.txt">

<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>

<targets>
<target name="allfile" xsi:type="File"
fileName="${basedir}\Logging\${shortdate}.log"
encoding="utf-8"
layout="[${longdate}][${machinename}][${level}] ${message} ${exception}" />
</targets>
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="allfile" />

<!--Skip Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>

2./ Config in Program.cs

public class Program  
{  
    public static void Main(string[] args)  
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>  
        WebHost.CreateDefaultBuilder(args)  
            .UseStartup()  
            .ConfigureLogging(logging =>  
            {  
                logging.ClearProviders();  
                logging.SetMinimumLevel(LogLevel.Information);  
            })  
            .UseNLog();  
}

3./ Using NLog in ValuesController

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Threading.Tasks;

namespace AspNetCoreWebApi.Controllers
{
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ILogger<ValuesController> _logger;

public ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;

_logger.LogInformation("ValuesController called.");
}
}

Reference

.NET Core

https://www.c-sharpcorner.com/article/net-core-web-api-logging-using-nlog-in-text-file/

https://www.c-sharpcorner.com/article/how-to-archive-log-files-using-nlog-with-asp-net-core/

https://www.c-sharpcorner.com/article/net-core-web-api-logging-using-nlog-in-event-log/

https://www.c-sharpcorner.com/article/combine-nlog-and-kafka-to-collect-logging-message-in-asp-net-core/

https://www.c-sharpcorner.com/article/introduction-to-nlog-with-asp-net-core2/

.NET

https://www.codeproject.com/Tips/1119363/Flexible-Logging-using-log-net

https://michaelscodingspot.com/logging-in-dotnet/

https://www.infoworld.com/article/2980677/implement-a-simple-logger-in-c.html

https://www.codeproject.com/Articles/1214072/A-Simple-Asynchronous-Logger-in-Csharp

https://www.codeproject.com/Tips/585796/Simple-Log

https://github.com/jirkapenzes/SimpleLogger

https://raygun.com/blog/c-sharp-logging-best-practices/

https://www.scalyr.com/blog/get-started-quickly-csharp-logging/

Logger

November 26, 2018 22:45

Snippet - Logger (edit)

public static class MyLogger
{
    private static string M_LogFilePath = "";
 
    static MyLogger()
    {
        M_LogFilePath = Path.Combine(Application.StartupPath, "Program.log");
 
        if (!File.Exists(M_LogFilePath))
        {
            using (StreamWriter writer = new StreamWriter(M_LogFilePath, true))
            {
                writer.WriteLine($"Start Debug at: {DateTime.Now.ToString("yyyy-MM-dd HH:mm tt")}");
            }
        }
    }
 
    public static void AppendLine(string line)
    {
        using (StreamWriter streamWriter = File.AppendText(M_LogFilePath))
        {
            streamWriter.WriteLine(line);
        }
    }
 
    public static void WriteLine(string line)
    {
        using (StreamWriter streamWriter = new StreamWriter(M_LogFilePath, true))
        {
            streamWriter.WriteLine(line);
        }
    }
}

Categories

Recent posts