Spring boot - sending emails with Logback

2020-02-23 05:52发布

I am trying to configure Logback to send emails whenever an exception (Logging level: ERROR) occurs. I have not been able to make it work so far so I would like to ask for your help with the configuration.

I have a Spring boot application where some processing is done:

private void foo() {
 try {
  // do something
 } catch (Exception e) {
  log.error("Logging my exception");
 }
}

I would like to trigger an email whenever this error is logged. I followed some tutorials and I added logback.xml and smtp-appender.xml to my resources directory:

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <include resource="smtp-appender.xml" />
    <logger name="com.mycompany" level="DEBUG">
        <appender-ref ref="SMTP" />
    </logger>
</configuration>

smtp-appender.xml

<?xml version="1.0" encoding="UTF-8"?>

<included>
    <appender name="SMTP" class="ch.qos.logback.classic.net.SMTPAppender">
        <smtpHost>xxx</smtpHost>
        <username>user</username>
        <password>password</password>

        <to>test@email.com</to>
        <from>me@email.com</from>
        <subject>testError</subject>

        <layout class="ch.qos.logback.classic.html.HTMLLayout" />

    </appender>
</included>

I have setup local smtpserver on localhost via sendmail. I have also tried with AWS smtp server and Gmail. None of these services worked for me so far.

The problem is that I do not receive any email after the exception and there is literally no output corresponding to the logback (besides the log.error() output, of course) which makes me think that the application does not even know about these config files...

These are my maven dependencies in pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.5.RELEASE</version>
    <relativePath />
    <!-- lookup parent from repository -->
</parent>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20141113</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4</version>
    </dependency>
</dependencies>

Any help would be highly appreciated.

3条回答
Viruses.
2楼-- · 2020-02-23 06:34

Default entry for port in smtpappender is 25, gmail is using authentication for smtp services, and you need use ports 587 for TLS and 465 for SSL.

I would say this might be your problem.

Try to setup mail server on your local machine first without authentication, and try is your appended works. then try to find how to configure it for gmail.

From page http://logback.qos.ch/manual/appenders.html#gmailSTARTTLS

SMTPAppender for Gmail (STARTTLS)

<configuration>   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <smtpHost>smtp.gmail.com</smtpHost>
    <smtpPort>587</smtpPort>
    <STARTTLS>true</STARTTLS>
    <username>YOUR_USERNAME@gmail.com</username>
    <password>YOUR_GMAIL_xPASSWORD</password>

    <to>EMAIL-DESTINATION</to>
    <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
    <from>YOUR_USERNAME@gmail.com</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%date %-5level %logger - %message%n</pattern>
    </layout>       
  </appender>

  <root level="DEBUG">
    <appender-ref ref="EMAIL" />
  </root>  
</configuration>
查看更多
迷人小祖宗
3楼-- · 2020-02-23 06:39

Pls include following (from my working project) on pom.xml & logback.xml in order to get error mail :-

pom.xml

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.4</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.6.4</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4</version>
    </dependency>

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="errMailer" class="ch.qos.logback.classic.net.SMTPAppender">
      <smtpHost>xxx</smtpHost>
      <smtpPort>25</smtpPort>
      <from>me@gmail.com</from>
      <to>you@gmail.com</to>
      <subjectStr>App Err Mail</subjectStr>
      <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
      <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
          <level>ERROR</level>
      </filter>
  </appender>
    <root level="ERROR">
        <appender-ref ref="errMailer" />
    </root>
</configuration>
查看更多
虎瘦雄心在
4楼-- · 2020-02-23 06:40

You have to enable Marker based triggering of email.

include an evaluator in your logback.xml under SMTP appender refer below link

http://logback.qos.ch/manual/appenders.html#OnMarkerEvaluator

then add below logic in your Exception catch block,pass Marker object to logger method if you want to send email like below -

Marker notifyAdmin = MarkerFactory.getMarker("NOTIFY_ADMIN");
logger.error(notifyAdmin,
  "This is a serious an error requiring the admin's attention",
   new Except
ion("Just testing"));

its possible that in some scenario you dont want to send email and only want to log the exception then just dont pass Marker object to logger method.

logger.error("This is a serious an error requiring the admin's attention",
   new Except
ion("Just testing"));
查看更多
登录 后发表回答