${aspnet-request-posted-body} not returning data - nlog

hi I am trying to use Http target to send the log to an API.
nlog.config:
<targets>
<target name='HTTP'
type='HTTP'
URL='https://localhost:44331/api/logs'
Method='POST'
BatchSize='1'
MaxQueueSize='2147483647'
IgnoreSslErrors='true'
FlushBeforeShutdown='true'
ContentType='application/json'
Accept='application/json'
DefaultConnectionLimit='2'
Expect100Continue='false'
UseNagleAlgorithm='true'
ConnectTimeout='30000'
InMemoryCompression='true'>
<layout type='JsonLayout'>
<attribute name='sourcetype' layout='_json' />
<attribute name='host' layout='${machinename}' />
<attribute name='RequestBody' layout='${aspnet-request-posted-body}' />
<attribute name='event' encode='false'>
<layout type='JsonLayout'>
<attribute name='level' layout='${level:upperCase=true}' />
<attribute name='source' layout='${logger}' />
<attribute name='thread' layout='${threadid}' />
<attribute name='message' layout='${message}' />
<attribute name='utc' layout='${date:universalTime=true:format=yyyy-MM-dd HH\:mm\:ss.fff}' />
</layout>
</attribute>
</layout>
</target>
I got every attribute I added except for RequestBody.
Also logging to file and database is working fine as well as
http it is being called but without the request body data.
Any thing I am missing?

Probably you're missing the proper setup.
I will list the options:
ASP.NET (non-core)
You need to have the package NLog.Web installed
Then it should work out of the box, but I you have still issues, then force to include NLog.Web like this:
<nlog>
<extensions>
<add assembly="NLog.Web"/>
</extensions>
...
See docs
ASP.NET Core
For ASP.NET Core it depends on the version.
First of all you need the package NLog.Web.AspNetCore installed.
Also add to your config:
<extensions>
<!--enable NLog.Web for ASP.NET Core-->
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
And the Setup need to call NLog.Web.AspNetCore. I would recommend to check: Use NLog in ASP.NET Core application
Make sure you have called .AddNLogWeb(); / .UseNLog() (dependent on the ASP.NET Core version)
Still issues?
Still issues? There could be various other reasons and for now that's guessing. The target you used could choke on the length of the value etc.
I would recommend: Test it with a FileTarget or ConsoleTarget
and as check the internal log! - that will show a good error message if there is something wrong.

I faced the same and solution is in few github issues and thanks to Julian.
1.https://github.com/NLog/NLog.Web/issues/548
FilePath=C:\Users\user\myapp\bin\Debug\netcoreapp3.1\nlog.development.config
2020-07-21 11:05:29.1792 Warn Exception in layout renderer. Exception: System.InvalidOperationException: Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
at Microsoft.AspNetCore.Server.IIS.Core.HttpRequestStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at Microsoft.AspNetCore.Server.IIS.Core.WrappingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.StreamReader.ReadBuffer()
at System.IO.StreamReader.ReadToEnd()
at NLog.Web.LayoutRenderers.AspNetRequestPostedBody.BodyToString(Stream body)
at NLog.Web.LayoutRenderers.AspNetRequestPostedBody.DoAppend(StringBuilder builder, LogEventInfo logEvent)
at NLog.LayoutRenderers.LayoutRenderer.RenderAppendBuilder(LogEventInfo logEvent, StringBuilder builder)
https://github.com/NLog/NLog.Web/pull/549
https://github.com/NLog/NLog.Web/issues/556
Adding below finally fixed the issue.
app.Use(async (context, next) => {
context.Request.EnableBuffering();
await next();
});
to here and Must be before app.UseEndpoints
public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env)

NLog.Web.AspNetCore v5.1 changes ${aspnet-request-posted-body} so it requires middleware to work:
app.UseMiddleware<NLog.Web.NLogRequestPostedBodyMiddleware>();
The middleware will ensure context.Request.EnableBuffering(); is called when necesary, so one doesn't have to call it explictly.
See also: https://github.com/NLog/NLog.Web/wiki/HTTP-Request-Logging

Related

Nlog - Can I set an action when nlog is done writing to a file?

My current .net core nlog WebAPI config. I'm using:
<targets async="true">
Asynchronous target wrapper allows the logger code to execute more
quickly, by queueing messages and processing them in a separate
thread.
https://github.com/nlog/NLog/wiki/AsyncWrapper-target#async-attribute-and-asyncwrapper
<targets async="true">
<target name="jsonfile" xsi:type="File" fileName="/MyAPI${date:format=yyyy-MM-dd HH-mm-ss}.json" >
<layout xsi:type="JsonLayout">
<attribute name="Date" layout="${date:format=O}" />
</layout>
</target>
</targets>
This creates files every second:
MyAPI_2022-12-08 23-06-28.json
How how can I let nlog do something (f.ex. change the name or move it to another folder) when nlog is done writing to the file? I have a system (Splunk Universal Forwarder) that picks up the logs and I don't want it to pick up the file while it's being written to.
Thanks! :-)

C# - log4net rollover on date, size, and application relaunch

I'm working on a wpf application that uses log4net. It currently logs to a single file and only rolls over when it grows too large. I am trying to modify this so that it grows over when the file grows too large, when the date changes, or when the application is relaunched.
I am trying to get output as close to the following as possible
App_2017-07-06.0.txt //First launch on 2017-07-06
App_2017-07-06.1.txt //Rollover due to size limit
App_2017-07-06.2.txt //Application relaunch
App_2017-07-06.3.txt //Rollover due to size limit
App_2017-07-07.0.txt //Rollover due to date change
App_2017-07-07.1.txt //Rollover due to size limit
App_2017-07-07.2.txt //Application relaunch - Currently Logging File
From what I understand from the documentation, The rolling style can be set to "compostite" to capture date and size or it can be set to "once" to capture application relaunches. It doesn't seem to have a way to do all 3: http://logging.apache.org/log4net/release/sdk/html/T_log4net_Appender_RollingFileAppender_RollingMode.htm
I got it to the point where everything looks correct and works except the application relaunch overwrites a pre existing file (I imagine because of the appendToFile property). I just cant seem to get it working the way I need to and I can't find any answers in the documentation.
This question seems to be trying to achieve a similar goal, but did not solve my problem:
How do I force a rollover at application startup with Log4net RolloverFileAppender?
Am I missing something? Is it just not possible to do this with log4net?
My current configuration
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="Log\App.txt" />
<appendToFile value="false" />
<rollingStyle value="Composite" />
<maximumFileSize value="10KB" />
<maxSizeRollBackups value="-1" />
<staticLogFileName value="false" />
<preserveLogFileNameExtension value="true" />
<countDirection value="1" />
<lockingModel type="log4net.Appender.RollingFileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level User = %username Class = %property{ClassName} Method = %property{MethodName}%newlineMessage - %message%newline%exception%newline***************************************" />
</layout>
</appender>
My current output
App_2017-07-06.0.txt //First launch on 2017-07-06
App_2017-07-06.1.txt //Rollover due to size limit
App_2017-07-06.1.txt //Application relaunch - overwrites pre-existing file
App_2017-07-06.2.txt //Rollover due to size limit
App_2017-07-07.0.txt //Rollover due to date change
App_2017-07-07.1.txt //Rollover due to size limit
App_2017-07-07.1.txt //Application relaunch - overwrites pre-existing file - Currently logging file
As far as I know log4net copies the log file to xxxx.{number}.txt when it rolls over to the next file. So your first App_2017-07-06.1.txt was never created and is still called App_2017-07-06.txt when the application restarts. You have configured so App_2017-07-06.txt will be overridden and your first App_2017-07-06.1.txt was never created.
You can configure <appendToFile value="true" /> to not override the existing file.

Mule RegistrationException

So this one makes me wonder. I have a Mule integration with a couple of flows in it and they all work nice. Except for the last one.
If I end that one in a file endpoint, it works as expected. But if I end it in my WS POST service.. I get an error complaining about multiple JAXB contexts.
I have multiple JAXB contexts but as said they work fine if I'm not trying to post my JSON to that REST service.
And somehow, I can't see that my HTTP endpoint has anything to do with JAXB either so I guess it's a misguiding error?
But then, what is wrong with my HTTP endpoint, I use it as inbound in the other flows and also tried to create an entirely new one for this particular flow, but still this nagging about JAXB.
<http:request-config name="WS" host="127.0.0.1" port="81" doc:name="HTTP Request Configuration" basePath="WSService"/>
<http:request-config name="MQService" host="127.0.0.1" port="82" doc:name="HTTP Request Configuration" />
<mulexml:jaxb-context name="JAXB_A" packageNames="se.razorlib.SystemAProduct" doc:name="JAXB Context"/>
<mulexml:jaxb-context name="JAXB_B" packageNames="se.razorlib.SystemAPurchase" doc:name="JAXB Context"/>
<mulexml:jaxb-context name="JAXB_C" packageNames="se.razorlib.SystemAOrder" doc:name="JAXB Context"/>
<context:property-placeholder location="razorlib.properties"/>
<flow name="ProductToSystemA">
....
<http:request config-ref="WS" path="Product/REST/GetProduct/{id}/{index}" method="GET" doc:name="WS">
<http:request-builder>
<http:uri-param paramName="id" value="${WS.id}"/>
<http:uri-param paramName="index" value="1"/>
</http:request-builder>
</http:request>
.....
</flow>
<flow name="PurchaseToSystemA">
.....
</flow>
.....
and this particular flow
<flow name="PurchaseDeliver">
<file:inbound-endpoint path="C:\temp\fileIn" responseTimeout="10000" doc:name="FileIn"/>
<mulexml:jaxb-xml-to-object-transformer returnClass="se.razorlib.SystemAPurchase.Header" encoding="UTF-16" jaxbContext-ref="JAXB_B" doc:name="XML to JAXB Object"/>
<custom-transformer returnClass="java.util.List" encoding="utf-16" class="se.razorlib.Transformer.Map2ZZPurchase" doc:name="Map2ZZ"/>
<json:object-to-json-transformer encoding="UTF-16" doc:name="Object to JSON"/>
<logger message="'Payload ' #[payload]" level="INFO" doc:name="Logger"/>
<http:request config-ref="WS" path="PurchaseSvc/REST/Deliver/{id}" method="POST" doc:name="WSDeliver">
<http:request-builder>
<http:uri-param paramName="id" value="${WS.id}"/>
</http:request-builder>
</http:request>
<!-- <file:outbound-endpoint path="C:\temp\fileOut" responseTimeout="10000" doc:name="File" outputPattern="inkop2ZZ-#[function:dateStamp].json" mimeType="text/json" encoding="UTF-8"/> -->
<catch-exception-strategy doc:name="Catch Exception Strategy">
<logger message="Oh no!!" level="INFO" doc:name="Logger"/>
<file:outbound-endpoint path="C:\temp\fileError" responseTimeout="10000" doc:name="File" outputPattern="error-inkop2ZZ-#[function:dateStamp].xml" mimeType="text/xml" encoding="UTF-8"/>
</catch-exception-strategy>
</flow>
The error I get is this one:
Root Exception stack trace:
org.mule.api.registry.RegistrationException: More than one object of type class javax.xml.bind.JAXBContext registered but only one expected.
Regards
I have seen a similar scenario's, this might be because of Multiple jaxb-context. Resolved by placing all the packages in one Context
<mulexml:jaxb-context name="JaxbContext" packageNames="se.razorlib.SystemAProduct:se.razorlib.SystemAPurchase:se.razorlib.SystemAOrder"/>
In flow
<mulexml:jaxb-xml-to-object-transformer returnClass="se.razorlib.SystemAPurchase.Header" encoding="UTF-16" jaxbContext-ref="JaxbContext" doc:name="XML to JAXB Object"/>
Hope this helps.
First I would not be surprised that the file endpoint gave no error. The file doesn't care what it gets. It just wants ones and zeros. I somewhat agree with the answer above but I think you only need to reference the package for the three Java bindings.
<mulexml:jaxb-context name="myJaxb" packageNames="se.razorlib"/>
You are defining the context for JAXB transformations. The package says it all.

NLog 3.1.0 event context does not work

This is not so much as a question as it is a warning, and a bit of a rant.
I have the following NLog configuration file:
<?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">
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<target xsi:type="File" name="f" fileName="${basedir}/logs/NLog_${shortdate}.log"
layout="${date} ${uppercase:${level}} ${message}" />
<target xsi:type="File" name="eventFile" fileName="${basedir}/logs/EventFile_${shortdate}.log"
layout="${date} ${uppercase:${level}} The answer is ${event-context:item=Universe}" />
</targets>
<rules>
<logger name="MyLogger" minlevel="Trace" writeTo="f" />
<logger name="EventLogger" minlevel="Debug" writeTo="eventFile" />
</rules>
</nlog>
I am using the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NLog;
using NLog.Config;
using NLog.Targets;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
Logger eventLogger = LogManager.GetLogger("EventLogger");
LogEventInfo eventInfo = new LogEventInfo(LogLevel.Debug, "EventLogger", "message");
eventInfo.Properties["Universe"] = 42;
eventLogger.Debug(eventInfo);
}
catch (Exception ex)
{
int a = 1;
}
int b = 1;
}
}
}
I used NuGet to download NLog for this application. It gave me NLog version 3.1.0.0. When I run this application, the exception handler is invoked, and the inner exception complains that a dictionary has been modified and therefore can no longer be enumerated.
Earlier, I had downloaded NLog 3.0.0.0 from another source. I replaced the 3.1.0.0 reference in my application with a reference to the 3.0.0.0 version, and the exception did not occur.
I am a brand new user of NLog, and this is the second serious bug I have found. The first one was that if a log is created with a log level of "Off", which is perfectly legal, an index out of range exception is thrown. This is because the integer value of an enumeration of log levels for "Off" is 6, and that number is used as an index into an array that only has six elements (thus, its highest index is 5).
I realize that NLog is an open-source project and thus does not have guarantees, but given its popularity, I would have expected that there would be much better test procedures in place than there seem to be.
RobR

How do I enable logging in RhinoETL process?

I have nearly completed my first ETL process that uses Rhino ETL, and I've been able to figure out the way to use the API by referring to the tests.
Great. I have data moving through the pipeline and being written to the db.
However I can't seem to figure out how to enable logging.
the log4net assemblies are there, the log4net object is being created
the WithLoggingMixin class seems to be doing its thing (although I must admit I'm a bit fuzzy on exactly what that is)
in the log4net.config file I have a follingFileAppender set up, and it contains the following:
But no log file is created. When I make a call to Debug() in my code it doesn't do anything because log.IsDebugEnabled is false.
What am I missing?
In Rhino Etl 1.2.3, I was able to get logging to the console by adding the following to items the configuration section of the program's app.config file:
<configSections>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging">
<arg key="level" value="DEBUG" />
<arg key="showLogName" value="true" />
<arg key="showDataTime" value="true" />
<arg key="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:fff" />
</factoryAdapter>
</logging>
</common>
To log to destinations other than the console, the Common.Logging documentation has information on how to wire up log4net.
Okay. I dug through the [log4net documentation][1] and figured out a way to do it.
First of all I moved the log4net config into the App.config file (in a log4net section) and then executed
log4net.Config.XmlConfigurator.Configure();
during initialization. Now it works.
[1]: http://logging.apache.org/log4net/release/manual/configuration.html#.config Files "Apache log4net documentation"

Resources