Logger level setting for entire package hierarchy? - logback

Trying this with logback suggests you can't set a level for an entire hierarchy. In other words, you can't specify something like:
<logger name="com.company.app.module.**" level="ERROR"/>
but instead you must specify:
<logger name="com.company.app.module.a" level="ERROR"/>
<logger name="com.company.app.module.a.b" level="ERROR"/>
<logger name="com.company.app.module.a.b.c" level="ERROR"/>
Is there no shorthand for an entire subpackage hierarchy?

I suggest that you read the manual and have a look at the example configuration. You specify a "hierarchy" without wildcard characters. Example
<logger name="com.company.app.module" level="ERROR"/>
<logger name="com.company.app.module.a" level="DEBUG"/>
<logger name="com.company.app.module.a.b" level="INFO"/>
The most specific logger wins. Effective level for com.company.app.module.a.b and below will be INFO. For com.company.app.module.a and below it will be DEBUG, except for com.company.app.module.a.b. And so on...

Related

Logback level element vs. level attribute

The question is simple. In some logback.xmls I see level as an element:
<logger name="mylog" additivity="false">
<level value="DEBUG" />
<appender-ref ref="fileAppender" />
</logger>
But in some it is written as an attribute:
<logger name="mylog" additivity="false" level="debug">
<appender-ref ref="fileAppender" />
</logger>
What is the difference?
Thanks.
In terms of configuring Logback, there is no difference. Both of the following declarations are functionally identical:
<logger name="com.x.y">
<level value="DEBUG"/>
</logger>
<logger name="com.x.y" level="DEBUG" />
Logback's configurer (have a look at ch.qos.logback.core.joran.GenericConfigurator.doConfigure()) creates an identical Logger instance for both of these declarations.
The only difference - when parsing the configuration - is that the first one manifests in more instances of ch.qos.logback.core.joran.event.SaxEvent (start and end events for the logger and for the level) than the second one (start and end events for the logger only).
If you are associating a logger with a specific appender then you'll already be defining a logger element body e.g.
<logger name="com.x.y">
<appender-ref ref="STDOUT"/>
</logger>
In which case defining a level within the element body rather than as an attribute might read better but it really is just a case of developer preference.

Throttling Mule Messages in Mule

I've a polling process in Mule that queries a MySQL database every 30 seconds and sends an email to a recipient. How do I limit to sending just 1 email regardless of the polling cycle whether it be 30 seconds or 15 seconds? I'm open to a counter in the mysql db as well if that's an option.
Thank you.
Write a condition which will only send an email if emailSentFlag == false.
Use choice router to create the condition, and objectstore to hold the emailSentFlag value.
<flow...>
....
<objectstore:retrieve config-ref="ObjectStore__Configuration" key="emailSentFlag" defaultValue-ref="#[false]" targetProperty="flowVars.emailSentFlag" doc:name="retrieve emailSentFlag"/>
<choice doc:name="IsEmailSent?">
<when expression="#[flowVars.emailSentFlag == true]">
<logger level="INFO" doc:name="Log Email Already Sent"/>
</when>
<otherwise>
<smtp:outbound-endpoint host="" user="" password="" to="" from="" subject="test" cc="" bcc="" replyTo="" responseTimeout="10000" ref="Gmail" doc:name="SMTP" connector-ref="Gmail"/>
<objectstore:store config-ref="ObjectStore__Configuration" key="emailSentFlag" value-ref="#[true]" doc:name="store emailSentFlag"/>
</otherwise>
</choice>
</flow>
Also explore the TTL and Persistence feature of objectstore, it could be useful to you.
Cheers
You could use queueing(JMS) for your use case, before sending the "data" to jms would add a delay. You could do this like this
<message-properties-transformer overwrite="true" doc:name="Add DELAY in sending the Response to Queue">
<add-message-property key="Content_Type" value="application/json"/>
<add-message-property key="AMQ_SCHEDULED_DELAY" value="${aupost.retry.timeout}"/>
</message-properties-transformer>
Then add jms consumer to consume the message and send the email accordingly.
Do you have any sample flow to show? You may be able to use collection/message aggregators but looking at flow first would help to suggest.
You can put a vm queue in the end of your flow where the poller picks the data from the sql database.
In other flow, invoke the vm queue using a mule requester as an inbound connector inside a poll then set whatever frequency you want for the mail in the poll frequency using a cron expression or fixed-scheduler. Something like the below code:-
<flow name="db_poll">
<poll doc:name="Poll">
<db:no-operation-selected config-ref="" doc:name="Database"/>
</poll>
<logger message="invoking the database in the poll.. every 30 secs" level="INFO" doc:name="Logger"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="email_queue" connector-ref="VMformail" doc:name="VM"/>
</flow>
<flow name="email_poll">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="1" timeUnit="DAYS"/>
<mulerequester:request-collection resource="VMformail" timeout="100000" doc:name="Mule Requester"/>
</poll>
<logger message="send an email" level="INFO" doc:name="Logger"/>
<smtp:outbound-endpoint host="localhost" responseTimeout="10000" doc:name="SMTP"/>
</flow>

Unable to get flow variable inside exception-strategy

Unable to get flow variable inside exception. In below code I am trying to use centirofilename inside default-exception-strategy. It gives Exception
<set-variable value="#[xpath('//soap/filename/text()').text]"
variableName="centirofilename" doc:name="Variable" />
<default-exception-strategy>
<rollback-transaction exception-pattern="*" /> <!-- [1] -->
<processor-chain>
<logger level="INFO" category="ProTSP Logger"
message="#[centirofilename]" doc:name="Logger" />
</processor-chain>
</default-exception-strategy>
You should be using rollback-exception-strategy instead of the one you're using. The exception strategy you're using is legacy and it's use is not recommended.

Logback fire mail for warnings

I want to configure Logback to fire an email whenever any warnings are found on server.
Right now it is already configure for error level we are getting mails when any error occurred. However same code with changing root level to warn doesn't work.
All sender, receiver, host etc. details are same for which use in error SMTP appender so it's not a server issue. Below is my code.
<appender name="EMAILWARN" class="ch.qos.logback.classic.net.SMTPAppender">
<smtpHost>XXXX</smtpHost>
<to>XXXX</to>
<!-- additional destinations are possible -->
<from>XXXX</from>
<!--
<discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
<key>req.remoteHost</key> visit http://logback.qos.ch/manual/mdc.html#mis for different key values
<defaultValue>default</defaultValue>
</discriminator>
-->
<!-- <subject>RCM-Error: ${HOSTNAME} %X{req.remoteHost} %logger - %m</subject> -->
<subject>Error: ${HOSTNAME} - %m %logger</subject>
<!-- <layout class="ch.qos.logback.classic.PatternLayout"> -->
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%date%X{REMOTE_ADDR}%X{USER_NAME}%level%logger%message</pattern>
</layout>
<cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTrackerImpl">
<bufferSize>20</bufferSize> <!-- set number of log entry to send per email -->
</cyclicBufferTracker>
</appender>
<root level="warning">
<appender-ref ref="EMAILWARN" />
</root>
ch.qos.logback.classic.net.SMTPAppender use an evaluator to trigger the email send procedure. The default one triggers at ERROR level.
So what you need is an evaluator that tiggers at WARN level (and above)
<appender ... class="ch.qos.logback.classic.net.SMTPAppender">
...
<evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
<expression>return level >= WARN;</expression>
</evaluator>
...
</appender>
I'm pretty sure that warning is not a valid logback level.
Try changing your root logger level to warn:
<root level="warn">
<appender-ref ref="EMAILWARN" />
</root>
You can use filters as below, which will select log levels error and warn
<appender name="EMAILWARN" class="ch.qos.logback.classic.net.SMTPAppender">
<!-- rest of your configurations -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>

How to split up the url?

I use Mule Studio.
When I run for example localhost:8080/?first=value1&second=value2 I would like to get two variables and their values:
first: value1
second: value2
I use splitter to delete first '/' like this:
[regex('/(.*?)', message.payload)]
but now I get:
?first=value1&second=value2
You can extract the parameters by using message.inboundProperties['parameter'].
For example:
<logger level="WARN" message="#[message.inboundProperties['first']]" />
<logger level="WARN" message="#[message.inboundProperties['second']]" />
You may extract the parameters in three ways:
Directly from the message's inbound properties
As a Map by accessing the inbound property keyed with http.query.params
Using http:body-to-parameter-map-transformer and have the map conveniently placed on the payload.
Consider running the following flow:
<flow name="mule-configFlow1" doc:name="mule-configFlow1">
<http:inbound-endpoint address="http://localhost:8082/app" />
<http:body-to-parameter-map-transformer />
<logger level="ERROR" />
<logger level="ERROR" message="Payload is: #[payload]" />
<json:object-to-json-transformer />
</flow>