Log4j2 not able to send mail - java

I have this controller class and log4j2 .
But I am not able to receive email in myemail#gmail.com.
What I am doing wrong? I am using latest version of spring boot.
// Logger statement in controller class
LOGGER.info(" send email : " + EMAIL);
LOGGER.error(" send email : " + EMAIL);
LOGGER.warn(" send email : " + EMAIL);
This is my log4j2.xml file under resources folder
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="omnichannel">
<Properties>
<Property name="LOG_CONSOLE">
%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%5p} ${hostName} --- [%15.15t] %-40.40c{1.} : %m%n%ex
</Property>
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_CONSOLE}"/>
</Console>
<SMTP name="SMTPAppender"
from="myemail#gmail.com"
to="myemail#gmail.com"
subject="hi"
smtpHost="smtp.gmail.com"
smtpPort="587"
smtpProtocol="smtp"
smtpUsername="myemail#gmail.com"
smtpPassword="mypassword"
bufferSize="1"
smtpDebug="false">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<HTMLLayout charset="UTF-8" title="Error Logs" contentType="text/html"/>
</SMTP>
<Async name="AsyncSMTP" bufferSize="1">
<AppenderRef ref="SMTPAppender"/>
</Async>
</Appenders>
<Loggers>
<Logger name="com.satish.central.docs.person.web.controller" level="debug" additivity="false">
<AppenderRef ref="ConsoleAppender" />
<!--<AppenderRef ref="AsyncSMTP" />-->
</Logger>
<Root level="info">
<AppenderRef ref="ConsoleAppender" />
<!--<AppenderRef ref="AsyncSMTP" />-->
</Root>
</Loggers>
</Configuration>

Your example shows 3 log events with a comment that they are generated in the controller class. Your logging configuration shows that the Logger associated with the Controller is being routed to the ConsoleAppender. Your example above has nothing routed to the SmtpAppender.

Related

Splunk HTTP Event Collector Log4j2 SpringBoot unable to send data

I tried integrating my SpringBoot Application with Splunk, but could not get the logs. There is no Error in Console. Kindly help
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout
pattern="%style{%d{ISO8601}} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{10}}{bright,yellow}: %msg%n%throwable" />
</Console>
<SplunkHttp
name="student-service-token"
url="https://prd-p-wyalk.splunkcloud.com:8080"
token="*********************************"
host="localhost"
index="student_idex_api"
type="raw"
source="http-event-logs"
sourcetype="log4j"
messageFormat="text"
disableCertificateValidation="true">
<PatternLayout pattern="%m" />
</SplunkHttp>
</Appenders>
<Loggers>
<!-- LOG everything at INFO level -->
<Root level="info">
<AppenderRef ref="console" />
<AppenderRef ref="splunkhttp" />
</Root>
</Loggers>
</Configuration>

log4j2 logger config level does not override root logger level

According to log4j documentation, if I define a logger config for package com.a.b.c with level ERROR with root logger level set to DEBUG, only ERROR logs should come from classes in com.a.b.c while other classes should print DEBUG logs. Therefore I have the below log4j2-test.xml.
However, in my case INFO level logs from classes in com.a.b.c are still being printed. Did I misunderstand anything? What should I do to make classes in com.a.b.c print ERROR logs while all other classes print INFO logs?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="PropertiesConfig" packages="org.apache.logging.log4j.test">
<Properties>
<Property name="basePath">target/</Property>
</Properties>
<ThresholdFilter level="trace"/>
<Appenders>
<Console name="consoleLogger" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd-MM-yyyy HH:mm:ss.SSS} %style{[%t]}{magenta} %highlight{%-5level}{TRACE=cyan, DEBUG=green, INFO=yellow, WARN=blue, ERROR=red} [%-60.60c] : %m%n" />
</Console>
<File name="fileLogger" fileName="${basePath}app.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %level [%t] [%c] [%M] [%l] : %msg%n" />
</File>
</Appenders>
<Loggers>
<Root level="INFO" >
<AppenderRef ref="consoleLogger" />
<AppenderRef ref="fileLogger" />
</Root>
<Logger name="com.a.b.c" level="ERROR" additivity="false">
<AppenderRef ref="consoleLogger" />
<AppenderRef ref="fileLogger" />
</Logger>
</Loggers>
</Configuration>
I figured this out. The class in question is (weirdly) not using its own class name when getting the logger. Typically it is LoggerFactory.getLogger(com.a.b.c) but in my case the class is doing LoggerFactory.getLogger(java.io.Console), thus our logger config <Logger name="com.a.b.c" level="ERROR" additivity="false"> will not apply to logs coming from this class. I had to add a logger config for the class java.io.Console.

log4j2 logging to console only

I have a maven web project which requires logging.
I decided to use log4j2 for that purpose and added the required entries in the pom.xml file
Then I created the log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<RollingFile name="RollingFile" fileName="${logs.path}/text.log"
filePattern="${logs.path}/%d{YYYYMMdd}-text.%i.log">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" />
<Policies>
<SizeBasedTriggeringPolicy size="100 MB" />
</Policies>
<DefaultRolloverStrategy max="20" />
</RollingFile>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} %-5p %c{1}:%L - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="root" level="info" additivity="false">
<appender-ref ref="RollingFile" level="info" />
<appender-ref ref="Console" level="info" />
</Logger>
<Root level="info" additivity="false">
<AppenderRef ref="RollingFile" />
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
I'm starting tomcat with -Dlogs.path="C:\mylogs", where C:\mylogs exists and has public read/write access.
The console logger is working fine, I can see the correct output in my console, the issue is that the file isn't being created, so I have no logfile, everything gets logged to catalina.out only, and the tomcat startup logs don't show errors for log4j.
What am I missing? is there some additional configuration I need to do in order to log to file?
I went through the documentation. You must refer to system properties with sys:, and it seems that tomcat properties are seen as system properties, so I replaced ${logs.path} with ${sys:logs.path} and it worked.
To create a log file with the log4j2 config you first need to define your appender. Here's an example:
<RollingFile name="MGMT"
fileName="${logdir}/mgmt.log"
filePattern="${logdir}/mgmt.%d{yyyy-MM-dd}.log">
<PatternLayout pattern="${layout}"/>
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy>
<Delete basePath="${logdir}" maxDepth="1">
<IfFileName glob="mgmt.*.log" />
<IfAccumulatedFileCount exceeds="10" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
Afterwards you just need to define a logger that will use it:
<Logger name="the package or name that is displayed in the log line"
level="ALL"
additivity="false">
<AppenderRef ref="MGMT"/>
</Logger>
If you have a log that has com.company.test as package set that package as name for the logger. It's important that they match.
The field additivity will define if you want to pass the catched log to its parent ( true ) or just let this logger handle it ( false )
EDIT:
your config file might need this:
<Configuration status="info">
<Properties>
<Property name="logdir">${sys:catalina.base}/logs</Property>
<Property name="layout">%d [%t] %-5p %c- %m%n</Property>
</Properties>
<Appenders>
If you don't want to use this you have to define the path static like <RollingFile name="MGMT"
fileName="C:\path\file.log"

Change log4j2 log level from string to int

within the log4j2 configuration I am trying to convert the loglevels from string to an int.
Following the directions located in log4j2 Patterns section
image snippet of example log4j2 pattern mapping
Following the example above I created in log4j2.xml config:
<JMS name="jmsQueue"
destinationBindingName="${sys:env}.logging"
factoryName="org.apache.activemq.jndi.ActiveMQInitialContextFactory"
factoryBindingName="ConnectionFactory"
providerURL="${sys:log4j.providerurl}"
userName="log"
password="log">
<PatternLayout pattern='{"Message":"%m","LogLevel":%level{Debug=1,Info=2,Warn=3,Error=4,Fatal=5,Trace=6},"Type":"middleware","App":"${app_name}","Env":"${sys:env}","data":{"Event_Time":"%d{ISO8601}","Thread":"%t","Class":"%c"}}'/>
</JMS>
The edited PatternLayout I would now expect would replace the string debug,info,warn etc. with the mapped int values of 1,2,3 . .
This is not the case, I still receive string value. If someone could suggest where I am making the mistake I would appreciate it. thank you.
edit:
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<!-- replace > app_name_here_only < with the distinct name of your service. you will use this name to search for within kibana (ex: type:middleware app:<app_name>) -->
<Properties>
<Property name="app_name">middleware_united</Property>
</Properties>
<!-- do not configure below this line -->
<Appenders>
<RollingFile name="file" fileName="${sys:mule.home}${sys:file.separator}logs${sys:file.separator}${app_name}.log" filePattern="${sys:mule.home}${sys:file.separator}logs${sys:file.separator}${app_name}-%i.log">
<PatternLayout pattern="%d [%t] %-5p %c - %m%n"/>
<SizeBasedTriggeringPolicy size="10 MB"/>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<JMS name="jmsQueue" destinationBindingName="${sys:env}.logging" factoryName="org.apache.activemq.jndi.ActiveMQInitialContextFactory" factoryBindingName="ConnectionFactory" providerURL="${sys:log4j.providerurl}" userName="log" password="log">
<PatternLayout pattern='{"Type":"middleware","Env":"${sys:env}","App":"${app_name}","LogLevel":%level{Debug=1,Info=2,Warn=3,Error=4,Fatal=5,Trace=6},"Message":"%m","data":{"Event_Time":"%d{ISO8601}","Thread":"%t","Class":"%c"}}'/>
</JMS>
</Appenders>
<Loggers>
<!-- CXF is used heavily by Mule for web services -->
<AsyncLogger name="org.apache.cxf" level="WARN"/>
<!-- Apache Commons tend to make a lot of noise which can clutter the log-->
<AsyncLogger name="org.apache" level="WARN"/>
<!-- Reduce startup noise -->
<AsyncLogger name="org.springframework.beans.factory" level="WARN"/>
<!-- Mule classes -->
<AsyncLogger name="org.mule" level="INFO"/>
<AsyncLogger name="com.mulesoft" level="INFO"/>
<!-- Reduce DM verbosity -->
<AsyncLogger name="org.jetel" level="WARN"/>
<AsyncLogger name="Tracking" level="WARN"/>
<AsyncRoot level="INFO">
<AppenderRef ref="file"/>
<AppenderRef ref="jmsQueue"/>
</AsyncRoot>
</Loggers>
</Configuration>
I've tested your pattern but it worked well.
Here's my log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout
pattern='{"Type":"middleware","Env":"${sys:env}","App":"${app_name}","LogLevel":%level{Debug=1,Info=2,Warn=3,Error=4,Fatal=5,Trace=6},"Message":"%m","data":{"Event_Time":"%d{ISO8601}","Thread":"%t","Class":"%c"}}'/>
</Console>
</Appenders>
<Loggers>
<Root level="DEBUG">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
And here's the output:
{"Type":"middleware","Env":"${sys:env}","App":"${app_name}","LogLevel":2,"Message":"b","data":{"Event_Time":"2017-03-29T11:28:14,477","Thread":"main","Class":"test.Log4j2"}}

How to log LoggerMarker to specific file only?

I'm trying to achive the following using log4j2:
Log all general content to console, but log MarkerFilter.FILTERED only to a specific file, not to console.
<Configuration>
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Console>
<RollingFile name="FILTERED" fileName="filtered.txt" />
<MarkerFilter marker="FILTERED" onMatch="ACCEPT" onMismatch="DENY"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="all">
<AppenderRef ref="CONSOLE" />
<AppenderRef ref="FILTERED" />
</Root>
</Loggers>
</Configuration>
The following works in general, BUT logs any FILTERED content to console additionally.
But when I remove the <AppenderRef ref="FILTERED" /> form <root> loggers, nothing is logged to the file anymore!
How about using the marker filter on the console appender with a DENY action?
You can set the level on the appender-ref, so you don't need to use a ThresholdFilter for that.
<Configuration status="warn">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<MarkerFilter marker="FILTERED" onMatch="DENY" onMismatch="ACCEPT"/>
</Console>
<RollingFile name="FILTERED" fileName="filtered.txt" />
<MarkerFilter marker="FILTERED" onMatch="ACCEPT" onMismatch="DENY"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="all">
<AppenderRef ref="CONSOLE" level="info" />
<AppenderRef ref="FILTERED" />
</Root>
</Loggers>
</Configuration>

Categories