1. 选择合适的日志框架
优先使用SLF4J作为日志门面(统一API,解耦业务代码与具体实现),搭配Logback(SLF4J原生实现,性能优于Log4j 1.x,支持异步日志与动态配置)或Log4j2(更高性能、更好扩展性)。避免使用JCL(Jakarta Commons Logging),因其类加载问题可能导致兼容性故障。
2. 优化日志配置
INFO或WARN级别,禁用DEBUG及以下级别(减少不必要的I/O消耗);开发环境可使用DEBUG排查问题。通过配置文件(如Logback的logback.xml、Log4j2的log4j2.xml)动态调整,无需重启应用。%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n。logger.debug("User {} logged in", username)),避免在日志语句中进行字符串拼接(减少不必要的对象创建);禁止在循环中记录日志(防止大量I/O操作影响性能)。3. 实施日志轮转策略
通过logrotate(Linux系统自带工具)或日志框架内置轮转(如Logback的TimeBasedRollingPolicy、Log4j2的RollingFileAppender)管理日志文件,防止单个文件过大占用磁盘空间。
/etc/logrotate.d/java_app):/path/to/java/logs/*.log {
daily # 每天轮转
rotate 7 # 保留7天日志
compress # 压缩旧日志(节省空间)
missingok # 日志文件不存在时不报错
notifempty # 日志为空时不轮转
create 0644 root root # 新日志文件权限与所有者
}
logback.xml):<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory> <!-- 保留30天 -->
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
4. 集中式日志管理
使用ELK Stack(Elasticsearch+Logstash+Kibana)或Graylog搭建集中式日志平台,实现日志的收集、存储、搜索、可视化。
input(如Filebeat采集Java日志)、filter(解析日志格式)、output(发送至Elasticsearch);ERROR级别日志)、性能瓶颈(如接口响应时间)。5. 异步日志记录
使用Log4j2的异步Logger(AsyncLogger)或Logback的异步Appender(AsyncAppender),将日志事件写入内存队列,由单独线程异步刷新至磁盘。优势:减少日志记录对业务线程的阻塞,提升应用性能(尤其在高并发场景下)。
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" /> <!-- 关联同步FileAppender -->
<queueSize>1024</queueSize> <!-- 队列大小 -->
<discardingThreshold>0</discardingThreshold> <!-- 不丢弃日志 -->
</appender>
6. 日志监控与告警
ERROR、Exception),当出现异常日志时,通过邮件、短信或钉钉通知运维人员;Discover功能搜索特定日志(如logger.name=com.example.service),或通过Visualize创建图表(如每日错误日志数量趋势);find /path/to/logs -size +1G -exec rm -f {} \;)。7. 敏感信息脱敏
在日志记录前对敏感信息(如用户密码、身份证号、手机号、银行卡号)进行脱敏处理,避免泄露。例如:
public class SensitiveDataLogger {
public static void logUserInfo(String username, String password) {
String maskedPassword = maskSensitiveInfo(password, "*", 6, 4); // 密码中间部分替换为*
logger.info("User {} logged in, password: {}", username, maskedPassword);
}
private static String maskSensitiveInfo(String info, char maskChar, int start, int end) {
if (info == null || info.length() <= start + end) {
return info;
}
return info.substring(0, start) + repeat(maskChar, info.length() - start - end) + info.substring(info.length() - end);
}
private static String repeat(char c, int times) {
return String.valueOf(c).repeat(times);
}
}
8. 自动化清理与备份
cron定期执行清理脚本,删除超过保留期限的日志文件(如保留30天)。示例脚本(backup_java_logs.sh):#!/bin/bash
BACKUP_DIR="/path/to/backup/java_logs"
DATE=$(date +%Y%m%d)
LOG_DIR="/path/to/java/logs"
# 备份日志
cp $LOG_DIR/*.log "$BACKUP_DIR/app_$DATE.log"
# 清空原日志文件
cat /dev/null > $LOG_DIR/*.log
# 删除30天前的备份
find $BACKUP_DIR -mtime +30 -type f -name "app_*.log" -exec rm -f {} \;
配置cron任务(每天凌晨0点执行):0 0 * * * /path/to/backup_java_logs.sh