如何通过Logback的SMTPAppender按主机名过滤邮件告警?
解决方案
一、修复依赖缺失问题
报错java.lang.NoClassDefFoundError: org/codehaus/commons/compiler/MultiCookable是因为Janino 3.x版本拆分了依赖模块,仅引入janino包不足以支持表达式解析,需要补充commons-compiler依赖到pom.xml:
<dependency> <groupId>org.codehaus.janino</groupId> <artifactId>janino</artifactId> <version>3.1.8</version> </dependency> <dependency> <groupId>org.codehaus.janino</groupId> <artifactId>commons-compiler</artifactId> <version>3.1.8</version> </dependency>
二、修正Logback XML配置
原配置存在两处语法错误(多余的**符号),同时调整表达式写法确保正确获取主机名:
<appender name="SMTP" class="ch.qos.logback.classic.net.SMTPAppender"> <smtpHost>host</smtpHost> <smtpPort>port</smtpPort> <username>username</username> <password>password</password> <to>email@domain.com</to> <from>no-reply@domain.com</from> <subject>Email Subject</subject> <STARTTLS>false</STARTTLS> <SSL>true</SSL> <layout class="ch.qos.logback.classic.html.HTMLLayout"/> <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker"> <!-- send just ten log entries per email --> <bufferSize>10</bufferSize> </cyclicBufferTracker> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator> <matcher> <Name>hostnameMatcher</Name> <regex>172-\d{1,3}-\d{1,3}-\d{1,3}</regex> </matcher> <!-- 通过日志上下文获取HOSTNAME属性,匹配则拒绝发送邮件 --> <expression>hostnameMatcher.matches(event.getLoggerContext().getProperty("HOSTNAME"))</expression> </evaluator> <OnMismatch>NEUTRAL</OnMismatch> <OnMatch>DENY</OnMatch> </filter> </appender>
若HOSTNAME是通过JVM系统属性传入的,也可将表达式替换为:
<expression>hostnameMatcher.matches(System.getProperty("HOSTNAME"))</expression>
三、备选方案:自定义Java Filter(若XML配置仍异常)
如果上述XML方式无法生效,可实现自定义Filter来过滤特定主机:
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; import java.util.regex.Pattern; public class HostnameFilter extends Filter<ILoggingEvent> { private static final Pattern HOSTNAME_PATTERN = Pattern.compile("172-\\d{1,3}-\\d{1,3}-\\d{1,3}"); @Override public FilterReply decide(ILoggingEvent event) { String hostname = event.getLoggerContext().getProperty("HOSTNAME"); if (hostname != null && HOSTNAME_PATTERN.matcher(hostname).matches()) { // 匹配到目标主机,拒绝发送邮件 return FilterReply.DENY; } // 不匹配则继续后续流程 return FilterReply.NEUTRAL; } }
随后在logback.xml中替换原Filter配置:
<filter class="com.yourcompany.HostnameFilter"/>
内容的提问来源于stack exchange,提问作者Matt Reichard
相关产品推荐
相关产品推荐

