更新说明书,调整应用日志配置方法。

This commit is contained in:
2026-01-18 19:33:53 +08:00
parent a2471d5258
commit d639229bba
3 changed files with 83 additions and 84 deletions

View File

@@ -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. 服务启动时发送通知

View File

@@ -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);

View File

@@ -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=%slog_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) {