Nlog / event-properties: how to hint NLog to ignore/skip empty/null properties from the final log entry - nlog

Basically the title itself kinda explains what i'm trying to achieve but in greater detail:
Let's say the one has similar to the following XML setup for the layout:
layout="<log level='${level:lowerCase=True}' time='${longdate:universalTime=true}' myCustomProperty1='${event-properties:item=myCustomProperty1}' myCustomProperty2='${event-properties:item=myCustomProperty2}'>${newline}
...."
Now when myCustomProperty1 is set to let's say 'blah1' but myCustomProperty2 is not added to eventInfo.Properties collection the resulting entry looks like following:
<log level='blah' time='blah' myCustomProperty1='blah1' myCustomProperty2=''>
...
The question is - what can be done (preferably in the config file) to exclude the myCustomProperty2 attribute from finally rendered result so the output looks as following:
<log level='blah' time='blah' myCustomProperty1='blah1'>
...
Here is the gotcha - the same logger is used by multiple threads so i can't simply alter target's layout configuration at the runtime since it may negatively affect the rest of the threads
Thank you in advance for your suggestions.
-K

You could try using When :
<variables>
<variable name="var_myCustomProperty1" value="${when:when=length('${event-properties:item=myCustomProperty1}')>0:Inner= myCustomProperty1="${event-properties:item=myCustomProperty1}"}"/>
<variable name="var_myCustomProperty2" value="${when:when=length('${event-properties:item=myCustomProperty2}')>0:Inner= myCustomProperty2="${event-properties:item=myCustomProperty2}"}"/>
</variables>
<targets>
<target name="test" type="Console" layout="<log level='${level:lowerCase=True}' time='${longdate:universalTime=true}'${var_myCustomProperty1}${var_myCustomProperty2} />" />
</targets>
NLog 4.6 will include the XmlLayout, that might make things easier:
https://github.com/NLog/NLog/pull/2670
Alternative you can use the JsonLayout, if xml-output is not a requirement (renderEmptyObject="false")

Related

JOOQ log with MDC

I use logback MDC to record my application defferent module's log, for example,
// 1. define a logger
org.slf4j.Logger mdclog = org.slf4j.LoggerFactory.getLogger("MY_LOGGER_NAME");
// record trade log
org.slf4j.MDC.put("MY_MDC_KEY", "trade_log");
mdclog.info("This is trade log");
// record goods log
org.slf4j.MDC.put("MY_MDC_KEY", "goods_log");
mdclog.info("This is goods log");
mdc config in logback.xml
<appender name="log_classify" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<Key>login</Key>
<DefaultValue>OTHER</DefaultValue>
</discriminator>
<sift>
<appender name="${MY_MDC_KEY}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<prudent>false</prudent>
<file>${LOG_PATH}/${MY_MDC_KEY}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${MY_MDC_KEY}_%d{yyyy-MM-dd}.log.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
</sift>
</appender>
this generate two log file,
I want to record trade or goods sql log in defferent log file,
so I wonder if JOOQ does support this ?
I find a way to resove my question.
I put my appender into org.jooq.tools.LoggerListener,
<Logger name="org.jooq.tools.LoggerListener" level="DEBUG">
<appender-ref ref="log_classify" />
</Logger>
the jooq sql excute log will be add to defferent file after initialise my MDC.
Actually, I don’t know if this is a good idea
jOOQ doesn't integrate this deeply with loggers out of the box, but you can place your org.slf4j.MDC.put calls in an ExecuteListener prior to running a SQL query, for example in the ExecuteListener::renderEnd event, once the SQL statement is generated, and regex-match the query to make a decision. Alternatively, using a VisitListener, you can make this decision already earlier, trying to match specific tables that may be present in queries.
But quite probably, a much better place to initialise your MDC context would be on the service layer, because your service will probably also know if you're about to run "trade" or "goods" queries.

How to setup cron dynamically via admin in Magento 2

How can I setup cron dynamically in config.xml (custom module) in Magento 2?
Magento2 has a different scheme to merge layout config so you have to create a new file that called crontab.xml under your_custom_module/etc folder. And then you can add your cron config like this one:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="custom_cronjob" instance="YourVenDoerName\CustomModule\Cron\Test" method="execute">
<schedule>* * * * *</schedule>
</job>
</group>
</config>
I will try to make a proposition, not sure if it completely answers your question tho.
So config.xml is setting a default value for your configuration field set in system.xml
So you can have another cron job that runs every minute (* * * * *) and dynamically change this value set in system.xml. Something like this:
public function __construct(
\Magento\Framework\App\Config\ConfigResource\ConfigInterface $resourceConfig)
{
$this->resourceConfig = $resourceConfig;
}
public function execute()
{
$newvalue = $dynamicvalue;
$this->resourceConfig->saveConfig(
'section/group/field',
$newvalue,
\Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
\Magento\Store\Model\Store::DEFAULT_STORE_ID
);
}
So basically two cron jobs.
One that actually does the job you want and one that tweaks it schedule.
Also you can tweak the schedule of it dynamically in an observer, plugin or some other class depending on your needs using the code above.

Spring File Inbound Channel Adapter slows down

I have a spring-integration flow that starts with a file inbound-channel-adapter activated by a transactional poller (tx is handled by atomikos).
The text in the file is processed and the message goes down through the flow until it gets sent to one of the JMS queues (JMS outbound-channel-adapter).
In the middle, there are some database writes within a nested transaction.
The system is meant to run 24/7.
It happens that the single message flow, progressively slows down and when I investigated, I found that the stage that is responsable for the increasing delay is the read from filesystem.
Below, the first portion fo the integration flow:
<logging-channel-adapter id="logger" level="INFO"/>
<transaction-synchronization-factory id="sync-factory">
<after-commit expression="payload.delete()" channel="after-commit"/>
</transaction-synchronization-factory>
<service-activator input-channel="after-commit" output-channel="nullChannel" ref="tx-after-commit-service"/>
<!-- typeb inbound from filesystem -->
<file:inbound-channel-adapter id="typeb-file-inbound-adapter"
auto-startup="${fs.typeb.enabled:true}"
channel="typeb-inbound"
directory="${fs.typeb.directory.in}"
filename-pattern="${fs.typeb.filter.filenamePattern:*}"
prevent-duplicates="${fs.typeb.preventDuplicates:false}" >
<poller id="poller"
fixed-delay="${fs.typeb.polling.millis:1000}"
max-messages-per-poll="${fs.typeb.polling.numMessages:-1}">
<transactional synchronization-factory="sync-factory"/>
</poller>
</file:inbound-channel-adapter>
<channel id="typeb-inbound">
<interceptors>
<wire-tap channel="logger"/>
</interceptors>
</channel>
I read something about issues related to the prevent-duplicates option that stores a list of seen files, but that is not the case because I turned it off.
I don't think that it may be related to the filter (filename-pattern) because the expression I use in my config (*.RCV) is easy to apply and the input folder does not contain a lot of files (less than 100) at the same time.
Still, there is something that gradually makes the read from filesystem slower and slower over time, from a few millis to over 3 seconds within a few days of up-time.
Any hints?
You should remove, or move files after they have been processed; otherwise the whole directory has to be rescanned.
In newer versions, you can use a WatchServiceDirectoryScanner which is more efficient.
But it's still best practice to clean up old files.
Finally I got the solution.
The issue was related to the specific version of Spring I was using (4.3.4) that is affected by a bug I had not discovered yet.
The problem is something about DefaultConversionService and the use of converterCache (look at this for more details https://jira.spring.io/browse/SPR-14929).
Upgrading to a more recent version has resolved.

cc.net: set subject email publisher from trigger name

folks!
I have project in cc.net and this project nay start by 3 ways
Forced (when user click button "force" in web
By project trigger
By sheduler trigger
After build server send mail to stackholders.
And now, i want to add trigger name to mail subject. e.g.
force_Project name ...buikd result
I have tried use variables:
<projectTrigger project="Someproject">
<triggerStatus>Success</triggerStatus>
<variable name="Trigger" value="commit" />
</projectTrigger>
and
<subjectSettings>
<subject buildResult="Broken" value="{Trigger} is broken" />
<subject buildResult="StillBroken" value="{Trigger} is still broken" />
</subjectSettings>
but this way doesnt have positive result.
What kind of way able help me?
You can use the fileLabeller of ccnet.
<tasks>
build tasks...
<fileLabeller>
<labelFilePath>c:\buildstuff\mybuild-label.txt</labelFilePath>
<allowDuplicateSubsequentLabels>false</allowDuplicateSubsequentLabels>
</fileLabeller>
</tasks>
Setup your build task to write to the contents of mybuild-label.txt. I write something like this.
[repo1 rev: 99, repo2 rev: 9999]
This will become part of the subject.

WSO2 - Using get-property() function in Property/Xquery Mediators

Our current service has 7 operations. when writing an outbound xquery "local entry" in wso2, we're trying to retrieve the name of the current operation being executed (how can this be so difficult?).
After reading what i could find in wso2's documentation. it appears as if we need to set up both a Property and an Xquery mediator. supposedly the property mediator would pull the value doing something like get-property('OperationName') and then this would be referenced and passed thru the Xquery mediator.
The other idea was that we needed to define it as a variable in the "Local Registry entry definitions" and than it would be around at all parts of the sequence.
I've tried for 2 days but haven't quite got it.
Please tell me what I'm missing...
Did you try the following xquery sample[1]? I modified the query mediator to get the operation name as follows.
<variable xmlns:ax21="http://services.samples/xsd" xmlns:m0="http://services.samples" name="code" expression="get-property('OperationName')" type="STRING" />
this worked fine. I could see the getQuote in the response message.
[1] http://wso2.org/project/esb/java/4.0.2/docs/samples/advanced_mediation_samples.html#Sample390

Resources