使用logback發送郵件
需求:
1、報錯發郵件,定位錯誤位置以盡快解決;(報錯發送郵件)
2、某一項重要操作完成之后發送郵件;(自定義發送郵件)
沒有接觸過logback,怎么辦?
沒辦法,硬着頭皮上吧。先搞需求1網上查了一波,按照說的一步一步走下來,竟然可以發送了 (意料之中)
首先加入logback需要的jar 這里使用maven
<!-- logback核心包 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.3</version> </dependency> <!-- 發送郵件需要的2個jar --> <dependency> <groupId>org.codehaus.janino</groupId> <artifactId>janino</artifactId> <version>2.7.8</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency>
網上找個logback.xml,加入以下內容,參數對應填入
需求1:
<!-- 郵件 --> <!-- SMTP server的地址,必需指定。如網易的SMTP服務器地址是: smtp.163.com --> <property name="smtpHost" value="127.0.0.1"/><!--填入要發送郵件的smtp服務器地址(問DBA或者經理啥的就知道)--> <!-- SMTP server的端口地址。默認值:25 --> <property name="smtpPort" value="25"/> <!-- 發送郵件賬號,默認為null --> <property name="username" value="zhouyantong@tjtftech.com"/><!--發件人賬號--> <!-- 發送郵件密碼,默認為null --> <property name="password" value="xxx"/><!--發件人密碼--> <!-- 如果設置為true,appender將會使用SSL連接到日志服務器。默認值:false --> <property name="SSL" value="false"/> <!-- 指定發送到那個郵箱,可設置多個<to>屬性,指定多個目的郵箱 --> <property name="email_to" value="1185611832@qq.com,1185611832@qq.com"/><!--收件人賬號多個可以逗號隔開--> <!-- 指定發件人名稱。如果設置成“<ADMIN> ”,則郵件發件人將會是“<ADMIN> ” --> <property name="email_from" value="logmonitor" /> <!-- 指定emial的標題,它需要滿足PatternLayout中的格式要求。如果設置成“Log: %logger - %msg ”,就案例來講,則發送郵件時,標題為“【Error】: com.foo.Bar - Hello World ”。 默認值:"%logger{20} - %m". --> <property name="email_subject" value="【Error】: %logger" /> <!-- ERROR郵件發送 --> <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender"> <smtpHost>${smtpHost}</smtpHost> <smtpPort>${smtpPort}</smtpPort> <username>${username}</username> <password>${password}</password> <asynchronousSending>true</asynchronousSending> <SSL>${SSL}</SSL> <to>${email_to}</to> <from>${email_from}</from> <subject>${email_subject}</subject> <!-- html格式--> <layout class="ch.qos.logback.classic.html.HTMLLayout"> <Pattern>%date%level%thread%logger{0}%line%message</Pattern> </layout> <!-- 這里采用等級過濾器 指定等級相符才發送 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker"> <!-- 每個電子郵件只發送一個日志條目 --> <bufferSize>1</bufferSize> </cyclicBufferTracker> </appender> <root level="info"> <appender-ref ref="EMAIL"/> </root>
這種配置執行下面代碼將會發送郵件!
logger.error("郵件內容");
如果需要直接報錯發送郵件的,只需更改如下代碼即可
<filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator"> <expression> <!-- 這里可以用java里的表達式 --> if(level >= WARN && null != throwable) { return true; } return false; </expression> </evaluator> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter>
而我個人更傾向於logger.error("郵件內容"); 原因很簡單,規范的代碼都有異常處理機制,處理時加入相應的參數發送報錯信息,清晰明了!
需求2:
<appender name="EMAILTO" class="ch.qos.logback.classic.net.SMTPAppender"> <smtpHost>${smtpHost}</smtpHost> <smtpPort>${smtpPort}</smtpPort> <username>${username}</username> <password>${password}</password> <asynchronousSending>true</asynchronousSending> <SSL>${SSL}</SSL> <to>${email_to}</to> <from>${email_from}</from> <subject>${email_subject}</subject> <layout class="ch.qos.logback.classic.html.HTMLLayout"> <Pattern>%date%level%thread%logger{0}%line%message</Pattern> </layout> <!-- 基於標記的發送郵件 這里我們加入一個標記DONE,發送日志時只需加入此標記即可,如有多個標記加入多個<maker></maker>標簽即可 --> <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator"> <marker>DONE</marker> </evaluator> <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker"> <!-- 每個電子郵件只發一個日志條目 --> <bufferSize>1</bufferSize> </cyclicBufferTracker> </appender> <root level="info"> <appender-ref ref="EMAILTO"/> </root>
基於標記的發送郵件任何級別都可以發送,也可以定制級別,這里沒有加入級別就不做演示了
基於標記的自定義發送郵件,加入一下代碼即可:
logger.info(MarkerFactory.getMarker("DONE"),"郵件內容");
紅色內容和上面<maker>標簽內的一致即可
最后貼上我的公司郵箱測試的截圖
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MarkerFactory;
使用java類發送郵件
1 package org.tfkj.hasl.base.utils; 2 3 import javax.mail.*; 4 import javax.mail.internet.InternetAddress; 5 import javax.mail.internet.MimeBodyPart; 6 import javax.mail.internet.MimeMessage; 7 import javax.mail.internet.MimeMultipart; 8 import java.util.Properties; 9 10 /** 11 * @Author zhouyantong 12 * @Date 2017-10-17 14:05 13 */ 14 public class SendMailUtils { 15 private String host = "192.168.1.1"; // smtp服務器 有好多類型的host 16 private String user = "logmonitor@XXX.com"; // 發件人地址 17 private String pwd = "XX@123"; // 密碼 18 private String from = "logmonitor"; // 發件人地址 19 private String to = "monitor@XXX.com"; // 收件人地址 20 21 public void send(String subject, String txt) { 22 Properties props = new Properties(); 23 // 設置發送郵件的郵件服務器的屬性(這里使用網易的smtp服務器) 24 props.put("mail.smtp.host", host); 25 // 需要經過授權,也就是有戶名和密碼的校驗,這樣才能通過驗證(一定要有這一條) 26 props.put("mail.smtp.auth", "true"); 27 // 用剛剛設置好的props對象構建一個session 28 Session session = Session.getDefaultInstance(props); 29 // 有了這句便可以在發送郵件的過程中在console處顯示過程信息,供調試使 30 // 用(你可以在控制台(console)上看到發送郵件的過程) 31 session.setDebug(false); 32 // 用session為參數定義消息對象 33 MimeMessage message = new MimeMessage(session); 34 try { 35 // 加載發件人地址 36 message.setFrom(new InternetAddress(from)); 37 // 加載收件人地址 38 message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); 39 // 加載標題 40 message.setSubject(subject); 41 // 向multipart對象中添加郵件的各個部分內容,包括文本內容和附件 42 Multipart multipart = new MimeMultipart(); 43 44 // 設置郵件的文本內容 45 BodyPart contentPart = new MimeBodyPart(); 46 contentPart.setText(txt); 47 multipart.addBodyPart(contentPart); 48 49 // 添加附件 50 // BodyPart messageBodyPart = new MimeBodyPart(); 51 // DataSource source = new FileDataSource(affix); 52 // 添加附件的內容 53 // messageBodyPart.setDataHandler(new DataHandler(source)); 54 // 添加附件的標題 55 // 這里很重要,通過下面的Base64編碼的轉換可以保證你的中文附件標題名在發送時不會變成亂碼 56 // sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder(); 57 // messageBodyPart.setFileName("=?GBK?B?"+ 58 // enc.encode(affixName.getBytes()) + "?="); 59 // multipart.addBodyPart(messageBodyPart); 60 61 // 將multipart對象放到message中 62 message.setContent(multipart); 63 // 保存郵件 64 message.saveChanges(); 65 // 發送郵件 66 Transport transport = session.getTransport("smtp"); 67 // 連接服務器的郵箱 68 transport.connect(host, user, pwd); 69 // 把郵件發送出去 70 transport.sendMessage(message, message.getAllRecipients()); 71 transport.close(); 72 } catch (Exception e) { 73 e.printStackTrace(); 74 } 75 } 76 77 public static void main(String[] args) { 78 SendMailUtils s = new SendMailUtils(); 79 s.send("主題","內容"); 80 } 81 82 }