简体   繁体   English

Java中的微服务中的日志记录和异常处理

[英]Logging and Exception handling in a micro-service in Java

I am working on a microservice which does some calculation based on certain configurations stored in its own data store. 我正在研究一个微服务,它根据存储在自己的数据存储中的某些配置进行一些计算。 The calculations apis are stored via REST APIs. 计算apis通过REST API存储。 The application is a spring boot application. 该应用程序是一个Spring启动应用程序。 Now there are mainly 3 layers in the application : 现在应用程序中主要有3层:

  1. REST Controller REST控制器
  2. Service layer 服务层
  3. DAO layer - it used spring data. DAO层 - 它使用了弹簧数据。

I am planning to handle the logging and exception handling using below points: 我打算使用以下几点处理日志记录和异常处理:

  • Log each request that the service receives and response or at least the response if the status is not in 2xx series. 记录服务接收和响应的每个请求,或者如果状态不是2xx系列,则至少记录响应。

  • If there are any checked exception in either DAO layer or Service layer then log them and throw a custom exception derived from RuntimeException. 如果DAO层或服务层中存在任何已检查的异常,则记录它们并抛出从RuntimeException派生的自定义异常。

  • Have Several custom exception which should be thrown from Service layer mainly if we come across scenarios like invalid values, null values etc. 有几个自定义异常应该从Service层抛出,主要是遇到无效值,空值等情况。

  • Have a try catch block in the REST Controller and log the exception ie message along with stacktrace and return the response accordingly. 在REST控制器中尝试catch块并记录异常即消息以及stacktrace并相应地返回响应。

So overall idea is to let the RuntimeExceptions propagate all the way to REST Controller where they should be logged and accordingly the response should be sent. 因此,总的想法是让RuntimeExceptions一直传播到REST控制器,在那里应该记录它们,因此应该发送响应。 Incase of checked exceptions log them in the same method and throw custom exceptions instead. 包含已检查的异常会以相同的方法记录它们,而是抛出自定义异常。

Please suggest what should be the correct or a good approach for logging exception in such applications. 请建议在此类应用程序中记录异常的正确或良好方法。

Choose only one place to log the exceptions. 仅选择一个位置来记录例外。

In your design, if an exception occurs in DAO, it will: 在您的设计中,如果DAO中发生异常,它将:

  • Get logged in DAO 登录DAO
  • Then trigger a runtime exception, which will be caught and logged in controller 然后触发运行时异常,该异常将被捕获并记录在控制器中
  • Which should then return non-2xx response status via REST, which will trigger logging the response as per your first point 然后应该通过REST返回非2xx响应状态,这将触发根据您的第一点记录响应

So you'll have either the same information in three places, or you will have the different bits of information regarding a single error scattered in two or three places across the log. 因此,您将在三个位置获得相同的信息,或者您将获得有关分散在日志中两个或三个位置的单个错误的不同信息。

Choose a single place to log the errors, and make sure all relevant info is present at that place (ie set the underlying DAO exception as a cause of the runtime exception, and don't forget to log the runtime exception along with its cause). 选择一个位置来记录错误,并确保在该位置存在所有相关信息(即将底层DAO异常设置为运行时异常的原因,并且不要忘记记录运行时异常及其原因) 。

Write controller advice which will catch all the exceptions & logs the required contents. 编写控制器建议 ,它将捕获所有异常并记录所需内容。 You may catch exceptions here. 你可以在这里捕捉例外。 I implemented same what you asked here. 我实现了你在这里问的相同内容。

*/
/**
 * Uncaught exception handler
 * @param e - Exception
 */
@ExceptionHandler(Exception.class)
@ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public void handleError(Exception e,HttpServletRequest request, HttpServletResponse response){
    logger.error("Exception occured : {}",e);
        //logs request & response here
}

Also please check AbstractRequestLoggingFilter described here. 另请检查此处描述的AbstractRequestLoggingFilter

For all custom application specific exeptions create your own custom exception type & handle it with the help of @ExceptionHandler as specified in above code block. 对于所有自定义应用程序特定的exeptions创建自己的自定义异常类型,并在上面的代码块中指定的@ExceptionHandler的帮助下处理它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM