• Stars
    star
    135
  • Rank 269,297 (Top 6 %)
  • Language
    Java
  • Created over 10 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

spring-trace

spring-trace

์Šคํ”„๋ง Trace ์†Œ๊ฐœ

์Šคํ”„๋ง Trace๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์†์‰ฝ๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ˜ธ์ถœ ํ˜„ํ™ฉ์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ ์šฉ ์˜ˆ์‹œ

[REQ] host=0:0:0:0:0:0:0:1, method=GET, url=http://localhost:8080/test, body={username:"hello"}
|-->[Controller] HelloController.test()
|   |-->[Service] HelloService.hello(holyeye)
|   |   |-->[Repository] HelloRepository.helloQuery()
|   |   |<--[Repository] HelloRepository.helloQuery() [size=2] 1ms.
|   |<--[Service] HelloService.hello(holyeye) [<Member>] 1ms.
|<--[Controller] HelloController.test() [hello holyeye] 1ms.
[RES] host=0:0:0:0:0:0:0:1, method=GET, url=http://localhost:8080/test, status=200, time=3ms, ex=null

๋นŒ๋“œ TODO

ํ…Œ์ŠคํŠธ TODO

๊ธฐ๋Šฅ

๋กœ๊ทธ ์ถœ๋ ฅ ๊ธฐ๋Šฅ

  • ์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ ์ถœ๋ ฅ(TRACE)
  • ๋ˆ„์ ๋œ ๋กœ๊ทธ ์ถœ๋ ฅ
    • ๋„ˆ๋ฌด ๋Š๋ฆฐ ๋กœ์ง ๋กœ๊ทธ(SLOW_LOGIC) : ํŠน์ • ์‹œ๊ฐ„ ์ด์ƒ ๊ฑธ๋ฆฐ ๋ˆ„์ ๋œ ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ์™ธ ๋ฐœ์ƒ ๋กœ์ง ๋กœ๊ทธ(APP_ERROR) : ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ˆ„์ ๋œ ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

๋กœ๊ทธ ๊ธฐ๋Šฅ

  • ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ๊ฐ„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ex) hello.finds() took 2ms. [size=2]
  • ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๋ฐ˜ํ™˜๊ฐ’์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ๋ฐ˜ํ™˜ ๊ฐ’์ด null์ด๋ฉด null์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ex) [null]
    • ๋ฐ˜ํ™˜ ๊ฐ’์ด ๊ฐ์ฒด๋ฉด ๊ฐ์ฒด ํƒ€์ž…์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ex) [<Member>]
    • ๋ฐ˜ํ™˜ ๊ฐ’์ด ์ปฌ๋ ‰์…˜์ด๋‚˜ ๋ฐฐ์—ด์ด๋ฉด ์‚ฌ์ด์ฆˆ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ex) [size=10]
  • HTTP ์š”์ฒญ

    • ๋‹ค์–‘ํ•œ HTTP ์š”์ฒญ ์ •๋ณด๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน๋ณ„ํžˆ HTTP Body ์ •๋ณด๋„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

ํ•„์ˆ˜ ์ค€๋น„๋ฌผ๊ณผ ์ฃผ์˜์‚ฌํ•ญ

  • ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ๋Š” ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ ์„ค์ •๋งŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ์•„์ง์€ ์‹คํ—˜์ ์ธ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์— @EnableTrace๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

@EnableTrace(basePackages = "spring.trace.testweb")

์˜ˆ)

@Configuration
@EnableTrace(basePackages = "spring.trace.testweb")
public class TargetWebConfig extends WebMvcConfigurerAdapter {
}

๋งŒ์•ฝ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋ฉด spring.trace.web.TraceLogFilter ํ•„ํ„ฐ๋„ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

public class TestWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    //...
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{new TraceLogFilter()};
    }
}

๋‹ค์Œ์œผ๋กœ logback.xml์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{MM-dd HH:mm:ss} [%thread] %.-1level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>

    <!-- ์‹ค์‹œ๊ฐ„ TRACE -->
    <logger name="TRACE" level="trace" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
    <!-- ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ˆ์™ธ -->
    <logger name="APP_ERROR" level="info" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
    <!-- ๋Š๋ฆฐ ๋กœ์ง -->
    <logger name="SLOW_LOGIC" level="info" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
    
</configuration>

์ฐธ๊ณ : ์šด์˜์‹œ์— ๋„ˆ๋ฌด ๋งŽ์€ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ์ƒ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‚˜๋‹ค. ์šด์˜์‹œ์—๋Š” ์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ๋Š” ๋„๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ˆ์™ธ ๋กœ๊ทธ์™€ ๋Š๋ฆฐ ๋กœ์ง๋งŒ ์ถœ๋ ฅํ•˜๋„๋ก ์„ค์ •ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.


์ถœ๋ ฅ ๊ฒฐ๊ณผ

์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ

06-09 23:14:44 TRACE - [REQ] host=0:0:0:0:0:0:0:1, method=GET, url=http://localhost:8080/test, body=null
06-09 23:14:44 TRACE - |-->[Controller] HelloController.test()
06-09 23:14:44 TRACE - |   |-->[Service] HelloService.hello(holyeye)
06-09 23:14:44 TRACE - |   |   |-->[Repository] HelloRepository.helloQuery()
06-09 23:14:44 TRACE - |   |   |<--[Repository] HelloRepository.helloQuery() [void] 1ms.
06-09 23:14:44 TRACE - |   |<--[Service] HelloService.hello(holyeye) [hello holyeye] 1ms.
06-09 23:14:44 TRACE - |<--[Controller] HelloController.test() [hello holyeye] 1ms.
06-09 23:14:44 TRACE - [RES] host=0:0:0:0:0:0:0:1, method=GET, url=http://localhost:8080/test, status=200, time=3ms, ex=null

๋Š๋ฆฐ ๋กœ์ง ๋กœ๊ทธ

06-09 23:14:44 [http-nio-8080-exec-6] E SLOW_LOGIC - TRACE LOG
[REQ] host=0:0:0:0:0:0:0:1, method=GET, url=http://localhost:8080/test, body=null
|-->[Controller] HelloController.test()
|   |-->[Service] HelloService.hello(holyeye)
|   |   |-->[Repository] HelloRepository.helloQuery()
|   |   |<--[Repository] HelloRepository.helloQuery() [void] 1ms.
|   |<--[Service] HelloService.hello(holyeye) [hello holyeye] 1ms.
|<--[Controller] HelloController.test() [hello holyeye] 1ms.
[RES] host=0:0:0:0:0:0:0:1, method=GET, url=http://localhost:8080/test, status=200, time=3ms, ex=null

์˜ˆ์™ธ ๋ฐœ์ƒ ๋กœ์ง ๋กœ๊ทธ

06-09 23:28:28 [http-nio-8080-exec-9] E APP_ERROR - TRACE LOG
[REQ] host=0:0:0:0:0:0:0:1, method=GET, url=http://localhost:8080/exception, body=null
|-->[Controller] HelloController.exception()
|   |-->[Service] HelloService.helloException()
|   |<X-[Service] HelloService.helloException() Exception! java.lang.Exception: ๊ฐ•์ œ ์˜ˆ์™ธ 1ms.
|<X-[Controller] HelloController.exception() Exception! java.lang.Exception: ๊ฐ•์ œ ์˜ˆ์™ธ 1ms.
[RES] host=0:0:0:0:0:0:0:1, method=GET, url=http://localhost:8080/exception, status=200, time=6ms, ex=org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.Exception: ๊ฐ•์ œ ์˜ˆ์™ธ
[EXCEPTION] Request processing failed; nested exception is java.lang.Exception: ๊ฐ•์ œ ์˜ˆ์™ธ; trace=org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.Exception: ๊ฐ•์ œ ์˜ˆ์™ธ
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at spring.trace.web.TraceLogFilter.doFilterInternal(TraceLogFilter.java:74)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    ...

์„ค์ •

TODO

  • ์Šฌ๋กœ์šฐ ๋กœ์ง ์‹œ๊ฐ„ ์„ค์ •

๋™์ž‘ ์›๋ฆฌ

์ง€์ •ํ•œ ํŒจํ‚ค์ง€ ํ•˜์œ„ ์Šคํ”„๋ง ๋นˆ์— ๋กœ๊ทธ ์ˆ˜์ง‘์šฉ AOP(spring.trace.SpringTraceAopInterceptor)๋ฅผ ์ ์šฉํ•˜๊ณ , HTTP ์š”์ฒญ์— ๋Œ€ํ•ด์„œ๋Š” spring.trace.web.TraceLogFilter๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ถ”์ ์šฉ ๋กœ๊ทธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ด ๋กœ๊ทธ๋“ค์€ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ถœ๋ ฅ๋˜๊ธฐ๋„ ํ•˜์ง€๋งŒ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋„ˆ๋ฌด ๋Š๋ฆฐ ๋กœ์ง์ด๋ผ๊ณ  ํŒ๋‹จ๋˜๋ฉด ๋กœ๊ทธ ์ด๋ ฅ ์ „์ฒด๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋กœ๊ทธ ์ด๋ ฅ ์ „์ฒด๋ฅผ ๋ณด๊ด€ํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ ThreadLocal์— ๋กœ๊ทธ ์ •๋ณด๋ฅผ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ThreadLocal์— ๋ณด๊ด€๋œ ๋กœ๊ทธ๋Š” ์ ์ ˆํžˆ ์‹œ์ ์— ์ œ๊ฑฐ ๋ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ํ•œ ๊ธฐ๋Šฅ

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์˜ org.springframework.aop.interceptor.CustomizableTraceInterceptor์—์„œ ๋งŽ์€ ์˜๊ฐ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋ฉด์„œ ์Šคํ”„๋ง Trace ํ”„๋กœ์ ํŠธ๊ฐ€ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

TODO

  • ๋กœ๊น… ํŠธ๋žœ์žญ์…˜ ID ๋ถ€์—ฌํ•˜๊ธฐ
  • ์Šคํ”„๋ง ์„ค์ • ์ฝ์–ด์„œ ๋™์ž‘ํ•˜๊ธฐ(์‹คํ–‰ ์‹œ๊ฐ„ ์˜ต์…˜ ์ฒ˜๋ฆฌ)
  • ํŠธ๋žœ์žญ์…˜ ์ƒํƒœ ์—ฌ๋ถ€ ์ ์ ˆํžˆ ๋กœ๊ทธ ๋‚จ๊ธฐ๊ธฐ
  • @Async์—์„œ ์ ์ ˆํžˆ ๋กœ๊ทธ ๋‚จ๊ธฐ๊ธฐ
  • XML ์„ค์ • ๊ธฐ๋Šฅ
  • Interceptor ์ œ๊ณตํ•˜๊ธฐ

License

Spring Trace is released under version 2.0 of the Apache License.