Nlog Logger.Info not working - nlog

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 .

Related

Rotating GC Log files with qos Logback

I am trying to rotate my gc.log file every time my application starts up.
I am using this file appender in my logback.xml file.
...
<appender name="GCFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.directory}/gc.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.directory}/gc.log.%d{yyyyMMdd}_%d{HHmmss,aux}.gz</fileNamePattern>
<TimeBasedFileNamingAndTriggeringPolicy class="com.ga.omni.utility.StartupTriggeringPolicy" />
<maxHistory>50</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
...
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="GCFILE" />
</root>
(the "FILE" ref is a reference to our default logging file for the app.)
The appender references a TimeBasedFileNamingAndTriggeringPolicy named StartupTriggeringPolicy:
#NoAutoStart //won't be autostarted by Joran at config time
public class StartupTriggeringPolicy<E> extends DefaultTimeBasedFileNamingAndTriggeringPolicy<E> {
Logger log = LoggerFactory.getLogger(StartupTriggeringPolicy.class);
public StartupTriggeringPolicy() {
log.info("StartupTriggeringPolicy constructor called");
}
#Override
public void start() {
log.info("StartupTriggeringPolicy start() called... initialting gc.log rollover");
super.start();
//only check this once, on startup.
nextCheck = 0L;
isTriggeringEvent(null, null);
try {
tbrp.rollover();
log.info("StartupTriggeringPolicy start() called... gc.log successfully rolled over.");
} catch (RolloverFailure e) {
log.warn("Error rolling over gc.log file in StartupTriggeringPolicy.start()");
//Do nothing
}
}
}
The trouble that I'm facing is that the app starts up, but the StartupTriggeringPolicy never seems to get instantiated. None of the logs from the constructor or start() method are written, and if I put breakpoints in those methods, the breakpoints don't get hit.
Any suggestions would be greatly apperciated!

Custom PatternLayoutConverter with log4net.Ext.Json?

I have the following log4net configuration:
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type='log4net.Layout.SerializedLayout, log4net.Ext.Json'>
<renderer type='log4net.ObjectRenderer.JsonDotNetRenderer, log4net.Ext.Json.Net'>
<DateFormatHandling value="IsoDateFormat" />
<NullValueHandling value="Ignore" />
</renderer>
<converter>
<name value="preparedMessage" />
<type value="JsonLogs.CustomLayoutConverter" />
</converter>
<default />
<remove value='message' />
<remove value='ndc' />
<member value='message:messageObject' />
<member value='details:preparedMessage' />
</layout>
</appender>
<appender name="Console2" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<converter>
<name value="preparedMessage" />
<type value="JsonLogs.CustomLayoutConverter" />
</converter>
<conversionPattern value="%level %thread %logger - %preparedMessage%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="Console2" />
</root>
</log4net>
with the following implementation of my custom PatternLayoutConverter:
namespace JsonLogs
{
using System.IO;
using log4net.Core;
using log4net.Layout.Pattern;
public class CustomLayoutConverter : PatternLayoutConverter
{
#region Methods
protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
if (loggingEvent.MessageObject is string stringMessage)
{
writer.Write(new { message = stringMessage });
}
else
{
writer.Write(loggingEvent.RenderedMessage);
}
}
#endregion
}
}
For some reason, the converter works perfectly fine with the Console2 appender(which is not JSON driven) but it doesn't work with the Console appender whose output is JSON.
Example of the output:
Console -> {"date":"2018-12-09T12:25:28.0529041+03:00","level":"INFO","appname":"JsonLogs.exe","logger":"JsonLogs.Program","thread":"1","message":"Test","details":"preparedMessage"}
Console2 -> INFO 1 JsonLogs.Program - { message = Test }
My goal is to have details always in JSON that's why I introduced my own converter to catch primitive values and wrap them in a custom object.
Is my configuration wrong? Or I'm missing something? Could you help me, please, to figure this out?
Thank you
The issue seems to be a bug of log4net.Ext.Json. I'm going to report it on their GitLab.
So far, I ended up with my custom log4net layout which looks like this
public class CustomLayout : PatternLayout
{
#region Public Methods and Operators
public override void Format(TextWriter writer, LoggingEvent loggingEvent)
{
var message = loggingEvent.MessageObject.GetType().IsPrimitive || loggingEvent.MessageObject is string || loggingEvent.MessageObject is decimal || loggingEvent.MessageObject is BigInteger
? new { message = loggingEvent.MessageObject }
: loggingEvent.MessageObject;
writer.WriteLine(JsonConvert.SerializeObject(new
{
timestamp = loggingEvent.TimeStampUtc,
threadId = loggingEvent.ThreadName,
details = message,
logger = loggingEvent.LoggerName,
level = loggingEvent.Level.DisplayName,
user = loggingEvent.UserName
}));
}
#endregion
}
it meets my needs and does exactly what I want.
The exact place of this problem is AddMember Method and its implementation. Here is SerializedLayout source code for that:
public virtual void AddMember(string value)
{
var arrangement = log4net.Util.TypeConverters.ArrangementConverter.GetArrangement(value, new ConverterInfo[0]);
m_arrangement.AddArrangement(arrangement);
}
As you can see the second parameter of GetArrangment is empty array of ConverterInfo, Though there must be our custom attached ones (by AddConverter method or by xml).
As the solution you can implement your own subclass that will derive from SerializedLayout with overridden AddMember like this:
public override void AddMember(string value)
{
var customConverter = new ConverterInfo("lookup", typeof(CustomPatternConverter));
var arrangement = log4net.Util.TypeConverters.ArrangementConverter.GetArrangement(value, new ConverterInfo[] { customConverter });
m_arrangement.AddArrangement(arrangement);
}
Hope it helps as it did with my case!

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);

event is not generated in windows event

I am using log4net for logging, I have two appenders one file and other eventlog appender.
I have refered here this link
My problem is that the log is generated in file but not in windows event.
My code is:
<log4net>
<logger name="FileLogger">
<level value="ERROR" />
<appender-ref ref="RollingLogFileAppender" />
</logger>
<logger name="EventLogger" additivity="False">
<level value="ALL" />
<appender-ref ref="EventLogAppender" />
</logger>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\logfile.xml"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<datePattern value="yyyyMMdd"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="5MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="<Event><Date>%date</Date><Message>%message</Message><Stack>%exception</Stack></Event>%newline" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<!--<param name="MvcApplication1" value="eventlog" />-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender></log4net>
code side is:
public class LogManager
{
private static readonly ILog eventLogger = log4net.LogManager.GetLogger("EventLogAppender");
private static readonly ILog fileLogger = LogManager.GetLogger("FileLogger");
public void Error(Exception ex)
{
eventLogger.Logger.Log(eventLogger.GetType(), Level.Error, ex.Source, ex);
}
public void Info(string message)
{
LoggingEventData e = new LoggingEventData()
{
Level = Level.Fatal,
Message = message
};
eventLogger.Logger.Log(new LoggingEvent(e));
fileLogger.Logger.Log(new LoggingEvent(e));
}
}
I am using application_Error for global level error
protected void Application_Error(object sender, EventArgs e)
{
var httpContext = ((MvcApplication)sender).Context;
var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
var currentController = " ";
var currentAction = " ";
if (currentRouteData != null)
{
if (currentRouteData.Values["controller"] != null && !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
{
currentController = currentRouteData.Values["controller"].ToString();
}
if (currentRouteData.Values["action"] != null && !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
{
currentAction = currentRouteData.Values["action"].ToString();
}
}
var ex = Server.GetLastError();
var controller = new ErrorController();
var routeData = new RouteData();
var action = "Index";
if (ex is HttpException)
{
var httpEx = ex as HttpException;
switch (httpEx.GetHttpCode())
{
case 404:
action = "NotFound";
break;
case 401:
action = " UnAuthorized";
break;
// others if any
default:
action = "Index";
break;
}
}
new LogManager().Error(ex);
httpContext.ClearError();
httpContext.Response.Clear();
httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
httpContext.Response.TrySkipIisCustomErrors = true;
routeData.Values["controller"] = "Error";
routeData.Values["action"] = action;
controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
}
Please help where I am wrong why error and Info is not logged in windows event
I think you have not referenced the EventLogger correctly in code:
ILog eventLogger = log4net.LogManager.GetLogger("EventLogAppender");
Should be changed to:
ILog eventLogger = log4net.LogManager.GetLogger("EventLogger");

Can't get NLog to work

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.

Resources