Alert Your Error Message Via Slack
Suppose you have a Slack account
Preview

Integration
Add integration

Search & add integration

Add configuration

Select channel

Copy webhook URL & save settings

logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="SLACK" class="io.github.piaozaiguang.logback.LogbackSlackAppender">
<level>ERROR</level>
<endpoint>https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XxxxxXXxXXXxxxxXXXXXxxxX</endpoint>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[${HOSTNAME}][Admin RELEASE] %date %-5level - %logger{0} - %message%n</pattern>
</layout>
</appender>
<!-- Root Logger -->
<root level="ALL">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
<appender-ref ref="SLACK" />
</root>
</configuration>
LogbackSlackAppender.java
package io.github.piaozaiguang.logback;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import ch.qos.logback.core.status.ErrorStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
/**
* Created by piaozaiguang on 2017/4/8.
*/
@Getter
@Setter
@Slf4j
public class LogbackSlackAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
private static final String SLACK_LOGGING = "slack logging response: ";
private static final String SLACK_LOGGING_RESPONSE = SLACK_LOGGING + "{}";
private String endpoint;
private Level level;
private Layout<ILoggingEvent> layout;
@Override
public void start() {
int errors = 0;
if (level == null) {
addStatus(new ErrorStatus("No level set for the appender named \"" + name + "\".", this));
errors++;
}
if (endpoint == null) {
addStatus(new ErrorStatus("No endpoint set for the appender named \"" + name + "\".", this));
errors++;
}
if (layout == null) {
addStatus(new ErrorStatus("No layout set for the appender named \"" + name + "\".", this));
errors++;
}
if (errors == 0) {
super.start();
}
};
@Override
protected void append(ILoggingEvent evt) {
if (!isStarted()) {
return;
}
if (!StringUtils.contains(evt.getMessage(), SLACK_LOGGING)) {
if (evt.getLevel().isGreaterOrEqual(level)) {
Message message = new Message(layout.doLayout(evt));
RestTemplate rt = new RestTemplate();
ResponseEntity<String> response = postMessage(message, rt);
log.debug(SLACK_LOGGING_RESPONSE, response);
}
}
}
protected ResponseEntity<String> postMessage(Message message, RestTemplate rt) {
ResponseEntity<String> response = rt.postForEntity(endpoint, message, String.class);
return response;
}
@Value
static class Message {
private String text;
}
}