[Spring] traceld ์™€ spanld๋ž€?

    Spring์—์„œ traceId์™€ spanId๋ž€ ์‰ฝ๊ฒŒ ๋งํ•ด, ๋ถ„์‚ฐ์ถ”์ ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ ๊ฐœ๋…์ด๋‹ค.

    ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์—์„œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฐ ๋ถ€๋ถ„์ด ๋™์‹œ์— ์‹คํ–‰๋˜๋ฉฐ, ์ด๋Ÿฌํ•œ ์‹คํ–‰์€ ์—ฌ๋Ÿฌ ์„œ๋น„์Šค ๊ฐ„์˜ ํ˜ธ์ถœ ๋ฐ ํ†ต์‹ ์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค. 

    ์ด๋Ÿฌํ•œ ํ™˜๊ฒฝ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋™์ž‘์„ ์ถ”์ ํ•˜๊ณ  ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ค‘์š”ํ•˜๋ฉฐ,

    ์ด๋Ÿฌํ•œ ๋™์ž‘์„ ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š”๊ฒŒ TraceID์™€ SpanID๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    TraceID์™€ SpanID๋ž€? 

    • TraceID
      : ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์—์„œ ์ „์ฒด ํŠธ๋žœ์žญ์…˜์„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ ๊ณ ์œ  ์‹๋ณ„์ž
      ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๊ฐ„์˜ ํ˜ธ์ถœ ์‚ฌ์ด์—์„œ ํ๋ฆ„์„ ์ถ”์ ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ๋ชจ๋“  ๋กœ๊ทธ ๋ฐ ์ด๋ฒคํŠธ์—๋Š” ๋™์ผํ•œ TraceID๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.  
    • SpanID
      : TraceID ๋‚ด์—์„œ ๊ฐœ๋ณ„ ์ž‘์—… ๋˜๋Š” ๋‹จ๊ณ„๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. 
      ๊ฐ ์„œ๋น„์Šค ํ˜ธ์ถœ์ด Span์œผ๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค. ์—ฌ๋Ÿฌ Span์ด ํ•˜๋‚˜์˜ Trace์— ์†ํ•  ์ˆ˜ ์žˆ๋‹ค.

    Spring์—์„œ TraceID์™€ SpanID ์‚ฌ์šฉํ•˜๊ธฐ 

    Spring์—์„œ๋Š” ์ฃผ๋กœ Spring Cloud Sleuth ์™€ ํ•จ๊ป˜ TraceId์™€ SpanId๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„์‚ฐ ์ถ”์ ์„ ๊ตฌํ˜„ํ•œ๋‹ค. 

    Spring Cloud Sleuth๋Š” ๊ฐ ์š”์ฒญ์— ๊ณ ์œ ํ•œ TraceID์™€ SpanID๋ฅผ ์ž๋™์œผ๋กœ ๋ถ€์—ฌํ•˜์—ฌ ์„œ๋น„์Šค ๊ฐ„์˜ ํ˜ธ์ถœ์„ ์ถ”์ ํ•œ๋‹ค.

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
    	private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
        @Autowired
        private SomeService someService;
        
        @GetMapping("/hello")
        public String hello() {
        	logger.info("Processing hello request");
            someService.doSomething();
            return "Hello world!";
       }
    }
    
    @Service
    public class SomeService {
    	private static final Logger logger = LoggerFactory.getLogger(SomeService.class);
        
        public void doSomething(){
        	logger.info("Doing something...");
        }
     }

    ์‹ค์ œ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ์˜ ํ™œ์šฉ ๋ฐฉ๋ฒ•

    1. ์žฅ์•  ํƒ์ง€ ๋ฐ ๋””๋ฒ„๊น… 
    : TraceID์™€ SpanID๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐœ์ƒํ•œ ์žฅ์• ๋ฅผ ์‹ ์†ํ•˜๊ฒŒ ํŒŒ์•…ํ•˜๊ณ  ๋””๋ฒ„๊น… ํ•  ์ˆ˜ ์žˆ๋‹ค. 

    ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ ์š”์ฒญ์˜ TraceID๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์š”์ฒญ์ด ์–ด๋–ค ์„œ๋น„์Šค์—์„œ ์‹คํŒจํ–ˆ๋Š”์ง€ ์‰ฝ๊ฒŒ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋‹ค. 

     

    2. ์„ฑ๋Šฅ ์ตœ์ ํ™”
    : ๊ฐ ์„œ๋น„์Šค ํ˜ธ์ถœ์˜ ์„ฑ๋Šฅ์„ ์ธก์ •ํ•˜๊ณ  ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ์‹๋ณ„ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. 
    ๊ฐ Span์—๋Š” ์‹คํ–‰ ์‹œ๊ฐ„๊ณผ ์š”์ฒญ ๋ฐ ์‘๋‹ต ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด, ์ด๋ฅผ ํ†ตํ•ด ์„œ๋น„์Šค ๊ฐ„์˜ ํ˜ธ์ถœ์„ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๋‹ค. 

     

    3. ์„œ๋น„์Šค ์ง€ํ‘œ ์ˆ˜์ง‘ 
    : TraceID์™€ SpanID๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋น„์Šค ๊ฐ„์˜ ํ˜ธ์ถœ ๊ฒฝ๋กœ๋ฅผ ์ถ”์ ํ•˜๊ณ  ๊ฐ ํ˜ธ์ถœ์˜ ์ง€ํ‘œ๋ฅผ ์ˆ˜์ง‘ํ•  ์ˆ˜ ์žˆ๋‹ค. 
    ์˜ˆ๋ฅผ ๋“ค์–ด ์„œ๋น„์Šค ๊ฐ„์˜ ํ‰๊ท  ์‘๋‹ต์‹œ๊ฐ„, ์„ฑ๊ณต๋ฅ , ์˜ค๋ฅ˜ ๋ฐœ์ƒ๋ฅ  ๋“ฑ์„ ์ถ”์ ํ•˜์—ฌ ์„œ๋น„์Šค์˜ ๊ฑด๊ฐ• ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    4. ๋ถ„์‚ฐ ์‹œ์Šคํ…œ ๋ชจ๋‹ˆํ„ฐ๋ง 
    : Zipkin๊ณผ ๊ฐ™์€ ๋ถ„์‚ฐ ์ถ”์  ์‹œ์Šคํ…œ๊ณผ ํ†ตํ•ฉํ•˜์—ฌ ์ถ”์  ๋ฐ์ดํ„ฐ๋ฅผ ์ค‘์•™ ์ง‘์ค‘์‹์œผ๋กœ ์ˆ˜์ง‘ํ•˜๊ณ  ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. 

    ์ด๋ฅผ ํ†ตํ•ด ์ „์ฒด ์‹œ์Šคํ…œ์˜ ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  ๋ณต์žกํ•œ ์„œ๋น„์Šค ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค. 


    ์ฆ‰, TraceID์™€ SpanID๋Š” ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋™์ž‘์„ ์ถ”์ ํ•˜๊ณ  ์ดํ•ดํ•˜๋Š”๋ฐ ๋งค์šฐ ์œ ์šฉํ•œ ๋„๊ตฌ์ด๋‹ค. 

    ์ด๋Ÿฌํ•œ ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์„œ๋น„์Šค๊ฐ„์˜ ํ˜ธ์ถœ์„ ์ถ”์ ํ•˜๊ณ  ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์—ฌ ์•ˆ์ •์ ์ด๊ณ  ์„ฑ๋Šฅ์ด ์šฐ์ˆ˜ํ•œ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๋Œ“๊ธ€