Search code examples
c#web-servicesnlognlog-configuration

Is there a missing setting in my nlog.config file configured for webservice to trigger method in controller?


I want to send the Information from Nlog in a file and to a webservice at the same time. The file works fine. The webservice one won't hit a breakpoint at the controller.

I tried the steps recommended here https://github.com/NLog/NLog/wiki/WebService-target, here https://github.com/NLog/NLog/issues/1996 and understood it should be doable since https://github.com/NLog/NLog/pull/1912 and used the following code which detects the logger:

Test working just fine:

    DebugTarget target = new DebugTarget();
    target.Layout = "${message}";
    NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Debug);
    Logger logger = LogManager.GetLogger("ws");
    logger.Debug("log message"); <--- here I expected to hit the breakpoint after this step
    logger.Debug("another log message");

My Nlog.config

 <targets>      
   <target xsi:type='WebService'
      name= 'ws'
      protocol= 'HttpPost'
      url= 'http://localhost:8082/API/Nlog'
      encoding= 'UTF-8'
      preAuthenticate= 'true'
      proxyType="NoProxy">       
    <parameter name="sourceSite"        type='System.String' layout="${aspnet-request:serverVariable=Url:format=ToString}" />
    <parameter name="sourceApplication" type='System.String' layout="${iis-site-name:format=ToString}" />
    <parameter name="message"           type='System.String' layout="${message:format=ToString}" />
    <parameter name="innerException"    type='System.String' layout="${exception:format=string,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}" />
    <parameter name="level"             type='System.String' layout="${level:uppercase=true}" />
    <parameter name="stackTrace"        type='System.String' layout="${exception:format=ToString,StackTrace}${newline}" />
    <parameter name='windowsUserName'   type='System.String' layout='${windows-identity:userName=true:domain=true:format=ToString}' />        
    <header name='WindowsUserName' layout='${windows-identity:userName=true:domain=true}' />
    <header name='xapikey' layout='keyValue' />
  </target>
  <target name="file" xsi:type="File" fileName="${basedir}/log.txt"  archiveAboveSize="52428800" layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${exception:format=ToString,StackTrace}${newline}"/>
</targets>
<rules>
    <logger name="*" minlevel="Off" writeTo="file"/>
    <logger name="ws" minlevel="Trace" writeTo="ws"/>
</rules>

Controller to call but Breakpoint won't be hit:

public class NlogController : BaseController (which has BaseController : ApiController)
{        
    protected new static readonly Logger Logger = LogManager.GetCurrentClassLogger();

    /// <summary>
    /// 
    /// </summary>
    /// <param name="data"></param>
    public void Post([FromBody] NlogData data)
    { //Breakpoint placed here
        Manager.StoreLoggingInformation(data);
    }
}

NLogData Definition

public class NlogData
{
    public string SourceSite { get; set; }
    public string SourceApplication { get; set; }
    public string Message { get; set; }
    public string InnerException { get; set; }
    public string Level { get; set; }
    public string StackTrace { get; set; }
    public string WindowsUserName { get; set; }
}

I expected to hit the breakpoint in my NlogController and see what is inside "data".


Solution

  • I found the errors after finding someone with the same error.

    The first mistake was this:

    protected new static readonly Logger Logger = LogManager.GetCurrentClassLogger();
    

    while using

        <logger name="ws" minlevel="Trace" writeTo="ws"/>
    

    name="*" ist the correct setting, because GetCurrenClassLogger gets the namespace+Classname as name. That is why the the logger never got hit. IF you have a named logger you need to use

    Logger logger = LogManager.GetLogger("ws");
    

    After that, there was a second error.

    url= 'http://localhost:8082/API/Nlog'
    url= 'http://localhost:Port/{Path}/Controller**/Action**' is the correct syntax. 
    

    After those two changes I could hit my breakpoint and everything worked as expected! Thanks for the help.

    I hope the Nlog Team changes that at https://github.com/NLog/NLog/wiki/WebService-target

    Example config:

    <nlog>
    <targets>
        <target type='WebService'
                name='ws'
                url='http://localhost:1234/logme' <-- change to 'http://localhost:1234/logme/Post'
                protocol='HttpPost'
                encoding='UTF-8'   >
            <parameter name='param1' type='System.String' layout='${message}'/> 
            <parameter name='param2' type='System.String' layout='${level}'/>
        </target>
    </targets>
    <rules>
      <logger name='*' writeTo='ws'></logger>
    </rules>
    </nlog>
    

    Would have saved 2 days of work.