Dockerized project cannot connect to elastic - c#

I have a docker compose file containing elasticsearch and my project. When I tried to start the project, elasticsearch couldn't register, I didn't know where I was doing wrong, can you help?
the codes i wrote
https://github.com/bayramerenn/LogingInfra
nlog.Development.config
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<extensions>
<add assembly="NLog.Targets.ElasticSearch"></add>
</extensions>
<targets>
<target name="elastic" xsi:type="BufferingWrapper" flushTimeout="5000">
<target xsi:type="ElasticSearch"
uri="${configsetting:item=ElasticUrl}"
index="Development"/>
</target>
</targets>
<rules>
<!--All logs, including from Microsoft-->
<!--<logger name="*" minlevel="Trace" writeTo="allfile" ></logger>
<logger name="*" minlevel="Trace" writeTo="ownFile-web" ></logger>
<logger name="*" minlevel="Trace" writeTo="database" ></logger>-->
<logger name="*" minlevel="Trace" writeTo="elastic" ></logger>
</rules>
nlog.Production.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">
<extensions>
<add assembly="NLog.Targets.ElasticSearch"></add>
</extensions>
<targets>
<target name="elastic" xsi:type="BufferingWrapper" flushTimeout="5000">
<target xsi:type="ElasticSearch"
uri="${configsetting:item=ElasticUrl}"
index="Production"/>
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="elastic" ></logger>
</rules>
</nlog>
appsettings.Development.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ElasticUrl": "http://localhost:9200/"
}
appsettings.Production.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ElasticUrl": "http://elasticsearch:9200/"
}
docker-compose.yml
version: "3.8"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
container_name: elasticsearch
restart: always
ports:
- 9200:9200
volumes:
- elasticsearch_volume:/usr/share/elasticsearch/data
environment:
- xpack.monitoring.enabled=true
- xpack.watcher.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.type=single-node
networks:
- nlognet
kibana:
image: docker.elastic.co/kibana/kibana:7.6.2
container_name: kibana
restart: always
ports:
- 5601:5601
depends_on:
- elasticsearch
environment:
- ELASTICSEARCH_URL=http://elasticsearch:9200/
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200/
networks:
- nlognet
nlog.api:
image: nlog_api
depends_on:
- elasticsearch
- kibana
build:
context: .
dockerfile: NLogElastic/Dockerfile
container_name: nlog.api
environment:
- ASPNETCORE_ENVIRONMENT=Production
ports:
- "5005:80"
networks:
- nlognet
volumes:
elasticsearch_volume:
networks:
nlognet:
driver: bridge

Related

NLog : How to conditional select target based on env variable

I would like to define 2 targets (typically file target on Devops and UDP locally) in nlog and choose them dynamically based on location. Motivation for this is to use different targets when running locally and running on Devops.
There are a number of articles on how to do this using C# code, but I was wondering if it is possible to do this directly in the config file.
In Pseudo Code I am looking for something like this in my rules section:
<rules>
if(Env==DEVOPS)
<logger name="*" minlevel="Info" writeTo="file" />
else
<logger name="*" minlevel="Trace" writeTo="udp" />
end
</rules>
I suggest that you use the method described here:
<nlog>
<variable name="myFileLevel" value="Off" />
<variable name="myUdpLevel" value="Off" />
<rules>
<logger name="*" minLevel="${var:myFileLevel}" writeTo="file" />
<logger name="*" minLevel="${var:myUdpLevel}" writeTo="udp" />
</rules>
</nlog>
And then do this at runtime:
if (DevOps)
{
LogManager.Configuration.Variables["myFileLevel"] = "Debug";
}
else
{
LogManager.Configuration.Variables["myUdpLevel"] = "Trace";
}
LogManager.ReconfigExistingLoggers();
See also: https://github.com/nlog/NLog/wiki/Filtering-log-messages#semi-dynamic-routing-rules
Same configuration as in Rolf Kristensen's answer above, just in json (in case you want to make it a part of the applications' appsettings.json):
"variables": {
"logConsoleLevel": "Off",
"logFileLevel": "Off"
},
"rules": [
{
"logger": "*",
"minLevel": "${var:logConsoleLevel}",
"writeTo": "coloredConsole"
},
{
"logger": "*",
"minLevel": "${var:logFileLevel}",
"writeTo": "logfile"
}
]

CKFinder NLog Isn't Logging

I am using CKFinder in ASP.NET. It has been working but has recently stopped (uploads specifically). While trying to track down the issues, I noticed no logs are being written.
In my web.config, I have enabled verbose logging for ckfinder:
enableVerboseLogging="true"
Here is my NLog.config file (which I am not familiar with; we use log4net). Other traces are being written via NLog, however, so I think this is correct.
<nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets async="true">
<target xsi:type="File" name="logFile" fileName="${basedir}/App_Data/logs/ckfinder.log"
archiveFileName="${basedir}/App_Data/logs/archives/ckfinder.{#}.log" archiveEvery="Day" archiveNumbering="Rolling" maxArchiveFiles="5" concurrentWrites="true" keepFileOpen="false"
layout="${level} | ${logger} | ${longdate} | ${message}${onexception: | ${exception:format=ToString,StackTrace:maxInnerExceptionLevel=10}}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>
I was forgetting this line from Startup.Configuration:
LoggerManager.LoggerAdapterFactory = new NLogLoggerAdapterFactory();

NLog not sending to papertrail once deployed to an EC2

When deploying to my EC2 NLog no longer seems to be working correctly. When deployed locally, I have no issues logging the chat. On the other hand, it's rapidly writing to it's internal log and ignoring the value of if it should write to it's internal log at all.
I've tried switching the protocol type to be used from TCP to UDP, which stops it from writing errors (but also does not allow it to connect to PaperTrail which was the point). I've also tried turning off internal logging, which also does not work. Recopying over my NLog.config, as well as going through the initial tutorial multiple times. I've also checked my firewall settings for ports, the EC2 security group settings for ports, and the application permissions on the firewall.
NLog version: "4.6.2"
Platform:.Net 4.5
Current NLog config (xml or C#, if relevant)
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="false" internalLogFile="c:\temp\nlog-internal.log">
<extensions>
<add assembly="NLog.Targets.Syslog" />
</extensions>
<targets>
<target name="syslog" type="Syslog">
<messageCreation>
<facility>Local7</facility>
<rfc5424 hostname="${machinename}-Ragnarok" appName="ChatServer-Ragnarok" />
</messageCreation>
<messageSend>
<protocol>TCP</protocol>
<tcp>
<server>logs.papertrailapp.com</server>
<port>REDACTED</port>
<tls>
<enabled>true</enabled>
</tls>
</tcp>
</messageSend>
</target>
<target name="logfile" xsi:type="File" fileName="file.txt" />
<target name="logconsole" xsi:type="Console" />
</targets>
<rules>
<logger name="*" minLevel="Trace" appendTo="syslog" />
<logger name="*" minlevel="Info" writeTo="logconsole" />
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
The actual error is as follows (It's repeated every few seconds in the logs):
2019-04-15 13:35:22.3986 Warn SendAsync failed Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at NLog.Targets.Syslog.MessageSend.SocketInitializationForWindows.KeepAliveConfigurationIsUpToDate(KeepAliveConfig keepAliveConfig)
at NLog.Targets.Syslog.MessageSend.SocketInitializationForWindows.ApplyKeepAliveValues(Socket socket, KeepAliveConfig keepAliveConfig)
at NLog.Targets.Syslog.MessageSend.SocketInitialization.SetKeepAlive(Socket socket, KeepAliveConfig keepAliveConfig)
at NLog.Targets.Syslog.MessageSend.Tcp.Init()
at NLog.Targets.Syslog.MessageSend.MessageTransmitter.b__21_0(Task _)
at NLog.Targets.Syslog.Extensions.TaskExtensions.<>c__DisplayClass0_01.<Then>b__0(Task t)
at System.Threading.Tasks.ContinuationResultTaskFromTask1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
Does anyone have any ideas on how to get this to work / why it's not working when deployed?
Just a stopgap for now just to add the following to the config, which allows it to not crash on the "Keep Alive"
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="false" internalLogFile="c:\temp\nlog-internal.log">
<extensions>
<add assembly="NLog.Targets.Syslog" />
</extensions>
<targets>
<target name="syslog" type="Syslog">
<messageCreation>
<facility>Local7</facility>
<rfc5424 hostname="${machinename}-Ragnarok" appName="ChatServer-Ragnarok" />
</messageCreation>
<messageSend>
<protocol>TCP</protocol>
<tcp>
<server>logs.papertrailapp.com</server>
<port>REDACTED</port>
<tls>
<enabled>true</enabled>
</tls>
<keepAlive>
<enabled>false</enabled>
<time>15</time>
</keepAlive>
</tcp>
</messageSend>
</target>
<target name="logfile" xsi:type="File" fileName="file.txt" />
<target name="logconsole" xsi:type="Console" />
</targets>
<rules>
<logger name="*" minLevel="Trace" appendTo="syslog" />
<logger name="*" minlevel="Info" writeTo="logconsole" />
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
The code I've added in question is the following:
<keepAlive>
<enabled>false</enabled>
<time>15</time>
</keepAlive>
Edit:
A fix was just pushed to NLog.Targets.Syslog's git which fixed this issue for me entirely.
https://github.com/luigiberrettini/NLog.Targets.Syslog/pull/183

How to make NLog thread-safely write to separate file target at runtime?

I have an application which runs many threads (~50), every thread acquires a payment with lock to be processed from a database, and then processes it.
However, 50 threads make logs unreadable, mixed up and of enormous filesize.
Now, I want to make NLog write to a separate file for every payment ID, so that all history on payment processment is stored in one file.
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">
<targets>
<target name="file" xsi:type="AsyncWrapper" queueLimit="10000" overflowAction="Discard">
<target name="f" xsi:type="File" fileName="C:\LogFiles\Immediate\${shortdate}.server.log" layout="${longdate}|${level}|${processid}|${threadid}|${level:upperCase=true}|${callsite:className=false}|${message}" encoding="utf-8"/>
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file"/>
</rules>
</nlog>
My code now:
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); // "2017-07-20.log"
while (!_cancellationToken.IsCancellationRequested)
{
using (var session = _connectionFactory.GetSession())
{
AcquirePaymentWithUpdlockReadpast(session,
Logger, // "2017-07-20.log"
payment => {
if (payment == null)
return;
Logger.Debug($"Payment {payment.Id} has been acquired for processment");
ProcessPayment(session, Logger, payment); // "2017-07-20.log"
});
}
Thread.Sleep(50);
}
What I expect it to be:
private static readonly ILogger GeneralLogger = LogManager.GetCurrentClassLogger(); // "2017-07-20.General.log"
while (!_cancellationToken.IsCancellationRequested)
{
using (var session = _connectionFactory.GetSession())
{
AcquirePaymentWithUpdlockReadpast(session,
GeneralLogger, // "2017-07-20.General.log"
payment => {
if (payment == null)
return;
var paymentLogger = LogManager.GetCurrentClassLogger();
paymentLogger.FileName = $"Payment-{payment.Id}.log"; // <-- I want this.
paymentLogger.Debug($"Payment has been acquired for processment");
ProcessPayment(session, paymentLogger, payment); // "2017-07-20.Payment-123.log"
});
}
Thread.Sleep(50);
}
I have found some solutions which use LogManager.Configuration, but it doesn't seem to be thread-safe.
Maybe something like this:
<?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="file" xsi:type="AsyncWrapper" queueLimit="10000" overflowAction="Discard">
<target name="f" xsi:type="File" fileName="C:\LogFiles\Immediate\${shortdate}.server.log" layout="${longdate}|${level}|${processid}|${threadid}|${level:upperCase=true}|${callsite:className=false}|${message}" encoding="utf-8"/>
</target>
<target name="paymentFile" xsi:type="AsyncWrapper" queueLimit="10000" overflowAction="Discard">
<target name="p" xsi:type="File" fileName="C:\LogFiles\Immediate\Payment-${event-properties:PaymentID:whenEmpty=0}.log" layout="${longdate}|${level}|${processid}|${threadid}|${level:upperCase=true}|${callsite:className=false}|${message}" encoding="utf-8"/>
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="paymentFile">
<condition="'${event-properties:PaymentID:whenEmpty=0}'!='0'" action="LogFinal" />
</logger>
<logger name="*" minlevel="Debug" writeTo="file"/>
</rules>
</nlog>
Then you can do the logging like this (Can be improved with NLog-Fluent):
LogEventInfo theEvent = new LogEventInfo(LogLevel.Debug, $"Payment has been acquired for processment");
theEvent.Properties["PaymentID"] = payment.Id;
Logger.Debug(theEvent);
Alternative solution could be like this:
var paymentLogger = LogManager.GetLogger($"Payment-{payment.Id}");
paymentLogger.Debug($"Payment has been acquired for processment")
And then change the logger-filter to this:
<logger name="Payment-*" minlevel="Debug" writeTo="paymentFile" />
And then change paymentFile filename to this:
fileName="C:\LogFiles\Immediate\{logger}.log"
Thanks to Rolf Kristensen's answer, I have used the second approach, but have found a similar, but shorter solution which uses name property:
<?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="all" xsi:type="AsyncWrapper" queueLimit="10000" overflowAction="Discard">
<target name="f" xsi:type="File" fileName="C:\LogFiles\${shortdate}.All.log" layout="${longdate}|${level}|${processid}|${threadid}|${level:upperCase=true}|${callsite:className=false}|${message}" encoding="utf-8"/>
</target>
<target name="perLoggerName" xsi:type="AsyncWrapper" queueLimit="10000" overflowAction="Discard">
<target name="f" xsi:type="File" fileName="C:\LogFiles\${shortdate}.${logger}.log" layout="${longdate}|${level}|${processid}|${threadid}|${level:upperCase=true}|${callsite:className=false}|${message}" encoding="utf-8"/>
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="all"/>
<logger name="Document-*" minlevel="Debug" writeTo="perLoggerName"/>
<logger name="Job-*" minlevel="Debug" writeTo="perLoggerName"/>
</rules>
</nlog>

Send ALL messages to one log file, and RavenDB logs to a different log file

This sounds trivial, but I somehow cannot manage to do it. I have the below 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" throwExceptions="true">
<variable name="logDirectory" value="${basedir}/App_Data/logs"/>
<targets>
<target name="file" xsi:type="AsyncWrapper">
<target xsi:type="File" name="f1" fileName="${logDirectory}\log1.txt" layout="${longdate} ${callsite} ${level} ${message} (File 1)"/>
</target>
<target xsi:type="File" name="fileGeneral" fileName="${logDirectory}\log_${shortdate}.txt" >
<layout xsi:type="Log4JXmlEventLayout"/>
</target>
<target xsi:type="File" name="fileRaven" fileName="${logDirectory}\raven_${shortdate}.txt" >
<layout xsi:type="Log4JXmlEventLayout"/>
</target>
</targets>
<rules>
<logger name="Raven.*" minlevel="Trace" writeTo="fileRaven"></logger>
<logger name="*" minlevel="Trace" writeTo="fileGeneral"></logger>
</rules>
</nlog>
This is ending up with Raven + ALL logs to 'log_[date].txt', and another copy of just RavenDB logs in 'raven_[date].txt'. How should this be done?
<logger name="Raven.*" minlevel="Trace" writeTo="fileRaven" final="true"></logger>
Where final="true" means that no more rules for Raven.* will be executed will do what you are asking (if I understood you correctly).
Unfortunately this is not possible.
The reason is that the loggers are evaluated from top to bottom, the first one matching will be used, and does below will not be evaluated.
In you case this means that when logging anything Raven related the first logger will be used and stops the flow.

Categories