Многострочное регулярное выражение исключения Java в rubular

У меня есть такие журналы в приложении, и я хочу их проанализировать. Я создал регулярное выражение, но оно не работает должным образом, поскольку не анализирует полную трассировку стека в журнале. Вот мое текущее выражение:

^(?<time>[0-9]+-[0-9]+-[0-9]+\s+[0-9]+:[0-9]+:[0-9]+.[0-9]+)[\s]*(?<level>[^\s]+) (?<pid>[\d]+) --- \[(?<thread>.*)\] (?<class>[^\s]+)[\s]*:[\s]*(?<message>.*)

Эти журналы, которые я получаю из своего приложения:

2018-06-26 09:01:42.144 DEBUG 1 --- [io-9090-exec-10] c.stakater.gateway.logging.MethodLogger  : Method called: StackService.fetchStack(..)
2018-06-26 09:01:42.149 ERROR 1 --- [io-9090-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: Stack with ID: 166a998f-dbb2-44a3-be86-asd Not Found!] with root cause
 java.lang.RuntimeException: Stack with ID: 166a998f-dbb2-44a3-be86-asd Not Found!
    at com.stakater.gateway.repository.StackRepositoryService.findById(StackRepositoryService.java:29) ~[classes!/:1.0.16]
    at com.stakater.gateway.repository.StackRepositoryService$$FastClassBySpringCGLIB$$fe7f2cc7.invoke(&lt;generated&gt;) ~[classes!/:1.0.16]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) ~[spring-tx-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at com.stakater.gateway.repository.StackRepositoryService$$EnhancerBySpringCGLIB$$ddd17ba6.findById(&lt;generated&gt;) ~[classes!/:1.0.16]
    at com.stakater.gateway.service.StackService.fetchStack(StackService.java:118) ~[classes!/:1.0.16]
    at com.stakater.gateway.service.StackService$$FastClassBySpringCGLIB$$97e6baa6.invoke(&lt;generated&gt;) ~[classes!/:1.0.16]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.12.RELEASE.jar!/:4.3.12.RELEASE]
2018-06-26 09:01:42.144 DEBUG 1 --- [io-9090-exec-10] c.stakater.gateway.logging.MethodLogger  : Method called: StackService.fetchStack(..)

Вы можете видеть здесь, что регулярное выражение не соответствует полной трассировке стека. Любая помощь здесь будет оценена по достоинству.


person Waseem Hassan    schedule 26.06.2018    source источник
comment
Обратите внимание, что Rubular предназначен для тестирования регулярных выражений Onigmo/Oniguruma, Java использует библиотеку java.util.regex.   -  person Wiktor Stribiżew    schedule 26.06.2018
comment
Я собираюсь использовать это регулярное выражение в Fluent, основанном на ruby.   -  person Waseem Hassan    schedule 26.06.2018
comment
Для поддержки синтаксиса, подобного Ruby, используйте (?m)^(?<time>\d+(?:-\d+){2}\s+\d+(?::\d+){2}\.\d+)\s*(?<level>\S+) (?<pid>\d+) --- \[(?<thread>.*?)\] (?<class>\S+)\s*:\s*(?<message>.*?)(?=\g<time>|\Z). Я не уверен, какой текст должен быть в полях thread и class, пожалуйста, уточните.   -  person Wiktor Stribiżew    schedule 26.06.2018
comment
Также попробуйте ^(?<time>\d+(?:-\d+){2}\s+\d+(?::\d+){2}\.\d+)\s*(?<level>\S+) (?<pid>\d+) --- \[(?<thread>[\s\S]*?)\] (?<class>\S+)\s*:\s*(?<message>[\s\S]*?)(?=\g<time>|\Z)   -  person Wiktor Stribiżew    schedule 26.06.2018
comment
Оба работают, как и ожидалось. Но я не уверен, как вы сделали это с последним. Не могли бы вы немного объяснить?   -  person Waseem Hassan    schedule 26.06.2018


Ответы (1)


Вы можете использовать

^(?<time>\d+(?:-\d+){2}\s+\d+(?::\d+){2}\.\d+)\s*(?<level>\S+) (?<pid>\d+) --- \[(?<thread>[\s\S]*?)\] (?<class>\S+)\s*:\s*(?<message>[\s\S]*?)(?=\g<time>|\Z)

См. демонстрацию регулярного выражения.

Основные моменты:

  • . заменяется на [\s\S] (или вы можете оставить ., но использовать (?m) в начале шаблона для . для соответствия символам разрыва строки, это поведение флага m только для Ruby)
  • .* слишком жадный, используйте ленивый квантификатор, .*?
  • Чтобы соответствовать только дате, используется просмотр вперед, (?=\g<time>|\Z). Он проверяет, есть ли шаблон времени (\g<time>, подпрограмма, рекурсивно повторяющая групповой шаблон time) или конец строки (\Z) сразу после текущего местоположения.

Я также «приукрасил» [^\s] как \S, [\d] как \d, [\s] как \s и сгруппировал повторяющиеся узоры. Вы также можете заменить пробелы на \s+, чтобы убедиться, что любое количество любых пробельных символов совпадает.

person Wiktor Stribiżew    schedule 26.06.2018