更新说明书,调整应用日志配置方法。
This commit is contained in:
16
README.md
16
README.md
@@ -10,23 +10,19 @@ http://localhost:8080/authcenter/ping
|
||||
bash bash/build_class.sh
|
||||
|
||||
网站运行环境配置命令
|
||||
java -cp "runtime:libs/*" cc.winboll.Main -log:SEVERE
|
||||
java -cp "runtime:libs/*" Main
|
||||
|
||||
应用程序通过 ./config/config.ini 文件配置应用运行参数,日志级别与日志路径。
|
||||
应用程序配置文件兜底路径为 /sdcard/WinBoLLStudio/AuthCenterConsoleApp/config/config.ini 。
|
||||
|
||||
|
||||
公网访问接口
|
||||
https://console.winboll.cc/authcenter/ping
|
||||
|
||||
启动程序时通过参数指定日志级别,支持的级别为 ALL / FINE / INFO / WARNING / SEVERE ,示例:
|
||||
# 仅输出INFO及以上级别日志
|
||||
java -cp "runtime:libs/*" Main -v -log:INFO
|
||||
# 输出所有级别日志(默认)
|
||||
java -cp "runtime:libs/*" Main -v -log:ALL
|
||||
# 仅输出错误日志
|
||||
java -cp "runtime:libs/*" Main -v -log:SEVERE
|
||||
|
||||
# 编译Jar文件
|
||||
bash bash/build_jar.sh
|
||||
# 运行jar文件
|
||||
java -Djava.library.path=./libs -cp "jar/AuthCenter.jar:libs/*" Main -v -log:ALL
|
||||
java -Djava.library.path=./libs -cp "jar/AuthCenter.jar:libs/*" Main
|
||||
|
||||
## 程序内使用技巧
|
||||
// 1. 服务启动时发送通知
|
||||
|
||||
@@ -9,7 +9,6 @@ public class Main {
|
||||
System.out.println("启动时间:" + new Date());
|
||||
System.out.println("程序开始运行...");
|
||||
try {
|
||||
//if (!IniConfigUtils.loadConfig("/sdcard/WinBoLLStudio/Sources/AuthCenterConsoleApp/config/config.ini")) {
|
||||
if (!IniConfigUtils.loadConfig(null)) {
|
||||
System.out.println("INI配置文件加载失败,程序无法启动,强制退出");
|
||||
System.exit(1);
|
||||
@@ -20,10 +19,9 @@ public class Main {
|
||||
System.out.println("\n【日志初始化】开始初始化日志工具...");
|
||||
|
||||
// 设置日志级别与日志输出目录
|
||||
LogUtils.setGlobalLogLevel(java.util.logging.Level.ALL);
|
||||
LogUtils.initLogDir("/sdcard/WinBoLLStudio/AuthCenterConsoleApp/logs");
|
||||
LogUtils.i("Main", "日志工具初始化完成!");
|
||||
|
||||
LogUtils.i("Main", "正在处理事务...");
|
||||
|
||||
// 执行自动化测试,传递启动参数
|
||||
LogUtils.i("Main", "开始执行ConsoleCmdAutoTest自动化测试套件");
|
||||
//ConsoleCmdAutoTest.main(args);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cc.winboll;
|
||||
|
||||
import cc.winboll.util.IniConfigUtils;
|
||||
import cc.winboll.util.MainUtils;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -19,11 +20,11 @@ import java.util.logging.Logger;
|
||||
* 适配Java7语法,兼容Android API30,支持异常堆栈打印
|
||||
* 支持通过启动参数动态控制全局日志级别、-v参数控制终端同步输出
|
||||
* 功能:单文件输出+10MB大小限制+满额时间戳备份+新日志沿用authcenter.log+退出自动清lck锁文件
|
||||
* 新增:默认日志目录=指定路径,目录不存在支持用户输入,静态变量存日志路径,空路径不初始化日志处理器
|
||||
* 核心调整:读取INI配置log_path和log_level,无兜底,配置失败打系统流日志后退出程序
|
||||
* 内部日志全部使用系统流输出,避免初始化依赖冲突
|
||||
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||
* @Date 2026-01-14 00:00:00
|
||||
* @LastEditTime 2026-01-24 移除无参initLogDir,完善带参初始化逻辑
|
||||
* @LastEditTime 2026-01-27 18:10:00
|
||||
*/
|
||||
public class LogUtils {
|
||||
// ========== 静态常量(常量优先,public对外暴露,private私有) ==========
|
||||
@@ -32,78 +33,90 @@ public class LogUtils {
|
||||
public static final String LOG_FILE_SUFFIX = ".log";
|
||||
private static final int MAX_LOG_SIZE = 10 * 1024 * 1024;
|
||||
private static final SimpleDateFormat BACKUP_SDF = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
// INI配置读取键名
|
||||
private static final String INI_SECTION_GLOBAL = "GlobalConfig";
|
||||
private static final String INI_KEY_LOG_PATH = "log_path";
|
||||
private static final String INI_KEY_LOG_LEVEL = "log_level";
|
||||
|
||||
// ========== 静态成员变量 ==========
|
||||
private static ConsoleHandler consoleHandler;
|
||||
private static FileHandler fileHandler;
|
||||
private static String DEFAULT_LOG_DIR = "/sdcard/WinBoLLStudio/AuthCenterConsoleApp/logs"; // 默认日志记录
|
||||
private static String CURRENT_LOG_DIR; // 静态变量保存当前日志目录路径
|
||||
private static Level CURRENT_LOG_LEVEL; // 当前日志级别
|
||||
|
||||
// ========== 静态初始化块(全局仅执行一次) ==========
|
||||
// ========== 静态初始化块(全局仅执行一次,读INI配置初始化,失败直接退出) ==========
|
||||
static {
|
||||
if (CURRENT_LOG_DIR != null && !CURRENT_LOG_DIR.trim().endsWith("")) {
|
||||
LOGGER.setUseParentHandlers(false);
|
||||
consoleHandler = new ConsoleHandler();
|
||||
consoleHandler.setFormatter(new CustomLogFormatter());
|
||||
setGlobalLogLevel(Level.ALL);
|
||||
// 调用带参initLogDir,传入默认路径,已删除无参方法
|
||||
initLogDir(CURRENT_LOG_DIR);
|
||||
System.out.printf("[LogUtils][DEBUG] 静态初始化完成,默认日志级别ALL,单文件10MB限制+时间戳备份+lck自动清理%n");
|
||||
} else {
|
||||
System.out.printf("LOG_DIR 路径为空,LogUtils 日志类未启用。%n");
|
||||
}
|
||||
LOGGER.setUseParentHandlers(false);
|
||||
consoleHandler = new ConsoleHandler();
|
||||
consoleHandler.setFormatter(new CustomLogFormatter());
|
||||
|
||||
// 1. 从INI读取核心配置,无兜底,失败直接退出
|
||||
loadConfigFromIni();
|
||||
// 2. 初始化日志目录
|
||||
initLogDirByIni();
|
||||
// 3. 初始化日志级别
|
||||
initLogLevelByIni();
|
||||
|
||||
System.out.printf("[LogUtils][INFO] 静态初始化完成,日志级别[%s],日志目录[%s],单文件10MB限制+时间戳备份+lck自动清理%n",
|
||||
CURRENT_LOG_LEVEL.getName(), CURRENT_LOG_DIR);
|
||||
}
|
||||
|
||||
// ========== 私有化构造器,禁止外部实例化 ==========
|
||||
private LogUtils() {}
|
||||
|
||||
// ========== 核心:日志目录初始化(仅保留带参方法,空路径不初始化处理器) ==========
|
||||
public static void initLogDir(String logDirParam) {
|
||||
// 核心逻辑:日志目录路径为空,直接返回,不初始化日志处理器
|
||||
if (logDirParam == null || logDirParam.trim().isEmpty()) {
|
||||
System.err.printf("[LogUtils][WARN] 日志目录路径为空,不初始化日志文件处理器%n");
|
||||
CURRENT_LOG_DIR = null;
|
||||
return;
|
||||
// ========== 核心新增:从INI读取log_path和log_level,失败退出 ==========
|
||||
private static void loadConfigFromIni() {
|
||||
System.out.println("[LogUtils][INFO] 开始从INI读取日志核心配置");
|
||||
// 读取log_path
|
||||
String logPath = IniConfigUtils.getConfigValue(INI_SECTION_GLOBAL, INI_KEY_LOG_PATH);
|
||||
if (logPath == null || logPath.trim().isEmpty()) {
|
||||
System.err.println("[LogUtils][ERROR] INI配置GlobalConfig.log_path为空或不存在,程序退出");
|
||||
System.exit(1);
|
||||
}
|
||||
CURRENT_LOG_DIR = logPath.trim();
|
||||
|
||||
// 赋值静态变量,保存当前日志目录
|
||||
CURRENT_LOG_DIR = logDirParam.trim();
|
||||
// 读取log_level
|
||||
String logLevelStr = IniConfigUtils.getConfigValue(INI_SECTION_GLOBAL, INI_KEY_LOG_LEVEL);
|
||||
if (logLevelStr == null || logLevelStr.trim().isEmpty()) {
|
||||
System.err.println("[LogUtils][ERROR] INI配置GlobalConfig.log_level为空或不存在,程序退出");
|
||||
System.exit(1);
|
||||
}
|
||||
// 转换日志级别,失败退出
|
||||
try {
|
||||
CURRENT_LOG_LEVEL = Level.parse(logLevelStr.trim().toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.err.printf("[LogUtils][ERROR] INI配置log_level无效[%s],支持ALL/FINE/INFO/WARNING/SEVERE,程序退出%n", logLevelStr);
|
||||
System.exit(1);
|
||||
}
|
||||
System.out.printf("[LogUtils][INFO] INI配置读取成功,log_path=%s,log_level=%s%n", CURRENT_LOG_DIR, CURRENT_LOG_LEVEL.getName());
|
||||
}
|
||||
|
||||
// ========== 核心:基于INI配置初始化日志目录(无用户输入,无兜底,失败退出) ==========
|
||||
private static void initLogDirByIni() {
|
||||
File logDir = new File(CURRENT_LOG_DIR);
|
||||
|
||||
// 目录存在,直接初始化日志处理器
|
||||
if (logDir.exists()) {
|
||||
System.out.printf("[LogUtils][INFO] 日志目录存在,路径:%s%n", logDir.getAbsolutePath());
|
||||
setLogDir(CURRENT_LOG_DIR);
|
||||
return;
|
||||
// 目录不存在则创建,创建失败退出
|
||||
if (!logDir.exists()) {
|
||||
boolean mkdirOk = logDir.mkdirs();
|
||||
if (!mkdirOk) {
|
||||
System.err.printf("[LogUtils][ERROR] 日志目录[%s]不存在且创建失败,程序退出%n", CURRENT_LOG_DIR);
|
||||
System.exit(1);
|
||||
}
|
||||
System.out.printf("[LogUtils][INFO] 日志目录不存在,创建成功:%s%n", CURRENT_LOG_DIR);
|
||||
}
|
||||
// 初始化日志处理器
|
||||
setLogDir(CURRENT_LOG_DIR);
|
||||
}
|
||||
|
||||
// 目录不存在,提示用户输入,空回车沿用传入路径尝试创建
|
||||
System.err.printf("[LogUtils][WARN] 传入的日志目录[%s]不存在%n", logDir.getAbsolutePath());
|
||||
System.out.print("请输入日志目录路径(输入空行使用默认值):");
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
String inputPath = scanner.nextLine().trim();
|
||||
|
||||
// 更新最终目录&静态变量,空输入沿用原传入路径
|
||||
String finalLogDir = inputPath.isEmpty() ? CURRENT_LOG_DIR : inputPath;
|
||||
CURRENT_LOG_DIR = finalLogDir;
|
||||
File finalDir = new File(CURRENT_LOG_DIR);
|
||||
System.out.printf("[LogUtils][INFO] 最终确认日志目录:%s%n", finalDir.getAbsolutePath());
|
||||
|
||||
scanner.close();
|
||||
|
||||
// 日志路径有效,初始化日志处理器
|
||||
if (logDir.exists()) {
|
||||
System.out.printf("[LogUtils][INFO] 日志目录存在,路径:%s%n", logDir.getAbsolutePath());
|
||||
setLogDir(CURRENT_LOG_DIR);
|
||||
return;
|
||||
}
|
||||
// ========== 核心:初始化日志级别(基于INI配置) ==========
|
||||
private static void initLogLevelByIni() {
|
||||
setGlobalLogLevel(CURRENT_LOG_LEVEL);
|
||||
System.out.printf("[LogUtils][INFO] 全局日志级别初始化完成:%s%n", CURRENT_LOG_LEVEL.getName());
|
||||
}
|
||||
|
||||
// ========== 私有工具方法(内部调用,按功能归类) ==========
|
||||
private static boolean containsHandler(Handler handler) {
|
||||
System.out.printf("[LogUtils][DEBUG] 【函数调用】containsHandler,入参handler=%s%n",
|
||||
(handler == null ? "null" : handler.getClass().getName()));
|
||||
System.out.printf("[LogUtils][DEBUG] 【函数调用】containsHandler,入参handler=%s%n",
|
||||
(handler == null ? "null" : handler.getClass().getName()));
|
||||
if (handler == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -116,8 +129,8 @@ public class LogUtils {
|
||||
}
|
||||
|
||||
private static void backupOldLog(File logFile) {
|
||||
System.out.printf("[LogUtils][DEBUG] 【函数调用】backupOldLog,入参logFile=%s%n",
|
||||
(logFile == null ? "null" : logFile.getAbsolutePath()));
|
||||
System.out.printf("[LogUtils][DEBUG] 【函数调用】backupOldLog,入参logFile=%s%n",
|
||||
(logFile == null ? "null" : logFile.getAbsolutePath()));
|
||||
if (logFile != null && logFile.exists() && logFile.length() >= MAX_LOG_SIZE) {
|
||||
String backupName = LOG_FILE_PREFIX + BACKUP_SDF.format(new Date()) + LOG_FILE_SUFFIX;
|
||||
File backupFile = new File(logFile.getParent(), backupName);
|
||||
@@ -134,19 +147,10 @@ public class LogUtils {
|
||||
static void setLogDir(String logDir) {
|
||||
System.out.printf("[LogUtils][DEBUG] 【函数调用】setLogDir,入参logDir=%s%n", logDir);
|
||||
if (logDir == null || logDir.trim().isEmpty()) {
|
||||
System.err.printf("[LogUtils][WARN] 日志目录为空,跳过文件处理器初始化%n");
|
||||
return;
|
||||
System.err.printf("[LogUtils][ERROR] 日志目录为空,程序退出%n");
|
||||
System.exit(1);
|
||||
}
|
||||
File dir = new File(logDir.trim());
|
||||
if (!dir.exists()) {
|
||||
boolean success = dir.mkdirs();
|
||||
if (success) {
|
||||
System.out.printf("[LogUtils][INFO] 日志目录创建成功,路径:%s%n", dir.getAbsolutePath());
|
||||
} else {
|
||||
System.err.printf("[LogUtils][ERROR] 日志目录创建失败,路径:%s%n", dir.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final File logFile = new File(dir, "authcenter.log");
|
||||
@@ -169,8 +173,9 @@ public class LogUtils {
|
||||
}));
|
||||
System.out.println("[LogUtils][DEBUG] lck文件清理钩子已注册,程序退出自动清理");
|
||||
} catch (IOException e) {
|
||||
System.err.printf("[LogUtils][ERROR] 文件日志处理器初始化失败%n");
|
||||
System.err.printf("[LogUtils][ERROR] 文件日志处理器初始化失败,程序退出%n");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,11 +185,11 @@ public class LogUtils {
|
||||
}
|
||||
|
||||
public static void setGlobalLogLevel(Level level) {
|
||||
System.out.printf("[LogUtils][DEBUG] 【函数调用】setGlobalLogLevel,入参level=%s%n",
|
||||
(level == null ? "null" : level.getName()));
|
||||
System.out.printf("[LogUtils][DEBUG] 【函数调用】setGlobalLogLevel,入参level=%s%n",
|
||||
(level == null ? "null" : level.getName()));
|
||||
if (level == null) {
|
||||
System.err.println("[LogUtils][WARN] 日志级别为null,不执行设置");
|
||||
return;
|
||||
System.err.println("[LogUtils][ERROR] 日志级别为null,程序退出");
|
||||
System.exit(1);
|
||||
}
|
||||
LOGGER.setLevel(level);
|
||||
if (consoleHandler != null) {
|
||||
|
||||
Reference in New Issue
Block a user