此前,本框架已有一套監控日志體系。此前,為提升數據庫與產品性能,我將日志文件分散存在本地文件中,在實際應用使用中,覺著不太合理,頻繁操作本地文件也會造成磁盤IO損耗,而且並沒有提升多高性能。
在一番思索後,我決定還是將所有的日志數據,均存儲在數據庫中,不過為了避免與業務庫性能交疊問題,我決定在此基礎上進行優化一下業務,可支持使用者獨立配置監控日志數據庫。
開發思路
為解決監控性能問題,我將使用線程池進行記錄。為解決多個功能之前重復代碼問題,我準備封裝一個“基礎監控工廠類”,將共用業務進行封裝,並提供抽象函數,由子類實現。
此系列將實現“日志”、“賬號”、“api”、“功能”、“sql”監控功能,此次將同步實現“日志”功能監控。
基礎功能開發
1. 監控工廠
package com.flycoding.monitor.factory.base;
import com.flycoding.drivenlibrary.engine.config.DrivenEngineConfig;
import com.flycoding.drivenlibrary.engine.config.constants.DrivenConstants;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 監控工廠類
*
* @author 趙屈犇
* @version 1.0
* @date 創建時間: 2020/10/5 15:26
*/
public class MonitorFactory {
/**
* 監聽工廠類
*/
private static MonitorFactory factory;
/**
* 多線程執行服務
*/
private ExecutorService executorService;
public static MonitorFactory getInstance() {
if (factory == null) {
synchronized (MonitorFactory.class) {
if (factory == null) {
factory = new MonitorFactory();
}
}
}
return factory;
}
protected MonitorFactory() {
Integer corePoolSize = DrivenEngineConfig.getConfigValue(DrivenConstants.MonitorConstants.ThreadPoolConstants.CORE_POOL_SIZE, 10);
Integer maxPoolSize = DrivenEngineConfig.getConfigValue(DrivenConstants.MonitorConstants.ThreadPoolConstants.MAX_POOL_SIZE, 10);
Long keepAliveTime = DrivenEngineConfig.getConfigValue(DrivenConstants.MonitorConstants.ThreadPoolConstants.KEEP_ALIVE_TIME, 0L);
executorService = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
}
/**
* 獲取執行service
*
* @return
*/
public ExecutorService getExecutorService() {
return executorService;
}
}
此功能,用於定義監控工廠的線程池,其中核心線程池大小、最大線程池大小、最大等待時間支持用戶yml配置,框架內置默認值。
2. 基礎監控工廠
package com.flycoding.monitor.factory.base;
import com.flycoding.biz.account.factory.UserFactory;
import com.flycoding.dblibrary.executor.inter.ISqlExecutor;
import com.flycoding.drivenlibrary.context.RequestContextHolder;
import com.flycoding.drivenlibrary.database.executor.MonitorSqlExecutor;
import com.flycoding.drivenlibrary.engine.config.DrivenEngineConfig;
import com.flycoding.drivenlibrary.engine.config.constants.DrivenConstants;
import com.flycoding.drivenlibrary.engine.util.RequestUtils;
import com.flycoding.monitor.entity.MonitorLoggerPO;
import com.flycoding.monitor.entity.base.BaseMonitorPO;
import com.flycoding.monitor.entity.base.BaseRequestMonitorPO;
import com.flycoding.monitor.factory.MonitorFileFactory;
import com.flycoding.utillibrary.date.TimeUtils;
import com.flycoding.utillibrary.java.ThrowableUtil;
import com.flycoding.utillibrary.logger.LoggerFactory;
import com.flycoding.utillibrary.strings.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.sql.SQLSyntaxErrorException;
/**
* 基礎監控工廠類
*
* @author 趙屈犇
* @version 1.0
* @date 創建時間: 2021/5/28 下午10:07
*/
public abstract class BaseMonitorFactory<T extends BaseMonitorFactory> {
/**
* 記錄開始時間
*/
protected long startTime;
/**
* 錯誤異常
*/
protected Throwable throwable;
/**
* 是否開啟監控 用戶代理信息 請求客戶端信息 異常信息 輸出控制臺 輸出db
*/
protected boolean isMonitor, isUserAgent, isRequestClient, isThrowable, isOutputConsole, isOutputDatabase;
/**
* 配置前綴 獲取瀏覽器信息 獲取客戶端信息 獲取IP地址 賬號ID 渠道編碼 應用渠道編碼
*/
protected String prefix, userAgent, requestClient, ipAddress, accountId, channelCode, appChannelCode;
protected BaseMonitorFactory() {
prefix = StringUtils.appendStrings(DrivenConstants.MonitorConstants.PREFIX, getMonitorConfigKey(), ".");
isMonitor = DrivenEngineConfig.getConfigValue(prefix DrivenConstants.MonitorConstants.IS_MONITOR, true);
isUserAgent = DrivenEngineConfig.getConfigValue(prefix DrivenConstants.MonitorConstants.IS_SAVE_USER_AGENT, true);
isRequestClient = DrivenEngineConfig.getConfigValue(prefix DrivenConstants.MonitorConstants.IS_SAVE_REQUEST_CLIENT, true);
isThrowable = DrivenEngineConfig.getConfigValue(prefix DrivenConstants.MonitorConstants.IS_SAVE_THROWABLE, true);
isOutputConsole = DrivenEngineConfig.getConfigValue(prefix DrivenConstants.MonitorConstants.IS_OUTPUT_CONSOLE, true);
isOutputDatabase = DrivenEngineConfig.getConfigValue(prefix DrivenConstants.MonitorConstants.IS_OUTPUT_DATABASE, true);
init();
initServletRequest(RequestContextHolder.getServletRequest());
}
public T init() {
startTime = System.currentTimeMillis();
throwable(null);
return (T) this;
}
/**
* 設置啟動時間
*
* @param startTime
* @return
*/
public T startTime(long startTime) {
this.startTime = startTime;
return (T) this;
}
/**
* 初始化請求數據
*
* @param request
* @return
*/
private void initServletRequest(HttpServletRequest request) {
if (isMonitor) {
if (request != null) {
try {
setChannelCode(RequestContextHolder.getChannelCode());
setAppChannelCode(RequestContextHolder.getAppChannelCode());
if (isGetAccountId()) {
// 獲取當前用戶ID
this.accountId = UserFactory.builder().setChannelCode(getMonitorChannelCode()).getAccountId();
}
if (isUserAgent) {
// 獲取瀏覽器信息
this.userAgent = request.getHeader("user-agent");
}
if (isRequestClient) {
// 獲取客戶端信息
this.requestClient = RequestUtils.getRequestContent(request);
}
// 獲取IP地址
this.ipAddress = RequestUtils.getIPAddress(request);
} catch (Exception e) {
}
}
}
}
/**
* 設置是否監控
*
* @param monitor
* @return
*/
public T monitor(boolean monitor) {
isMonitor = monitor;
return (T) this;
}
/**
* 設置異常
*
* @param throwable
* @return
*/
public T throwable(Throwable throwable) {
if (isMonitor && isThrowable) {
this.throwable = throwable;
}
return (T) this;
}
/**
* 設置賬號id
*
* @param accountId
* @return
*/
public T accountId(String accountId) {
if (isMonitor) {
this.accountId = accountId;
}
return (T) this;
}
/**
* 獲取執行時長
*
* @return
*/
protected long getDuration() {
return TimeUtils.getNowTimeMills() - startTime;
}
/**
* 設置渠道編碼
*
* @param channelCode
*/
public void setChannelCode(String channelCode) {
if (isMonitor) {
this.channelCode = channelCode;
}
}
/**
* 設置應用渠道編碼
*
* @param appChannelCode
*/
public void setAppChannelCode(String appChannelCode) {
if (isMonitor) {
this.appChannelCode = appChannelCode;
}
}
/**
* 記錄監控
*
* @return
*/
public T record() {
if (isMonitor) {
long duration = getDuration();
MonitorFactory.getInstance().getExecutorService().submit(() -> {
// 日志工廠類
LoggerFactory logger = LoggerFactory.getLogger(getClass().getName());
try {
// 監控文件工廠
MonitorFileFactory monitorFileFactory = MonitorFileFactory.getInstance();
// 獲取監控信息
BaseMonitorPO monitorInfo = getMonitorInfo(duration, monitorFileFactory);
if (monitorInfo != null) {
// 執行器
ISqlExecutor executor = MonitorSqlExecutor.newInstance().setRecordSQL(false);
if (monitorInfo instanceof MonitorLoggerPO) {
executor.setRecordLog(false);
}
if (monitorInfo instanceof BaseRequestMonitorPO) {
BaseRequestMonitorPO requestMonitorPO = (BaseRequestMonitorPO) monitorInfo;
// 存儲異常信息
if (isThrowable) {
requestMonitorPO.setThrowable(ThrowableUtil.throwableConvertString(throwable));
}
// 存儲用戶代理信息
if (isUserAgent) {
requestMonitorPO.setUserAgent(userAgent);
}
// 存儲客戶端請求內容
if (isRequestClient) {
requestMonitorPO.setRequestClient(requestClient);
}
requestMonitorPO.setIpAddress(ipAddress);
}
monitorInfo.setAccountId(accountId);
monitorInfo.setChannelCode(channelCode);
monitorInfo.setAppChannelCode(appChannelCode);
monitorInfo.save(executor);
}
} catch (SQLSyntaxErrorException e) {
} catch (Exception e) {
logger.error("記錄監控信息失敗", e);
}
});
}
return (T) this;
}
/**
* 獲取監控信息
*
* @param duration
* @param monitorFileFactory
* @return
* @throws Exception
*/
protected abstract BaseMonitorPO getMonitorInfo(long duration, MonitorFileFactory monitorFileFactory) throws Exception;
/**
* 獲取監控配置
*
* @return
*/
protected abstract String getMonitorConfigKey();
/**
* 獲取監控渠道編碼
*
* @return
*/
protected abstract String getMonitorChannelCode();
/**
* 是否獲取賬號id
*
* @return
*/
protected boolean isGetAccountId() {
return true;
}
}
此功能實現基礎監控工廠類,封裝基礎監控功能。
此類定義了是否“開啟監控,記錄用戶代理信息 、請求客戶端信息、異常信息、輸出控制臺、輸出db” yml配置並配置默認值。
封裝了初始化請求數據。記錄調用函數,此函數已實現通過“線程池”動態創建,並其中封裝了一些常用記錄參數功能。
3. 監控SQL執行器
package com.flycoding.drivenlibrary.database.executor;
import com.flycoding.drivenlibrary.database.executor.impl.AbstractSqlExecutor;
import com.flycoding.drivenlibrary.engine.config.DrivenEngineConfig;
/**
* 監控sql執行器
*
* @author 趙屈犇
* @version 1.0
* @date 創建時間: 2023/12/21 20:37
* @Copyright(C): 2023 by 趙屈犇
*/
public class MonitorSqlExecutor extends AbstractSqlExecutor {
public static MonitorSqlExecutor newInstance() {
return new MonitorSqlExecutor();
}
public MonitorSqlExecutor() {
}
@Override
protected String getDBConfigValue() {
return DrivenEngineConfig.getInstance().getMonitorDBConfigPath();
}
@Override
protected String getTemplateFolder() {
return "monitor";
}
}
定義監控數據庫執行器,此配置若未配置監控配置時,將采用默認後臺數據庫配置。若配置,則采用監控配置。
4. 配置監控模型
/**
* 監控模型數據編碼
*/
@ModelDBConfig(dbConfigName = "系統監控模型配置", extendPackageNames = {"com.flycoding.monitor"},
dataExecutorClass = MonitorSqlExecutor.class, dbConfigFileName = DrivenConfigConstants.MONITOR_MODEL_DB_NAME,
createDBPackageNames = {"com.flycoding.monitor.entity"}, dictionarys = {}, apiModuleUrl = "driven")
String MONITOR_MODEL = "MONITOR_MODEL";
日志監控功能開發
此上,業已實現監控基礎配置。此下,將具體實現日志監控功能。我將從數據庫設計-日志工廠實現-效果演示逐步該功能。
1. 設計數據庫
![](https://news.xinpengboligang.com/upload/keji/bd036d5409fa353efbf86b2426c99493.jpeg)
2. 定義PO對象
package com.flycoding.monitor.entity;
import com.flycoding.dblibrary.annotation.create.Column;
import com.flycoding.dblibrary.annotation.create.PrimaryAuto;
import com.flycoding.dblibrary.annotation.create.Table;
import com.flycoding.dblibrary.enums.ColumnType;
import com.flycoding.dblibrary.enums.OrderByType;
import com.flycoding.drivenlibrary.engine.annotation.function.FunctionConfig;
import com.flycoding.drivenlibrary.engine.annotation.function.config.popup.PopupConfig;
import com.flycoding.drivenlibrary.engine.annotation.function.config.table.TableConfig;
import com.flycoding.drivenlibrary.engine.annotation.function.form.FormConfig;
import com.flycoding.drivenlibrary.engine.annotation.function.form.FormFieldConfig;
import com.flycoding.drivenlibrary.engine.annotation.function.form.field.DictConfig;
import com.flycoding.drivenlibrary.engine.annotation.function.form.field.FieldConfig;
import com.flycoding.drivenlibrary.engine.config.constants.dictionary.ConfigDictionaryConstants;
import com.flycoding.drivenlibrary.engine.constants.DefaultFieldConstants;
import com.flycoding.drivenlibrary.engine.constants.FieldConfigConstants;
import com.flycoding.drivenlibrary.engine.constants.config.DrivenElementConstants;
import com.flycoding.drivenlibrary.enums.dictionary.QueryType;
import com.flycoding.monitor.entity.base.BaseMonitorPO;
import com.flycoding.utillibrary.logger.LoggerLevel;
/**
* 日志監控對象
*
* @author 趙屈犇
* @version 1.0
* @date 創建時間: 2018/2/6 下午11:14
*/
@Table(tableName = MonitorLoggerPO.TABLE_NAME)
@FunctionConfig(funcName = "日志管理", funcCode = "Sy_Monitor_Logger", tableConfig = @TableConfig(tableName = MonitorLoggerPO.TABLE_NAME,
columns = {
@Column(columnName = DefaultFieldConstants.CREATE_TIME, isInsertUse = false, isSelectUse = false, orderBy = OrderByType.DESC)
}), formConfig = @FormConfig(keyCode = "id", isCreateTableAddBtn = false, popupConfig = @PopupConfig(popupWidth = 850, popupHeight = 550)
))
public class MonitorLoggerPO extends BaseMonitorPO {
public static final String TABLE_NAME = "Sys_Monitor_Logger";
@PrimaryAuto(columnName = "id", comment = "日志ID")
@FormFieldConfig(fieldCode = "id", fieldName = "日志ID", isPageVisibility = false, isTableEnable = false, fieldParentName = MONITOR_BASIC_MESSAGE_NAME)
private Integer id;
/**
* 日志標簽
*/
@Column(columnName = "logger_tag", length = 200, isNotNull = true, comment = "日志標簽")
@FormFieldConfig(fieldCode = "logger_tag", fieldName = "日志標簽", isVerifyEmpty = true, tableQueryType = QueryType.LIKE, fieldParentName = MONITOR_BASIC_MESSAGE_NAME, tableColumnWidth = "235")
private String loggerTag;
/**
* 日志級別
*/
@FormFieldConfig(fieldCode = "logger_level", fieldName = "日志級別", tableQueryType = QueryType.EQUAL, elementCode = DrivenElementConstants.SELECT_ELEMENT, fieldParentName = MONITOR_BASIC_MESSAGE_NAME,
dict = @DictConfig(dictCode = ConfigDictionaryConstants.LoggerLevelConstants.DICTIONARY_CODE))
@Column(columnName = "logger_level", length = 6, isNotNull = true, comment = "日志級別")
private String loggerLevel;
/**
* 關聯主鍵ID
*/
@Column(columnName = "relevance_id", columnType = ColumnType.VARCHAR, length = 34)
private String relevanceId;
/**
* 日志內容
*/
@Column(columnName = "logger_content", columnType = ColumnType.LONG_TEXT, comment = "日志內容")
@FormFieldConfig(fieldCode = "logger_content", fieldName = "日志內容", config = @FieldConfig(appendCss = FieldConfigConstants.CSS_HALF_SCREEN_COL),
elementCode = DrivenElementConstants.BIG_INPUT_ELEMENT, isTableEnable = false, fieldParentName = BaseMonitorPO.DETAIL_BASIC_MESSAGE_NAME)
private String loggerContent;
/**
* 日志級別
*/
private LoggerLevel level;
/**
* 是否輸出錯誤
*/
private boolean isOutToError;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLoggerTag() {
return loggerTag;
}
public void setLoggerTag(String loggerTag) {
this.loggerTag = loggerTag;
}
public String getLoggerLevel() {
return loggerLevel;
}
public void setLoggerLevel(String loggerLevel) {
this.loggerLevel = loggerLevel;
}
public String getRelevanceId() {
return relevanceId;
}
public void setRelevanceId(String relevanceId) {
this.relevanceId = relevanceId;
}
public LoggerLevel getLevel() {
return level;
}
public void setLevel(LoggerLevel level) {
this.level = level;
}
public boolean isOutToError() {
return isOutToError;
}
public void setOutToError(boolean outToError) {
isOutToError = outToError;
}
public String getLoggerContent() {
return loggerContent;
}
public void setLoggerContent(String loggerContent) {
this.loggerContent = loggerContent;
}
}
3. 實現日志監控工廠
package com.flycoding.monitor.factory;
import com.flycoding.biz.manage.constants.ManageDictionaryConstants;
import com.flycoding.monitor.entity.MonitorLoggerPO;
import com.flycoding.monitor.entity.base.BaseMonitorPO;
import com.flycoding.monitor.factory.base.BaseMonitorFactory;
import com.flycoding.drivenlibrary.engine.config.DrivenEngineConfig;
import com.flycoding.drivenlibrary.engine.config.constants.DrivenConstants;
import com.flycoding.utillibrary.date.TimeUtils;
import com.flycoding.utillibrary.date.enums.DateStyle;
import com.flycoding.utillibrary.java.ThrowableUtil;
import com.flycoding.utillibrary.logger.LoggerConfig;
import com.flycoding.utillibrary.logger.LoggerLevel;
import com.flycoding.utillibrary.strings.StringUtils;
/**
* 日志監控工廠類
*
* @author 趙屈犇
* @version 1.0
* @date 創建時間: 2020/10/8 20:43
*/
public class MonitorLoggerFactory extends BaseMonitorFactory<MonitorLoggerFactory> {
/**
* 日志級別
*/
private LoggerLevel level;
/**
* 日志別名 日志信息 關聯主鍵
*/
private String logTag, message, relevanceId;
/**
* 是否輸出錯誤 是否記錄日志
*/
private boolean isOutToError, isSaveLogger;
public static MonitorLoggerFactory builder() {
return new MonitorLoggerFactory();
}
private MonitorLoggerFactory() {
super();
isSaveLogger = DrivenEngineConfig.getConfigValue(prefix DrivenConstants.MonitorConstants.IS_SAVE_LOGGER, true);
}
/**
* 日志別名
*
* @param logTag
* @return
*/
public MonitorLoggerFactory logTag(String logTag) {
this.logTag = logTag;
return this;
}
/**
* 日志信息
*
* @param message
* @return
*/
public MonitorLoggerFactory message(String message) {
this.message = message;
return this;
}
/**
* 日志級別
*
* @param level
* @return
*/
public MonitorLoggerFactory level(LoggerLevel level) {
this.level = level;
return this;
}
/**
* 是否輸出錯誤,控制臺錯誤警告
*
* @param outToError
* @return
*/
public MonitorLoggerFactory outToError(boolean outToError) {
isOutToError = outToError;
return this;
}
/**
* 關聯主鍵
*
* @param relevanceId
* @return
*/
public MonitorLoggerFactory relevanceId(String relevanceId) {
this.relevanceId = relevanceId;
return this;
}
@Override
protected BaseMonitorPO getMonitorInfo(long duration, MonitorFileFactory monitorFileFactory) throws Exception {
MonitorLoggerPO monitorInfo = new MonitorLoggerPO();
monitorInfo.setLevel(level);
monitorInfo.setLoggerTag(logTag);
monitorInfo.setOutToError(isOutToError);
monitorInfo.setRelevanceId(relevanceId);
monitorInfo.setLoggerLevel(level.getTag());
// 日志配置
LoggerConfig loggerConfig = LoggerConfig.getInstance();
// 生成日志信息
StringBuffer loggerContent = new StringBuffer(TimeUtils.getNowTimeString(DateStyle.YYYY_MM_DD_HH_MM_SS_SSS.getValue()));
loggerContent.append(" ").append(level.getTag()).append("/").append(logTag).append(": ").append(message);
// 異常轉換字符串
String throwableMessage = ThrowableUtil.throwableConvertString(throwable);
if (StringUtils.isNotEmpty(throwableMessage)) {
loggerContent.append("\n").append(throwableMessage);
}
// 判斷控制臺日志級別
if (level.getLevelValue() >= loggerConfig.getConsoleLoggerLevel().getLevelValue()) {
/**
* 輸出日志到控制臺
*/
if (isOutputConsole) {
if (isOutToError) {
System.err.println(loggerContent);
} else {
System.out.println(loggerContent);
}
}
}
// 判斷數據庫日志級別
if (level.getLevelValue() >= loggerConfig.getDataBaseLoggerLevel().getLevelValue()) {
/**
* 輸出日志到DB文件中
*/
if (isOutputDatabase) {
// 存儲異常信息
if (isSaveLogger) {
monitorInfo.setLoggerContent(loggerContent.toString());
}
return monitorInfo;
} else {
return null;
}
} else {
return null;
}
}
@Override
protected String getMonitorConfigKey() {
return "logger";
}
@Override
protected String getMonitorChannelCode() {
return ManageDictionaryConstants.ChannelDictionary.MONITOR_LOGGER;
}
}
此工廠,實現了日志監控工廠將日志記錄數據庫中。
4. 實現日志工廠
package com.flycoding.utillibrary.logger;
import com.flycoding.monitor.factory.MonitorLoggerFactory;
/**
* 日志工廠類
*
* @author 趙屈犇
* @version 1.0
* @date 創建時間: 2018/2/6 下午11:16
*/
public class LoggerFactory {
/**
* 日志標簽
*/
private String tag;
/**
* 關聯業務主鍵ID
*/
private String relevanceId;
/**
* 是否記錄日志
*/
private boolean isRecordLog = true;
public static LoggerFactory getLogger() {
return getLogger("");
}
public static LoggerFactory getLogger(String tag) {
return new LoggerFactory(tag);
}
private LoggerFactory() {
}
private LoggerFactory(String tag) {
this.tag = tag;
}
/**
* 設置TAG
*
* @param tag
*/
public LoggerFactory setTag(String tag) {
this.tag = tag;
return this;
}
/**
* 設置關聯主鍵ID
*
* @param relevanceId
* @return
*/
public LoggerFactory setRelevanceId(String relevanceId) {
this.relevanceId = relevanceId;
return this;
}
/**
* =============非靜態輸出日志=============
*/
public LoggerFactory debug(String message) {
debug(message, null);
return this;
}
public LoggerFactory info(String message) {
info(message, null);
return this;
}
public LoggerFactory warn(String message) {
warn(message, null);
return this;
}
public LoggerFactory error(String message) {
error(message, null);
return this;
}
/**
* =============非靜態輸出日志=============
*/
/**
* =============非靜態輸出異常信息=============
*/
public LoggerFactory debug(Throwable throwable) {
debug("", throwable);
return this;
}
public LoggerFactory info(Throwable throwable) {
info("", throwable);
return this;
}
public LoggerFactory warn(Throwable throwable) {
warn("", throwable);
return this;
}
public LoggerFactory error(Throwable throwable) {
error("", throwable);
return this;
}
/**
* =============非靜態輸出異常信息=============
*/
/**
* =============非靜態輸出異常信息=============
*/
public LoggerFactory debug(String message, Throwable throwable) {
printLog(LoggerLevel.DEBUG, tag, message, throwable, false);
return this;
}
public LoggerFactory info(String message, Throwable throwable) {
printLog(LoggerLevel.INFO, tag, message, throwable, false);
return this;
}
public LoggerFactory warn(String message, Throwable throwable) {
printLog(LoggerLevel.WARN, tag, message, throwable, false);
return this;
}
public LoggerFactory error(String message, Throwable throwable) {
printLog(LoggerLevel.ERROR, tag, message, throwable, true);
return this;
}
/**
* =============非靜態輸出異常信息=============
*/
/**
* 設置是否記錄日志
*
* @param recordLog
* @return a
* @author 趙屈犇
* @date 創建時間: 2022/6/18 21:31
* @version 1.0
*/
public void setRecordLog(boolean recordLog) {
isRecordLog = recordLog;
}
/**
* 打印輸出日志
*
* @param level
* @param tag
* @param message
* @param throwable
* @param isOutToErr
*/
private void printLog(LoggerLevel level, String tag, String message, Throwable throwable, boolean isOutToErr) {
if (isRecordLog) {
MonitorLoggerFactory.builder().level(level).logTag(tag).message(message).throwable(throwable).outToError(isOutToErr)
.relevanceId(relevanceId).record();
}
}
}
至此,日志工廠類已實現。
![](https://news.xinpengboligang.com/upload/keji/1f176adc46c01e0c55098366c6cb957b.jpeg)