!22 ➕ 添加依赖:添加并引入Slf4j api 与 logback作为项目日志框架,已替换项目内控制台输出,简单封装了日志工具类
Merge pull request !22 from 格物方能致知/master
This commit is contained in:
commit
1cd41017b2
19
pom.xml
19
pom.xml
@ -37,7 +37,24 @@
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--log-->
|
||||
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>2.0.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<version>1.4.11</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.4.11</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
module org.jcnc.jnotepad {
|
||||
requires javafx.controls;
|
||||
// 不知道为什么,不加这个,日志框架在打包后的程序不起作用,会报错
|
||||
// Exception in thread "JavaFX Application Thread" java.lang.NoClassDefFoundError: javax/naming/NamingException
|
||||
// 但我打开源代码,他们的模块的确有包含这个,java.naming,这个没懂,我干脆自己导入
|
||||
requires java.naming;
|
||||
requires atlantafx.base;
|
||||
// requires cn.hutool.json;
|
||||
// requires cn.hutool.core;
|
||||
requires com.google.gson;
|
||||
requires org.slf4j;
|
||||
requires ch.qos.logback.core;
|
||||
requires ch.qos.logback.classic;
|
||||
exports org.jcnc.jnotepad;
|
||||
exports org.jcnc.jnotepad.tool;
|
||||
exports org.jcnc.jnotepad.Interface;
|
||||
|
||||
@ -70,7 +70,6 @@ public class LunchApp extends Application {
|
||||
// 初始化菜单项和标签栏
|
||||
view.initTabPane();
|
||||
view.initShortcutKey();
|
||||
|
||||
if (controller.isRelevance()) {
|
||||
// 使用线程池加载关联文件并创建文本区域
|
||||
List<String> rawParameters = getParameters().getRaw();
|
||||
|
||||
@ -7,7 +7,6 @@ import javafx.stage.FileChooser;
|
||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
|
||||
import org.jcnc.jnotepad.view.manager.ViewManager;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@ -26,8 +25,6 @@ public class OpenFile implements EventHandler<ActionEvent> {
|
||||
*/
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
// 获取ViewManager的实例
|
||||
ViewManager viewManager = ViewManager.getInstance();
|
||||
// 获取控制器
|
||||
Controller controller = Controller.getInstance();
|
||||
// 创建文件选择器
|
||||
|
||||
@ -4,9 +4,9 @@ import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.stage.FileChooser;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
|
||||
import org.jcnc.jnotepad.view.manager.ViewManager;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
@ -49,7 +49,7 @@ public class SaveAsFile implements EventHandler<ActionEvent> {
|
||||
selectedTab.setText(file.getName()); // 更新Tab页标签上的文件名
|
||||
selectedTab.setUserData(file); // 将文件对象保存到Tab页的UserData中
|
||||
} catch (IOException ignored) {
|
||||
System.out.println("已忽视IO异常!");
|
||||
LogUtil.info("已忽视IO异常!",this.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import org.jcnc.jnotepad.controller.event.handler.NewFile;
|
||||
import org.jcnc.jnotepad.controller.event.handler.OpenFile;
|
||||
import org.jcnc.jnotepad.controller.event.handler.SaveAsFile;
|
||||
import org.jcnc.jnotepad.tool.EncodingDetector;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTab;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
|
||||
@ -98,9 +99,9 @@ public class Controller implements ControllerInterface {
|
||||
if (file != null) {
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
|
||||
writer.write(newValue);
|
||||
System.out.println("正在自动保存---");
|
||||
LogUtil.info("正在自动保存---",this.getClass());
|
||||
} catch (IOException ignored) {
|
||||
System.out.println("已忽视IO异常!");
|
||||
LogUtil.info("已忽视IO异常!",this.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,7 +153,6 @@ public class Controller implements ControllerInterface {
|
||||
*/
|
||||
@Override
|
||||
public void getText(File file) {
|
||||
ViewManager viewManager = ViewManager.getInstance();
|
||||
LineNumberTextArea textArea = createNewTextArea();
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
StringBuilder textBuilder = new StringBuilder();
|
||||
@ -173,7 +173,7 @@ public class Controller implements ControllerInterface {
|
||||
autoSave(textArea);
|
||||
});
|
||||
} catch (IOException ignored) {
|
||||
System.out.println("已忽视IO异常!");
|
||||
LogUtil.info("已忽视IO异常!",this.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import com.google.gson.reflect.TypeToken;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.input.KeyCombination;
|
||||
import org.jcnc.jnotepad.Interface.ShortcutKeyInterface;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
|
||||
|
||||
import java.io.*;
|
||||
@ -33,7 +34,7 @@ public class ShortcutKey implements ShortcutKeyInterface {
|
||||
jsonData.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
LogUtil.error("读取配置失败!",e,this.getClass());
|
||||
}
|
||||
} else {
|
||||
// todo new InputStreamReader(inputStream) 实参 'inputStream' 可能为null
|
||||
@ -43,7 +44,7 @@ public class ShortcutKey implements ShortcutKeyInterface {
|
||||
jsonData.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
LogUtil.error("读取配置失败!",e,this.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
12
src/main/java/org/jcnc/jnotepad/exception/AppException.java
Normal file
12
src/main/java/org/jcnc/jnotepad/exception/AppException.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.jcnc.jnotepad.exception;
|
||||
|
||||
/**
|
||||
* 应用异常类
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class AppException extends RuntimeException {
|
||||
public AppException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package org.jcnc.jnotepad.tool;
|
||||
|
||||
|
||||
import javafx.application.Platform;
|
||||
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
@ -36,7 +37,7 @@ public class EncodingDetector {
|
||||
// 尝试常见的编码
|
||||
for (Charset charset : commonCharsets()) {
|
||||
if (isValidEncoding(text, charset)) {
|
||||
System.out.println("编码监测结果:" + isValidEncoding(text, charset));
|
||||
Platform.runLater(()-> LogUtil.info("编码监测结果:" + isValidEncoding(text, charset),EncodingDetector.class));
|
||||
return charset.name();
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ public class FileUtil {
|
||||
jsonStr = sb.toString();
|
||||
return jsonStr;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
LogUtil.error("读取配置失败!",e,FileUtil.class);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
85
src/main/java/org/jcnc/jnotepad/tool/LogUtil.java
Normal file
85
src/main/java/org/jcnc/jnotepad/tool/LogUtil.java
Normal file
@ -0,0 +1,85 @@
|
||||
package org.jcnc.jnotepad.tool;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 日志工具<br>注意,使用该工具的方法时,如果需要在JavaFx项目中调用日志请使用Platform.runLater()调用
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class LogUtil {
|
||||
private LogUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日志类
|
||||
*
|
||||
* @param currentClass 所要记录的类
|
||||
* @return org.apache.logging.log4j.Logger 日志对象
|
||||
* @apiNote 传入当前需要记录的类,返回记录该类的日志类,也可直接使用工具类定义好的方法,也可调用这个方法自定义
|
||||
* @see LogUtil
|
||||
*/
|
||||
public static Logger getLogger(Class<?> currentClass) {
|
||||
return LoggerFactory.getLogger(currentClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志信息打印
|
||||
*
|
||||
* @param message 日志信息
|
||||
* @param currentClass 所要记录的类
|
||||
* @apiNote 传入当前需要记录的类,方便知晓是哪个位置记录的日志
|
||||
*/
|
||||
public static void info(String message, Class<?> currentClass) {
|
||||
getLogger(currentClass).info(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志排错信息打印
|
||||
*
|
||||
* @param message 日志信息
|
||||
* @param currentClass 所要记录的类
|
||||
* @apiNote 传入当前需要记录的类,方便知晓是哪个位置记录的日志
|
||||
*/
|
||||
|
||||
public static void debug(String message, Class<?> currentClass) {
|
||||
getLogger(currentClass).debug(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志警告信息打印
|
||||
*
|
||||
* @param message 日志信息
|
||||
* @param currentClass 所要记录的类
|
||||
* @apiNote 传入当前需要记录的类,方便知晓是哪个位置记录的日志
|
||||
*/
|
||||
public static void warn(String message, Class<?> currentClass) {
|
||||
getLogger(currentClass).warn(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志错误信息打印
|
||||
*
|
||||
* @param message 日志信息
|
||||
* @param currentClass 所要记录的类
|
||||
* @apiNote 传入当前需要记录的类,方便知晓是哪个位置记录的日志
|
||||
*/
|
||||
public static void error(String message, Class<?> currentClass) {
|
||||
getLogger(currentClass).error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志错误信息打印
|
||||
*
|
||||
* @param message 日志信息
|
||||
* @param throwable 抛出的异常
|
||||
* @param currentClass 所要记录的类
|
||||
* @apiNote 这个方法用来弥补当抛出异常或手动抛出异常时,无法捕捉到所抛异常
|
||||
*/
|
||||
|
||||
public static void error(String message, Throwable throwable, Class<?> currentClass) {
|
||||
getLogger(currentClass).error(message, throwable);
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.jcnc.jnotepad.exception.AppException;
|
||||
import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
|
||||
|
||||
@ -35,8 +36,6 @@ public class ViewManager {
|
||||
private static ViewManager instance = null;
|
||||
|
||||
|
||||
|
||||
|
||||
public Label getEnCodingLabel() {
|
||||
return enCodingLabel;
|
||||
}
|
||||
@ -47,7 +46,6 @@ public class ViewManager {
|
||||
* @return int 标签页索引
|
||||
* @apiNote ++tabIndex
|
||||
*/
|
||||
|
||||
public int selfIncreaseAndGetTabIndex() {
|
||||
return ++tabIndex;
|
||||
}
|
||||
@ -83,7 +81,7 @@ public class ViewManager {
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
} else {
|
||||
throw new RuntimeException("ViewManager的实例未初始化!");
|
||||
throw new AppException("ViewManager的实例未初始化!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
122
src/main/resources/logback.xml
Normal file
122
src/main/resources/logback.xml
Normal file
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- scan属性未true时,如果配置文档发生改变将会进行重新加载 -->
|
||||
<!-- scanPeriod属性设置监测配置文件修改的时间间隔,默认单位为毫秒,在scan为true时才生效 -->
|
||||
<!-- debug属性如果为true时,会打印出logback内部的日志信息 -->
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||
<!-- 定义参数常量 -->
|
||||
<!-- 日志级别:TRACE<DEBUG<INFO<WARN<ERROR,其中常用的是DEBUG、INFO和ERROR -->
|
||||
<property name="log.level" value="debug"/>
|
||||
<!-- 文件保留时间 -->
|
||||
<property name="log.maxHistory" value="30"/>
|
||||
<!-- 日志存储路径 -->
|
||||
<property name="log.filePath" value="logs"/>
|
||||
<!-- 日志的显式格式 -->
|
||||
<property name="log.pattern"
|
||||
value="时间:[%d{yyyy-MM-dd HH:mm:ss.SSS}] 线程:[%thread] 日志级别:[%-5level] 调用位置:[%logger{50} [%L]] - 日志信息:[%msg]%n">
|
||||
</property>
|
||||
<!-- 用于说明输出介质,此处说明控制台输出 -->
|
||||
<appender name="consoleAppender"
|
||||
class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- 类似于layout,除了将时间转化为数组,还会将转换后的数组输出到相应的文件中 -->
|
||||
<encoder>
|
||||
<!-- 定义日志的输出格式 -->
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- DEBUG,表示文件随着时间的推移按时间生成日志文件 -->
|
||||
<appender name="debugAppender"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 文件路径 -->
|
||||
<file>${log.filePath}/debug.log</file>
|
||||
<!-- 滚动策略 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 设置文件名称 -->
|
||||
<fileNamePattern>
|
||||
${log.filePath}/debug/debug.%d{yyyy-MM-dd}.log.gz
|
||||
</fileNamePattern>
|
||||
<!-- 设置最大保存周期 -->
|
||||
<MaxHistory>${log.maxHistory}</MaxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<!-- 过滤器,过滤掉不是指定日志水平的日志 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 设置日志级别 -->
|
||||
<level>DEBUG</level>
|
||||
<!-- 如果跟该日志水平相匹配,则接受 -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 如果跟该日志水平不匹配,则过滤掉 -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
<!-- INFO,表示文件随着时间的推移按时间生成日志文件 -->
|
||||
<appender name="infoAppender"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 文件路径 -->
|
||||
<file>${log.filePath}/info.log</file>
|
||||
<!-- 滚动策略 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 设置文件名称 -->
|
||||
<fileNamePattern>
|
||||
${log.filePath}/info/info.%d{yyyy-MM-dd}.log.gz
|
||||
</fileNamePattern>
|
||||
<!-- 设置最大保存周期 -->
|
||||
<MaxHistory>${log.maxHistory}</MaxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<!-- 过滤器,过滤掉不是指定日志水平的日志 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 设置日志级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 如果跟该日志水平相匹配,则接受 -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 如果跟该日志水平不匹配,则过滤掉 -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
<!-- ERROR,表示文件随着时间的推移按时间生成日志文件 -->
|
||||
<appender name="errorAppender"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 文件路径 -->
|
||||
<file>${log.filePath}/error.log</file>
|
||||
<!-- 滚动策略 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 设置文件名称 -->
|
||||
<fileNamePattern>
|
||||
${log.filePath}/error/error.%d{yyyy-MM-dd}.log.gz
|
||||
</fileNamePattern>
|
||||
<!-- 设置最大保存周期 -->
|
||||
<MaxHistory>${log.maxHistory}</MaxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<!-- 过滤器,过滤掉不是指定日志水平的日志 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 设置日志级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 如果跟该日志水平相匹配,则接受 -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 如果跟该日志水平不匹配,则过滤掉 -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
<!-- 用于存放日志对象,同时指定关联的package位置 -->
|
||||
<!-- name指定关联的package -->
|
||||
<!-- level表明指记录哪个日志级别以上的日志 -->
|
||||
<!-- appender-ref指定logger向哪个文件输出日志信息 -->
|
||||
<!-- additivity为true时,logger会把根logger的日志输出地址加入进来,但logger水平不依赖于根logger -->
|
||||
<logger name="org.jcnc.jnotepad" level="${log.level}" additivity="true">
|
||||
<appender-ref ref="debugAppender"/>
|
||||
<appender-ref ref="infoAppender"/>
|
||||
<appender-ref ref="errorAppender"/>
|
||||
</logger>
|
||||
<!-- 特殊的logger,根logger -->
|
||||
<root lever="info">
|
||||
<!-- 指定默认的日志输出 -->
|
||||
<appender-ref ref="consoleAppender"/>
|
||||
</root>
|
||||
</configuration>
|
||||
Loading…
x
Reference in New Issue
Block a user