Can't get NLog to work - nlog

I am having no luck getting NLog to work. Working through the tutorial, I have the exact code as seen there.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
namespace NLog2
{
class Program
{
static void Main(string[] args)
{
var c = new MyClass();
c.MyMethod1();
}
}
public class MyClass
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public void MyMethod1()
{
logger.Trace("Sample trace message");
logger.Debug("Sample debug message");
logger.Info("Sample informational message");
logger.Warn("Sample warning message");
logger.Error("Sample error message");
logger.Fatal("Sample fatal error message");
// alternatively you can call the Log() method
// and pass log level as the parameter.
logger.Log(LogLevel.Info, "Sample fatal error message");
}
}
}
My config file (named NLog.config) looks like...
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="logfile" xsi:type="File" fileName="file.txt" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
</nlog>
I get no output. Can someone see what the issue is here?

Web User, find your NLog.config in uour files list in Solution Explorer. Right click NLog.config and choose properties. choose "Copy always" at "Copy to output directory" and be happy ^)

Dumb mistake. I had not set the config file to copy to the output directory.

Related

Log4j create a file for each logger

I have a lot of selenium tests that create a logger per class, it might not be the best way but it's code written by somebody else and I dont have time to rewrite it. I would like each Test of have it's own logfile so that it's easier to see what went wrong.
Is there a way to have log4j create a file for each logger that is created?
Yes, you can do this with log4j1 but I believe the only way is through programmatically adding the file appender to the logger.
Here is some sample code:
package test;
import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
public class Main {
private static final Logger logger = Logger.getLogger(Main.class);
private static final Logger logFoo = Logger.getLogger("test.Foo");
private static final Logger logBar = Logger.getLogger("test.Bar");
public static void main(String[] args) {
logger.addAppender(createFileAppender("logs/main.log"));
logFoo.addAppender(createFileAppender("logs/foo.log"));
logBar.addAppender(createFileAppender("logs/bar.log"));
logger.info("This is the main logger");
logFoo.info("this is the foo logger");
logBar.info("This is the bar logger");
}
private static Appender createFileAppender(String logName) {
FileAppender fa = new FileAppender();
fa.setName("FileLogger");
fa.setFile(logName);
fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fa.setThreshold(Level.DEBUG);
fa.setAppend(true);
fa.activateOptions();
return fa;
}
}
Here is a sample log4j.xml config file:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<logger name="test" additivity="false">
<level value="DEBUG" />
<appender-ref ref="consoleAppender" />
</logger>
</log4j:configuration>
Note that you probably don't need to specify the console appender, I did it just to make sure things were working. You may not even need to specify any loggers, but I didn't test with that configuration.
The output of the above is 3 log files each containing the one message that was provided to the corresponding logger, and console output of all log messages.

LoggerName already in use

So i had this working, ive switched to paket and i guess some versions of dll's have changed.
However I still do not understand the error i am getting.
System.ArgumentException : LoggerName already in use
Parameter name: loggerName
my code is basically exactly as it is on here
http://www.tomdupont.net/2015/06/capture-xunit-test-output-with-nlog-and.html
public class NLogTests : IDisposable
{
private readonly ILogger _logger;
public NLogTests(ITestOutputHelper outputHelper)
{
_logger = outputHelper.GetNLogLogger();
}
public void Dispose()
{
_logger.RemoveTestOutputHelper();
}
[Fact]
public void Hello()
{
_logger.Trace("World Trace");
_logger.Debug("World Debug");
_logger.Warn("World Warn");
_logger.Error("World Error");
}
}
and config
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
throwExceptions="true">
<extensions>
<add assembly="xunit.NLog" />
</extensions>
<targets async="false">
<target xsi:type="TestOutput"
layout="${time}|${level:uppercase=true}|${logger}|${message}"
name="Test" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="Test" />
</rules>
</nlog>
The GetNLogLogger method has an overload that takes a logger name and a bool for incremental suffixes. Using these does not help.
I am really confused.
stacktrace:
System.ArgumentException
LoggerName already in use
Parameter name: loggerName
at Xunit.NLog.Targets.TestOutputTarget.Add(ITestOutputHelper testOutputHelper, String loggerName)
at Xunit.NLog.Helpers.TestOutputHelpers.AddTestOutputHelper(ITestOutputHelper testOutputHelper, String loggerName, Boolean addNumericSuffix)
at Xunit.NLogTestOutputExtensions.GetNLogLogger(ITestOutputHelper testOutputHelper, String loggerName, Boolean addNumericSuffix)
at ProjectRake.BusinessLogic.Spec.TautologiesToVerifyNLogOutput..ctor(ITestOutputHelper outputHelper) in M:\programming\ProjectRake\src\server\ProjectRake.BusinessLogic.Spec\TautologiesToVerifyNLogOutput.cs:line 19
edit:
have downgraded all xunit stuff to 2.1.0, same issue.
outputHelper.GetNLogLogger(); is calling AddTestOutputHelper("")
I guess it only works if you call it once.
You can use outputHelper.GetNLogLogger("myname"); or outputHelper.GetNLogLogger(typeof(NLogTests).Name);

custom log4j layout class not being called

I've a custom log4j layout class that extends PatternLayout, my layout class simply masks the password in the log. It works in a simple console app. Here's the log4j.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.ConsoleAppender">
<layout class="com.PortalLog4jFilteringPattern"> <param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/> </layout>
</appender>
<root>
<priority value ="DEBUG" /> <appender-ref ref="A1" />
</root>
</log4j:configuration>
Here's a snipet of the layout class:
public class PortalLog4jFilteringPattern extends PatternLayout {
// omitted
#Override
public String format(LoggingEvent event) {
System.out.println("in format()...... ");
// rest omitted
Here's the calling code:
import org.apache.log4j.Logger;
public class ProductDemo {
private static Logger logger = Logger.getLogger(ProductDemo.class);
public ProductDemo() {
}
public void processOrder(CustomerOrder order) {
logger.info(order.getProductName());
}
// rest ommited
A sample result log with pswd being masked:
main INFO test.ProductDemo - "password":"*****"},
But once I moved the custom layout class to my webapp (log4j.xml is exactly the same.), it doesn't get called (i.e., no System.out output) and the pswd is still being shown. I'm running the webapp locally with maven on Jetty using this cmd: mvn jetty:run
Here's the calling code:
// original code, but I changed it to import org.apache.log4j.Logger for experiment
//import org.slf4j.LoggerFactory;
//import org.slf4j.Logger;
import org.apache.log4j.Logger;
public class BlahBlahClass extends Blah
// things omitted
private final static Logger log = Logger.getLogger( BlahBlahClass .class );
Any idea? thanks
In a Java EE server environment I would say: it's a class loader issue. Jetty is a servlet container, so it's class loading architecture is simpler; still, it's worth checking. If your log4j is not deployed within the WAR, but comes from the Jetty class path, this is almost certainly the cause.
Try changing the class loading strategy to "parent last", as described in the Jetty manual, see if it helps.
You should import package name of your class in log4j. I added to log4j2.xml as below:
<Configuration packages="package path of your class">

log4net issue in web service

We are successfully using log4net in our UI Layer but when we are testing in Webservice layer it does not work.
Here is the code in UI Layer:
public partial class _Default : System.Web.UI.Page
{
ILog logger = log4net.LogManager.GetLogger(typeof(_Default));
protected void Page_Load(object sender, EventArgs e)
{
ServiceReference1.IService1 is1 = new ServiceReference1.Service1Client();
is1.GetData(1);
logger.Info("Hello Nine Thanks for use Log4Net,This is info message");
logger.Debug("Hello Nine Thanks for use Log4Net,This is Debug message");
logger.Error("Hello Nine Thanks for use Log4Net,This is Error message");
logger.Warn("Hello Nine Thanks for use Log4Net,This is Warn message");
logger.Fatal("Hello Nine Thanks for use Log4Net,This is Fatal message");
}
}
Here is the web.config settings for the UI Layer:
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="MyloggerSite2.log"/> <!-- This is logging in app root folder -->
<param name="AppendToFile" value="true"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-2p %c [%x] - %m%n"/>
</layout>
</appender>
<root>
<level value="All"/>
<appender-ref ref="FileAppender"/>
</root>
</log4net>
Here is the code in ServiceLayer which does not work although it it is the same as above for the most:
public class Service1 : IService1
{
public string GetData(int value)
{
ILog logger = log4net.LogManager.GetLogger(typeof(Service1));
logger.Info("Hello Nine Thanks for use Log4Net,This is info message");
logger.Debug("Hello Nine Thanks for use Log4Net,This is Debug message");
logger.Error("Hello Nine Thanks for use Log4Net,This is Error message");
logger.Warn("Hello Nine Thanks for use Log4Net,This is Warn message");
logger.Fatal("Hello Nine Thanks for use Log4Net,This is Fatal message");
return string.Format("You entered: {0}", value);
}
}
Please let me know if you have any suggestions.
Thanks,
N
Do you configure log4net for instance by having an attribute like this in your web service:
[assembly: log4net.Config.XmlConfigurator(Watch=true)]
I have just added this attribute manually in AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
It works.
Thanks.
Just add below assembly in web config file of your service's project.
[assembly: log4net.Config.XmlConfigurator(Watch = true)]

Nlog Logger.Info not working

i have a webservice which is consumed via jquery ... now the problem is i want to put some debug into from nlog so that i can see how the flow is actually going .. i thought nlog's option for debuging ....
here is my config and code
<targets>
<target name="file" xsi:type="File"
layout="${longdate} ${logger} ${message}"
fileName="${basedir}/Logs/${shortdate}.log" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file" />
<logger name="*" minlevel="Error" writeTo="file" />
<logger name="*" minlevel="Fatal" writeTo="file" />
<logger name="*" minlevel="Info" writeTo="file" />
</rules>
and the logger class where i have given for getting debug information is
[ScriptService]
public class Service : System.Web.Services.WebService
{
Logger logger = LogManager.GetCurrentClassLogger();
[WebMethod]
public String GetAgentDetails(String AgentId)
{
logger.Info("This is webservice");
String result = string.Empty;
try
{
using (ISession session = NhibernateHelper.Opensession())
{
logger.Info("Enters Session");
var agent = GetAgent(); // Gets the agent object
result = JsonConvert.SerializeObject(agent);
logger.Info(result);
return result;
}
}
catch (InvalidOperationException ioe)
{
logger.Error(ioe.Message);
logger.Fatal(ioe.Message);
logger.Error(ioe.InnerException);
logger.Fatal(ioe.InnerException);
return null;
}
catch (Exception ex)
{
logger.Error(ex.Message);
logger.Fatal(ex.Message);
logger.Error(ex.InnerException);
logger.Fatal(ex.InnerException);
}
return result;
}
}
when accessed through the jquery script it should have written the log informations where i have written logger.info(result) but it seems no log file is created .can someone explain whats the problem ? however the same log file works for all other classes . no issues in that . if exceptions are thrown the log file gets created and log is written. but in this case for logger.info its not happening . i am using Nlog 2.0 with Asp.net 3.5 SP1 .

Resources