优化:基于阿里巴巴 Java 开发手册(黄山版)优化日志配置
1.异常日志>日志规约>第2条: 【强制】日志文件至少保存 15 天,因为有些异常具备以“周”为频次发生的特点。对于当天日志,以“应用名.log”来保存,保存在/{统一目录}/{应用名}/logs/目录下,过往日志格式为:{logname}.log.{保存日期},日期格式:yyyy-MM-dd 正例:以 mppserver 应用为例,日志保存/home/admin/mppserver/logs/mppserver.log,历史日志名称为 mppserver.log.2021-11-28 2.异常日志>日志规约>第3条: 【强制】根据国家法律,网络运行状态、网络安全事件、个人敏感信息操作等相关记录,留存的日志不少于六个月,并且进行网络多机备份。 3.异常日志>日志规约>第9条: 【强制】异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过关键字throws 往上抛出。 正例:logger.error("inputParams: {} and errorMessage: {}", 各类参数或者对象 toString(), e.getMessage(), e); 4.异常日志>日志规约>第12条: 【推荐】可以使用 warn 日志级别来记录用户输入参数错误的情况,避免用户投诉时,无所适从。如非必要,请不要在此场景打出 error 级别,避免频繁报警。 说明:注意日志输出的级别,error 级别只记录系统逻辑出错、异常或者重要的错误信息。
This commit is contained in:
parent
47fa1422bb
commit
44fa7266b6
@ -97,7 +97,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler(BadRequestException.class)
|
||||
public R handleBadRequestException(BadRequestException e, HttpServletRequest request) {
|
||||
log.error("请求地址'{}',自定义验证失败", request.getRequestURI(), e);
|
||||
log.warn("请求地址'{}',自定义验证失败", request.getRequestURI(), e);
|
||||
LogContextHolder.setErrorMsg(e.getMessage());
|
||||
return R.fail(HttpStatus.BAD_REQUEST.value(), e.getMessage());
|
||||
}
|
||||
@ -108,7 +108,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler(BindException.class)
|
||||
public R handleBindException(BindException e, HttpServletRequest request) {
|
||||
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||
log.warn("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||
String errorMsg = StreamUtils.join(e.getAllErrors(), DefaultMessageSourceResolvable::getDefaultMessage, ",");
|
||||
LogContextHolder.setErrorMsg(errorMsg);
|
||||
return R.fail(HttpStatus.BAD_REQUEST.value(), errorMsg);
|
||||
@ -120,7 +120,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler(ConstraintViolationException.class)
|
||||
public R constraintViolationException(ConstraintViolationException e, HttpServletRequest request) {
|
||||
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||
log.warn("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||
String errorMsg = StreamUtils.join(e.getConstraintViolations(), ConstraintViolation::getMessage, ",");
|
||||
LogContextHolder.setErrorMsg(errorMsg);
|
||||
return R.fail(HttpStatus.BAD_REQUEST.value(), errorMsg);
|
||||
@ -132,7 +132,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
|
||||
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||
log.warn("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||
String errorMsg = ExceptionUtils
|
||||
.exToNull(() -> Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
|
||||
LogContextHolder.setErrorMsg(errorMsg);
|
||||
@ -147,7 +147,7 @@ public class GlobalExceptionHandler {
|
||||
public R handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e,
|
||||
HttpServletRequest request) {
|
||||
String subMsg = StrUtil.format("参数名:'{}',期望参数类型:'{}'", e.getName(), e.getParameter().getParameterType());
|
||||
log.error("请求地址'{}',参数转换失败。方法:'{}',{}", request.getRequestURI(),
|
||||
log.warn("请求地址'{}',参数转换失败。方法:'{}',{}", request.getRequestURI(),
|
||||
Objects.requireNonNull(e.getParameter().getMethod()).getName(), subMsg, e);
|
||||
LogContextHolder.setErrorMsg(subMsg);
|
||||
return R.fail(HttpStatus.BAD_REQUEST.value(), subMsg);
|
||||
@ -170,7 +170,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
public R handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e, HttpServletRequest request) {
|
||||
log.error("请求地址'{}',上传文件失败,文件大小超过限制", request.getRequestURI(), e);
|
||||
log.warn("请求地址'{}',上传文件失败,文件大小超过限制", request.getRequestURI(), e);
|
||||
String sizeLimit = StrUtil.subBetween(e.getMessage(), "The maximum size ", " for");
|
||||
String errorMsg = String.format("请上传小于 %s MB 的文件", NumberUtil.parseLong(sizeLimit) / 1024 / 1024);
|
||||
LogContextHolder.setErrorMsg(errorMsg);
|
||||
|
@ -27,7 +27,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
@ -90,7 +89,7 @@ public class ExcelUtils {
|
||||
// 自动转换大数值
|
||||
.registerConverter(new ExcelBigNumberConverter()).sheet(sheetName).doWrite(list);
|
||||
} catch (Exception e) {
|
||||
Log.error("Export excel occurred an error.", e);
|
||||
log.error("Export excel occurred an error: {}. fileName: {}.", e.getMessage(), fileName, e);
|
||||
throw new ServiceException("导出 Excel 出现错误");
|
||||
}
|
||||
}
|
||||
|
@ -56,16 +56,16 @@ public class FileUtils {
|
||||
String originalFilename = multipartFile.getOriginalFilename();
|
||||
String extensionName = FileNameUtil.extName(originalFilename);
|
||||
|
||||
String filename;
|
||||
String fileName;
|
||||
if (isKeepOriginalFilename) {
|
||||
filename = String.format("%s-%s.%s", FileNameUtil.getPrefix(originalFilename),
|
||||
fileName = String.format("%s-%s.%s", FileNameUtil.getPrefix(originalFilename),
|
||||
DateUtil.format(LocalDateTime.now(), StringConsts.PURE_DATE_TIME_MS_PATTERN), extensionName);
|
||||
} else {
|
||||
filename = String.format("%s.%s", IdUtil.fastSimpleUUID(), extensionName);
|
||||
fileName = String.format("%s.%s", IdUtil.fastSimpleUUID(), extensionName);
|
||||
}
|
||||
|
||||
try {
|
||||
String pathname = filePath + filename;
|
||||
String pathname = filePath + fileName;
|
||||
File dest = new File(pathname).getCanonicalFile();
|
||||
// 如果父路径不存在,自动创建
|
||||
if (!dest.getParentFile().exists()) {
|
||||
@ -77,7 +77,7 @@ public class FileUtils {
|
||||
multipartFile.transferTo(dest);
|
||||
return dest;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
log.error("Upload file occurred an error: {}. fileName: {}.", e.getMessage(), fileName, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ public class QueryHelper {
|
||||
// 解析查询条件
|
||||
parse(queryAnnotation, field.getName(), fieldValue, queryWrapper);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
log.error("Build query occurred an error: {}. Query: {}, Field: {}.", e.getMessage(), query, field, e);
|
||||
} finally {
|
||||
field.setAccessible(accessible);
|
||||
}
|
||||
|
@ -36,19 +36,19 @@
|
||||
|
||||
<!-- 输出日志到文件 -->
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文件的路径及文件名 -->
|
||||
<file>${LOG_PATH}/${APP_NAME}.log</file>
|
||||
<!-- 滚动策略:基于时间归档日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 归档日志文件的路径及文件名 -->
|
||||
<fileNamePattern>${LOG_PATH}/${APP_NAME}.log.%d{yyyy-MM-dd}.gz</fileNamePattern>
|
||||
<!-- 归档日志最大保留数量(取决于 fileNamePattern 配置的规则,例如:配置归档为每天 1 个文件,那么保留 15 个也可以理解为是保留 15 天) -->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
<charset>${LOG_CHARSET}</charset>
|
||||
</encoder>
|
||||
<!-- 循环政策:基于时间和大小创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!-- 日志文件输出的文件名 -->
|
||||
<fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd, aux}/${APP_NAME}.%d{yyyy-MM-dd_HH}.%i.log</fileNamePattern>
|
||||
<!-- 日志保存 10 天(一小时生成一个,一天 24 个文件) -->
|
||||
<maxHistory>240</maxHistory>
|
||||
<!-- 单个日志文件最大的大小 -->
|
||||
<maxFileSize>20MB</maxFileSize>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<!-- 输出日志到文件(异步) -->
|
||||
|
Loading…
Reference in New Issue
Block a user