日志体系
slf4j 替换jcl、jul集成方案
提问:
假设Spring 框架要打印日志,应该选择中其中哪一个组件?
发现哪个都不能选,只能基于应用实际使用的日志组件来。不然就会日志打印会多份。
怎么找到应用实际使用的日志组件 Apache Commons Loging 解决了这个问题
Apache Commons Loging (JCL)
Commons Loging 本身只提供日志接口,具体实现在运行时动态寻找对应组件?比如:log4j、jdk14looger 等。但这种动态绑定的方式当系统特别宠大的时候会出现绑定失败的问题。现在比较流行的slf4j 基于静态绑定的方式解决了这个问题?
slf4j
sl4j 本身也只提供日志接口,与commons loging 不同的是其采用在classPath 加入以下jar包来表示具体采用哪种实现 :
- slfj-log4j12.jar (表示指定 log4j)
- slf4j-jdk14.jar(表示指定jdk Looging)
- slf4j-jcl.jar(表示指定jcl)
- log4j-slf4j-impl(表示指定log4j2)
- logback-classic(表示指定logback)
提问:
假设你们系统当中之前在用 JCL 打印日志,但这时想加入slf4j来打印日志,就会出现两类日志输出如何解决?
加入如下等JAR包jcl-over-slf4j、log4j-over-sl4j、jul-over-sl4j ,即可在使用原API的情况下,又统一至slf4j 的实现进行输出了。 .
<?xml version="1.0" encoding="UTF-8" ?> <Configuration status="error"> <!-- 定义输出源 --> <Appenders> <Console name="Console" target="SYSTEM_ERR"> <PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/> </Console> <!-- 测试环境使用--> <File name="file" fileName="logs/all.log" append="false"> <PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/> </File> <RollingFile name="rollingFile" fileName="logs/all-2.log" filePattern="logs/$${date:yyyy-MM-dd}/all-%d{yyyy-MM-dd-HH}-%i.zip"> <PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="2 KB"/> </Policies> <DefaultRolloverStrategy max="10"/> </RollingFile> <RollingFile name="errorRollingFile" fileName="logs/error2.log" filePattern="logs/$${date:yyyy-MM-dd}-error/error-%d{yyyy-MM-dd-HH}-%i.zip"> <PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/> <ThresholdFilter level="error" /> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="2 KB"/> </Policies> <DefaultRolloverStrategy max="10"/> </RollingFile> </Appenders> <!-- 具体的日志配置 name =--> <Loggers> <!-- <Logger name="org.springframework" level="error"> <AppenderRef ref="Console"/> </Logger>--> <Logger name="com" level="info"> <AppenderRef ref="rollingFile"/> <AppenderRef ref="errorRollingFile"/> </Logger> <AsyncRoot level="debug"> <AppenderRef ref="Console"/> <!-- <AppenderRef ref="file"/> <AppenderRef ref="rollingFile"/>--> </AsyncRoot> </Loggers> </Configuration>
异常处理
@ControllerAdvice public class ExceptionAdviceController { @ResponseBody @ExceptionHandler(BusinessException.class) @ResponseStatus(HttpStatus.OK) public String handleBusinessException(BusinessException exception) { HttpResult result = new HttpResult(); result.fail(exception.getCode()).message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(AuthorizationException.class) @ResponseStatus(HttpStatus.UNAUTHORIZED) public String handleAuthorizationException(AuthorizationException exception) { HttpResult result = new HttpResult(); result.fail(exception.getCode()).message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(HttpMessageNotReadableException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleHttpMessageNotReadableException(HttpMessageNotReadableException exception) { HttpResult result = new HttpResult(); logger.error("handleHttpMessageNotReadableException exception{}", exception); result.fail("400").message("HTTP_MESSAGE_NOT_READABLE"); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(MissingServletRequestParameterException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleMissingServletRequestParameterException(MissingServletRequestParameterException exception) { HttpResult result = new HttpResult(); result.fail("400").message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) { HttpResult result = new HttpResult(); // Always get the first error's default message BindingResult bindingResult = exception.getBindingResult(); ObjectError error = bindingResult.getAllErrors().get(0); String message = ""; if (error instanceof FieldError) { FieldError fieldError = (FieldError) error; message = "Field error on field '" + fieldError.getField() + "': " + fieldError.getDefaultMessage(); } else { message = error.getDefaultMessage(); } result.fail("400").message(message); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(BindException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleBindException(BindException exception) { HttpResult result = new HttpResult(); // Always get the first error's default message BindingResult bindingResult = exception.getBindingResult(); ObjectError error = bindingResult.getAllErrors().get(0); String message = ""; if (error instanceof FieldError) { FieldError fieldError = (FieldError) error; message = "Field error on field '" + fieldError.getField() + "': " + fieldError.getDefaultMessage(); } else { message = error.getDefaultMessage(); } result.fail("400").message(message); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(MissingRequestBodyParameterException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleMissingRequestBodyParameterException(MissingRequestBodyParameterException exception) { HttpResult result = new HttpResult(); result.fail("400").message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(NoSuchRequestHandlingMethodException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String handleNoSuchRequestHandlingMethodException(NoSuchRequestHandlingMethodException exception) { HttpResult result = new HttpResult(); result.fail("404").message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(NoHandlerFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String handleNoHandlerFoundException(NoHandlerFoundException exception) { HttpResult result = new HttpResult(); result.fail("404").message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(HttpRequestMethodNotSupportedException.class) @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) public String handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) { HttpResult result = new HttpResult(); result.fail("405").message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(HttpMediaTypeNotAcceptableException.class) @ResponseStatus(HttpStatus.NOT_ACCEPTABLE) public String handleHttpMediaTypeNotAcceptableException(HttpMediaTypeNotAcceptableException exception) { HttpResult result = new HttpResult(); result.fail("406").message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(HttpMediaTypeNotSupportedException.class) @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) public String handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException exception) { HttpResult result = new HttpResult(); result.fail("415").message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(ConversionNotSupportedException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public String handleConversionNotSupportedException(ConversionNotSupportedException exception) { HttpResult result = new HttpResult(); result.fail("500").message(exception.getMessage()); return JsonUtils.toJsonString(result); } @ResponseBody @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public String handleException(Exception exception) { if (exception.getClass().getName().endsWith("ClientAbortException")) { logger.warn("ClientAbortException: ", exception); }else { logger.error("Unhandled Exception: ", exception); } HttpResult result = new HttpResult(); result.fail("500").message("服务器未知异常"); return JsonUtils.toJsonString(result); } }