Разработчик сам должен позаботиться о качестве логов, информации из stacktrace будет маловато. Интересны условия возникновения ошибки. Однозначно нужны значения переменных в момент возникновения ошибки, т.к. эти данные потом нигде не получить. Примитивный пример:
log.error("Not found product code={} name={}", code, name); )
1. Через devops инструменты получения протоколов работы GrayLog и т.п.
2. Spring Actuator Log.
https://github.com/cherepakhin/vacancy_backend?tab=readme-ov-file#spring-actuator
https://www.demo2s.com/g/java/how-to-use-spring-boot-actuator-logfile-endpoint-in-java-application.html
Получение пути loggers из Actuator:
$ http http://127.0.0.1:8988/vacancy/api/actuator "logfile": { "href": "http://127.0.0.1:8988/vacancy/api/actuator/logfile", "templated": false }, "loggers": { "href": "http://127.0.0.1:8988/vacancy/api/actuator/loggers", "templated": false }, "loggers-name": { "href": "http://127.0.0.1:8988/vacancy/api/actuator/loggers/{name}", "templated": true },
Получение лога:
$ http http://127.0.0.1:8988/vacancy/api/actuator/logfile .... INFO 15088 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8980 (http) with context path '/vacancy/api' INFO 15088 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8988 (http) INFO 15088 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] INFO 15088 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.54] INFO 15088 --- [main] o.a.c.c.C.[Tomcat-1].[localhost].[/] : Initializing Spring embedded WebApplicationContext INFO 15088 --- [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 89 ms INFO 15088 --- [main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 15 endpoint(s) beneath base path '/vacancy/api/actuator' INFO 15088 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8988 (http) with context path '' ....
3. Через очень грязный хак получения лога через служебный REST, в случае когда все предыдущие способы не срабатывают. Совсем! НЕТ оперативного доступа к сервисам логирования на prod, preprod:
@RestController @RequestMapping("/log") @Api(tags = ["Log controller"]) class LogCtrl { private val logger = LoggerFactory.getLogger(this.javaClass.name) var basedir = Paths.get("").toAbsolutePath().toString() val path = "log/spring.log" @GetMapping("/") @ApiOperation("Getting log") fun getLog(): String { val current = File(basedir + File.separator + path) val currentDir = current.getAbsolutePath() logger.info(java.lang.String.format("Log file %s", currentDir)) return String(Files.readAllBytes(current.toPath())) } }
Метод как параметр получает путь к файлу лога и отправляет его содержимое. Именно, в случае ОЧЕНЬ оперативного доступа, и в ОЧЕНЬ запущенных случаях, и на "preprod" контуре. В некоторых случаях, чтобы получить кусок лога, нужно оформить кучу всяких разрешений, а оформляться они могут неделям и т.д. и т.п. В общем, самое крайнее решение(