I have a Graylog logging server set up for all our projects. One of the projects is using NLog and it uses a framework with Common Logging.
When the framework logs, the messsage received in Graylog is {0}. So somewhere it's string formatting not done.
If i configure a parameter and send in $(message) there, the expanded message is sent.
Also, the colored console configured works as expected.
<?xml version="1.0" encoding="utf-8" ?>
<nlog throwExceptions="true" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<add assembly="NLog.Targets.GraylogHttp"/>
</extensions>
<targets>
<target name="graylog" xsi:type="GraylogHttp" facility="Superman"
graylogServer="http://xxxxxx.stackhero-network.com" graylogPort="xxxx">
<parameter name="real_message" layout="${longdate}|${pad:padding=5:inner=${level:uppercase=true}}|${message}" />
<parameter name="source_method" layout="${callsite}" />
</target>
<target name="coloredConsole" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false"
layout="${longdate}|${pad:padding=5:inner=${level:uppercase=true}}|${message}" >
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" appendTo="graylog"/>
<logger name="*" minlevel="Trace" appendTo="coloredConsole"/>
</rules>
</nlog>
The code used for calling looks like this (Relevant parts...)
using Common.Logging;
internal static ILog Logger = LogManager.GetLogger<SboApp>();
Logger.Error($"UI Connect Error: {ex.Message}", ex);
I'm using
Common.Logging.NLog4412 v 3.4.1
NLog v 4.4.12
NLog.Targets.GraylogHttp v 0.0.24
What am i doing wrong
Related
I have implemented NLog for .NET Core 3.1 MVC web app and API projects. The nlog.config file for both of them is nearly identical. I've carefuly checked this and the only difference is the database table name and file name that they log to.
I'm successfully suppressing non-essential Microsoft logs from the API project, but am only partially able to do so for the web app. Specifically, Trace and Info logs by Microsoft that deal with making calls to the API using HttpClient appear in the file and database:
You can see that only one of the logs is a log that I actually wrote, and the rest are were automatically logged by Microsoft.
I'm not sure what to try here, but I've looked at the internal logs and saw nothing out of the ordinary.
I want to know how can I suppress the additional Microsoft logs and what's wrong with my current configuration?
NuGet packages I have installed (identical for both apps):
nlog.config of the web app project:
<?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"
autoReload="true"
throwConfigExceptions="true"
internalLogLevel="Info"
internalLogFile="c:\temp\internal-CNC_WebUI-nlog.txt">
<extensions>
<add assembly="Nlog.Extensions.Logging"/>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<targets>
<target xsi:type="File" name="CNC_WebUIFile" fileName="c:\temp\nlog-CNC_WebUIFile-${shortdate}.log"
layout="${aspnet-traceidentifier}|${configsetting:AppSettings.NlogConnection.AppName}|${event-properties:ObjectID}|${date}|${uppercase:${level}}|${message} ${exception:format=tostring}|${logger}|${callsite:filename=false}|${exception:toString}" />
<target name="databaseLogger" xsi:type="Database"
dbProvider="sqlserver"
dbHost="${configsetting:AppSettings.NlogConnection.DbHost}"
dbDatabase="${configsetting:AppSettings.NlogConnection.Database}"
dbUserName="${configsetting:AppSettings.NlogConnection.User}"
dbPassword="${configsetting:AppSettings.NlogConnection.Password}" >
<commandText>
INSERT INTO dbo.CNC_WebUILogs (
CorrelationId, Application, ObjectID, Logged, Level, Message,
Logger, CallSite, Exception
) VALUES (
#CorrelationId, #Application, #ObjectID, #Logged, #Level, #Message,
#Logger, #Callsite, #Exception
);
</commandText>
<parameter name="#correlationId" layout="${aspnet-traceidentifier}" />
<parameter name="#application" layout="${configsetting:AppSettings.NlogConnection.AppName}" />
<parameter name="#ObjectID" layout="${event-properties:ObjectID}" />
<parameter name="#logged" layout="${date}" />
<parameter name="#level" layout="${level}" />
<parameter name="#message" layout="${message}" />
<parameter name="#logger" layout="${logger}" />
<parameter name="#callSite" layout="${callsite:filename=false}" />
<parameter name="#exception" layout="${exception:toString}" />
</target>
</targets>
<rules>
<logger name="Microsoft.*" levels="Warn,Error,Fatal" writeTo="databaseLogger,CNC_WebUIFile"></logger>
<logger name="Microsoft.*" minlevel="Trace" final="true" />
<logger name="*" minlevel="Trace" writeTo="CNC_WebUIFile" />
<logger name="*" minlevel="${configsetting:AppSettings.NlogConnection.LogLevel}" writeTo="databaseLogger" />
</rules>
</nlog>
One of my repos that had their API call activity logged by Microsoft:
public class MfgrRepo : IMfgrRepo
{
private readonly IHttpClientFactory _clientFactory;
public MfgrRepo(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task<List<MfgrDto>> Get()
{
HttpClient client = _clientFactory.CreateClient(HttpClientConfigNames.CNC);
List<MfgrDto> models = new List<MfgrDto>();
try
{
HttpResponseMessage response = await client.GetAsync("api/Mfgrs");
models.AddRange(await response.Content.ReadFromJsonAsync<List<MfgrDto>>());
}
catch (Exception ex)
{
throw ex;
}
return models;
}
}
You can configure the log levels that the M.E.Logging system uses through the appsettings.json file. This also allows you to configure the types per namespace, so you can make the System.Net.Http namespace silent that way:
{
"Logging": {
"LogLevel": {
"System.Net.Http": "Warning"
}
}
}
You already have one blackhole here:
<rules>
<logger name="Microsoft.*" levels="Warn,Error,Fatal" writeTo="databaseLogger,CNC_WebUIFile"></logger>
<logger name="Microsoft.*" minlevel="Trace" final="true" /> <!-- Black Hole -->
<logger name="*" minlevel="Trace" writeTo="CNC_WebUIFile" />
<logger name="*" minlevel="${configsetting:AppSettings.NlogConnection.LogLevel}" writeTo="databaseLogger" />
</rules>
I would just configure an additional "blackhole" like this:
<rules>
<logger name="Microsoft.*" maxLevel="Info" final="true" /> <!-- Black Hole 1 -->
<logger name="System.Net.Http.*" maxLevel="Info" final="true" /> <!-- Black Hole 2 -->
<logger name="*" minlevel="Trace" writeTo="CNC_WebUIFile" />
<logger name="*" minlevel="${configsetting:AppSettings.NlogConnection.LogLevel}" writeTo="databaseLogger" />
</rules>
I have a .NET Core application which has NLog configured. This is the contents of the NLog.config:
<?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" autoReload="false" internalLogLevel="Error" internalLogToConsole="true" internalLogIncludeTimestamp="true" keepVariablesOnReload="true">
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<variable name="appId" value="" />
<variable name="componentId" value="" />
<variable name="file-target-path" value="" />
<variable name="file-target-name" value="" />
<targets>
<target xsi:type="Console" name="console-target" layout="${date:universalTime=true:format=yyyy-MM-dd HH\:mm\:ss.fff}Z ${uppercase:${level}} APP=${var:appId} COMP=${var:componentId} [${when:when='${threadname}'=='':inner=${threadid}:else=${threadname}}] ${message} - Logger=${logger},Level=${uppercase:${level}},ThreadId=${threadid},${onexception:,Exception\="${exception:format=tostring}"}" />
<target xsi:type="File" name="file-target"
layout="${date:universalTime=true:format=yyyy-MM-dd HH\:mm\:ss.fff}Z ${uppercase:${level}} APP=${var:appId} COMP=${var:componentId} [${when:when='${threadname}'=='':inner=${threadid}:else=${threadname}}] ${message} - Logger=${logger},Level=${uppercase:${level}},ThreadId=${threadid},${onexception:,Exception\="${exception:format=tostring}"}"
fileName="${basedir}/${var:file-target-path}/${var:file-target-name}.log"
archiveFileName="${basedir}/${var:file-target-path}/${var:file-target-name}.{###}.txt"
archiveEvery="Day"
archiveNumbering="DateAndSequence"
archiveAboveSize="5242880"
archiveDateFormat="yyyyMMdd"
maxArchiveDays="31" />
</targets>
<rules>
<logger name="*" minLevel="Trace" writeTo="console-target" />
<logger name="*" minLevel="Trace" writeTo="file-target" />
</rules>
</nlog>
I'm now writing a class which parses the log for a the Regex value \sApplication Running\s([\-]+?)\s. I currently have the log file path hard coded in my StreamReader like below:
Regex regex = new Regex(#"\sApplication Running\s([\-]+?)\s");
using (StreamReader reader = new StreamReader(#"C:\path\to\my\log_file.log"))
{
...
}
How can I update this so the log file is obtained from the logging configuration instead of the hard coding it in my class?
You can retrieve log file location from LogManager.Configuration.
var nlogFileTarget = LogManager.Configuration.AllTargets.OfType<FileTarget>().First();
var dummyEventInfo = new LogEventInfo { TimeStamp = DateTime.UtcNow };
var logFilePath = nlogFileTarget.FileName.Render(dummyEventInfo);
Similar solution:
<nlog>
<variable name="file-target-path" value="" />
<variable name="file-target-name" value="" />
<variable name="file-target-filename" value="${basedir}/${var:file-target-path}/${var:file-target-name}.log"" />
<targets>
<target xsi:type="File" name="file-target" fileName="${file-target-filename}" />
</targets>
<rules>
<logger name="*" minLevel="Trace" writeTo="file-target" />
</rules>
</nlog>
And then you can do this:
var filetargetPath = NLog.LogManager.Configuration?.Variables["file-target-filename"]?.Render(LogEventInfo.CreateNullEvent());
I have the following nlog.config file in ASP.NET Core 2.1 project. However, it's logging messages from every logger (including Microsoft logger) to console.
<?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"
autoReload="true"
internalLogLevel="Error"
internalLogFile="${specialfolder:folder=UserProfile}\nlog\internal-nlog.txt">
<variable name="fullLayout" value="${shortdate} [${uppercase:${level}}] ${logger}: ${message} ${exception:format=tostring} url: ${aspnet-request-url}" />
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!-- the targets to write to -->
<targets>
<!-- write to console -->
<target name="console" xsi:type="ColoredConsole" layout="${fullLayout}" />
<!-- write to file -->
<target xsi:type="File"
name="allfile"
fileName="${defaultDirectory}/test-api-all.log"
archiveEvery="Day"
archiveFileName="${defaultDirectory}/test-api-all-${#}.log"
archiveNumbering="Date"
archiveDateFormat="yyyy-MM-dd"
maxArchiveFiles="5"
layout="${fullLayout}" />
<!-- another file log, only own logs. Uses some ASP.NET core renderers -->
<target xsi:type="File"
name="ownFile-web"
fileName="${defaultDirectory}/test-api-app.log"
archiveEvery="Day"
archiveFileName="${defaultDirectory}/test-api-app-${#}.log"
archiveNumbering="Date"
archiveDateFormat="yyyy-MM-dd"
maxArchiveFiles="5"
layout="${fullLayout}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="console" />
<!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" maxLevel="Info" final="true" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>
I do not have any logging settings in appsettings.json files. All logger configuration in in nlog.config. In the Program.cs, I'm registering NLog like:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging => logging.ClearProviders())
.UseNLog()
.Build();
How can I filter out Microsoft logs?
EDIT:
Above configuration started working without a problem the next day without me making any changes :O
Maybe this will work:
<!-- rules to map from logger name to target -->
<rules>
<!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" maxLevel="Info" final="true" />
<logger name="*" minlevel="Trace" writeTo="console" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
The order of the logging rules are important, as the rules are matched from the top. See also https://github.com/NLog/NLog/wiki/Configuration-file#rules
The order of your logging rules seems to be correct. I suggest trying to double check if your updated nlog.config file is being copied to the build directory (e.g. \bin\Debug\netcoreapp2.1\nlog.config)
I kind of encountered the same issue, but found out that debugging using Visual Studio, it sometimes doesn't really copy the nlog.config file to your build directory. So the solution is to Clean the project first, then Build, and finally Debug.
I have some console apps I've written at work. I'd like to get NLog into them but I am having trouble.
When I inspect the 'logger' object, I see in it's 'Factory' property, that the configuration had targets=0, loggingrules=0, everything blank or unset.
So, it doesn't do ANYTHING.. doesn't drop an internal log file either... I have tried nLog.config NLog.config and nlog.config... to no avail. Tried ver 3 and 4 of NLog too...
Why would it not pick up the config?
I have:
NLog.config in the root with 'Content' for build action and 'Copy Always' set
Confirmed the NLog.config IS being copied to the bin
Here's the NLog.config:
<?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"
autoReload="true"
throwConfigExceptions="true"
throwExceptions="true"
internalLogLevel="Trace"
internalLogFile="c:\temp\NlogInternal.log"
internalLogToConsole="true"
internalLogToConsoleError="true"
internalLogToTrace="true">
<targets>
<target xsi:type="Console" name="debugConsole" layout="${message} "/>
<target xsi:type="File" name="debugFile" createDirs="true" fileName="c:\temp\testlog.log" layout="${longdate} ${uppercase:${level}} ${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="debugConsole"/>
<logger name="*" minlevel="Trace" writeTo="debugFile"/>
</rules>
</nlog>
and finally (this doesn't error, but nothing is output since the config is blank):
private static Logger logger = LogManager.GetCurrentClassLogger();
logger.Info("ConsoleApp test log...");
Do your app.config have a NLog configSection?
Something like this:
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog>
</nlog>
</configuration>
If even the internalLogger isn't working, you could debug the issue by setting
the InternalLogger.LogWriter
e.g.
// enable internal logging to a custom TextWriter
InternalLogger.LogWriter = new StringWriter(); //e.g. TextWriter writer = File.CreateText("C:\\perl.txt")
I got the same issue on my end. When you make change your fileName Path "c:\temp\testlog.log" to
"c:/temp/testlog.log" then it will work. Hope the below snipet help you to resolve the issue.
<targets>
<target xsi:type="Console" name="debugConsole" layout="${message} "/>
<target xsi:type="File" name="debugFile" createDirs="true"
fileName="c:/temp/testlog.log" layout="${longdate} ${uppercase:${level}}
${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="debugConsole"/>
<logger name="*" minlevel="Trace" writeTo="debugFile"/>
</rules>
In my code I have some info messages like logger.Log("dwewe") and logger.Debug("ddddf").
The problem is that the Debug messages are not being written even when I debug in VS.
<?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"
throwExceptions="true"
internalLogLevel="Trace"
internalLogFile="c:\nlog-app.log"
autoReload="false"
internalLogToConsole="true">
<!--
See http://nlog-project.org/wiki/Configuration_file
for information on customizing logging rules and outputs.
-->
<targets>
<!-- file targets -->
<target name="asyncFile" xsi:type="AsyncWrapper">
<target xsi:type="File" name="f" fileName="${basedir}/Logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message} ${event-context:item=error-source} ${event-context:item=error-class} ${event-context:item=error-method} ${event-context:item=error-message} ${event-context:item=inner-error-message} ${event-context:item=stack-trace}"/>
</target>
<!-- database targets -->
<target name="database" xsi:type="Database" keepConnection="true" useTransactions="true"
dbProvider="System.Data.SqlClient"
connectionString="data source=XXXXXX.database.windows.net;initial catalog=NLog;integrated security=false;persist security info=True;User ID=XXXXr;Password=BXXXX3"
commandText="INSERT INTO Logs(EventDateTime, EventLevel, UserName, MachineName, EventMessage, ErrorSource, ErrorClass, ErrorMethod, ErrorMessage, InnerErrorMessage, StackTrace) VALUES (#EventDateTime, #EventLevel, #UserName, #MachineName, #EventMessage, #ErrorSource, #ErrorClass, #ErrorMethod, #ErrorMessage, #InnerErrorMessage, #StackTrace)">
<!-- parameters for the command -->
<parameter name="#EventDateTime" layout="${date:s}" />
<parameter name="#EventLevel" layout="${level}" />
<parameter name="#UserName" layout="${windows-identity}" />
<parameter name="#MachineName" layout="${machinename}" />
<parameter name="#EventMessage" layout="${message}" />
<parameter name="#ErrorSource" layout="${event-context:item=error-source}" />
<parameter name="#ErrorClass" layout="${event-context:item=error-class}" />
<parameter name="#ErrorMethod" layout="${event-context:item=error-method}" />
<parameter name="#ErrorMessage" layout="${event-context:item=error-message}" />
<parameter name="#InnerErrorMessage" layout="${event-context:item=inner-error-message}" />
<parameter name="#StackTrace" layout="${event-context:item=stack-trace}" />
</target>
<target name="console" xsi:type="Console" />
</targets>
<rules>
<!-- add your logging rules here -->
<logger name="*" minlevel="Info" writeTo="database" />
<logger name="*" minlevel="Error" writeTo="asyncFile" />
<logger name="*" minlevel="Trace" writeTo="console" />
</rules>
</
The reason that you are not able to get Debug is that debug is the lowest level log level
just add following tag in rules tag in nlog.config file.
<logger name="*" minlevel="Debug" writeTo="console" />
I found the problem to be related to the default appsettings.json that Visual Studio automatically adds to the project. It looks like this.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
The solution was to remove or rename this section.
{
"Logging-DISABLE": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
This allowed nlog.config to be utilized.
You are using 3 different log targets.
Database target is set to Info level, so debug messages are not going there.
File target accepts only Error messages (and higher) so there will not be any debug either.
The last target Console is the one where debug mesages should be looged to. But as I see it you didn't set layout of the message. Try to look at this documentation. It says that layout is a required field.
Also I would suggest you temporarily set additional File target and set it to accept debug messages.
For anyone else who has this issue, an answer at a similar question just saved me: https://stackoverflow.com/a/8881521/3959735
If you are using a separate NLog.config file, make sure it's set to "copy always" via its file properties. Alternatively, you can include the NLog configuration section in your main App.config.
I think I might have caused this issue for myself either by trying to copy an NLog configuration file from another project manually; or because when adding NLog to my project I got a permissions error (of which I cannot remember any specific details) – just passing on this information in case it helps anyone diagnose their own issue.
Add nlog.config file to your project
Example of my config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<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="${basedir}/Logs/${date:format=yyyy-MM-dd}_log.txt" />
<target name="logconsole" xsi:type="Console" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logconsole" />
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
</configuration>