DevLog ๐Ÿ˜ถ

[Spring] ์—๋Ÿฌ ๋กœ๊น…ํ•˜๊ธฐ - Logback์„ ์‚ฌ์šฉํ•ด์„œ ERROR ๋ ˆ๋ฒจ๋งŒ ํŒŒ์ผ๋กœ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ฒจ๋ณด์ž! ๋ณธ๋ฌธ

๊ฐœ๋ฐœ์ผ์ง€

[Spring] ์—๋Ÿฌ ๋กœ๊น…ํ•˜๊ธฐ - Logback์„ ์‚ฌ์šฉํ•ด์„œ ERROR ๋ ˆ๋ฒจ๋งŒ ํŒŒ์ผ๋กœ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ฒจ๋ณด์ž!

dolmeng2 2023. 6. 5. 19:36

๐ŸŒฑ ๋“ค์–ด๊ฐ€๊ธฐ ์ „

์ด๋ฒˆ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฏธ์…˜์—์„œ๋Š” ํ”„๋ก ํŠธ ํฌ๋ฃจ๋“ค๊ณผ ํ˜‘์—…์„ ํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์•ž์œผ๋กœ ์—๋Ÿฌ ๋กœ๊ทธ๋ฅผ ๋ณผ ์ผ์ด ๋งŽ์•„์งˆ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ์Šคํ”„๋ง์ด ๋„์›Œ์งˆ ๋•Œ์˜ ๋กœ๊ทธ๋Š” ๋ณผ ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ, ์—๋Ÿฌ์— ๋Œ€ํ•œ ๋กœ๊ทธ๋งŒ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์„œ ์ด๋ฒˆ ๋ฏธ์…˜์— ๋‚˜๋ฆ„์˜ ์‚ฝ์งˆ์„ ๊ณ๋“ค์—ฌ๊ฐ€๋ฉฐ ์ ์šฉํ•ด๋ณด์•˜๋‹ค ๐Ÿ˜Š 

 


 

๐ŸŒฑ ๋ฌธ์ œ ์ƒํ™ฉ

๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ฉฐ ์•„๋ž˜์˜ ๋ฌธ์žฅ์ด ๋‚˜๋ฅผ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ํ–ˆ๋‹ค.

nohup sudo java -jar $JAR_NAME >> $REPOSITORY/deploy.log 2> $REPOSITORY/deploy-err.log &

nohup : ํ„ฐ๋ฏธ๋„์„ ์ข…๋ฃŒํ•ด๋„ ๊ณ„์† ์‹คํ–‰ํ•˜๊ธฐ.

java -jar $JAR_NAME : jar ํŒŒ์ผ ์‹คํ–‰ํ•˜๊ธฐ.

>> : ์ถœ๋ ฅ ๋ฆฌ๋‹ค์ด๋ ‰์…˜. jar์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅํ•˜๊ณ  ์‹ถ์–ด! (deploy.log ํŒŒ์ผ๋กœ ์ €์žฅ)

- ์ฐธ๊ณ ๋กœ, >>์˜ ๊ฒฝ์šฐ ๊ธฐ์กด์˜ ํŒŒ์ผ์— ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๊ณ  ์ƒˆ๋กญ๊ฒŒ ๋ฎ์–ด์”Œ์šฐ๊ณ  ์‹ถ๋‹ค๋ฉด >์„ ์‚ฌ์šฉํ•˜์ž.

โญ๏ธ 2> : ํ‘œ์ค€ ์˜ค๋ฅ˜ ์ถœ๋ ฅ ๋ฆฌ๋‹ค์ด๋ ‰์…˜. jar์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ ์ค‘ 'ํ‘œ์ค€ ์˜ค๋ฅ˜'์— ๋Œ€ํ•ด์„œ deploy-err.log ์ €์žฅํ•˜๊ธฐ

& : ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ์‹คํ–‰ํ•˜๊ธฐ. ๊ธฐ๋ณธ์ ์œผ๋กœ ์‰˜์€ ๋ช…๋ น์–ด๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ณ„์† ๋Œ€๊ธฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ์‹คํ–‰ํ•˜์—ฌ ๋‹ค๋ฅธ ์ž‘์—…๋„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค๊ธฐ.

 

๋‚˜๋Š” ์—ฌ๊ธฐ์„œ 2> $REPOSITORY/deploy-err.log ์ด ์นœ๊ตฌ ๋•Œ๋ฌธ์— ์Šคํ”„๋ง์—์„œ ์—๋Ÿฌ ๋กœ๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด deploy-err.log๋กœ ์ €์žฅ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ... ์•„๋ฌด๋ฆฌ ํ•ด๋„ ์•„๋ฌด๊ฒƒ๋„ ์ €์žฅ์ด ๋˜์ง€ ์•Š์•„์„œ ์ ˆ๋งํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

์ด๋Š”, 2>๊ฐ€ 'ํ‘œ์ค€ ์˜ค๋ฅ˜ ์ถœ๋ ฅ'์— ๋Œ€ํ•ด์„œ ๋ฆฌ๋‹ค์ด๋ ‰์…˜์„ ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๐Ÿ’ฌ ํ‘œ์ค€ ์˜ค๋ฅ˜ ์ถœ๋ ฅ์ด ๋ญ˜๊นŒ?
๋ณดํ†ต ์‰˜์—์„œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด, ํ•ด๋‹น ๋ช…๋ น์–ด์— ๋Œ€ํ•œ ์ถœ๋ ฅ์€ ํ‘œ์ค€ ์ถœ๋ ฅ (STDOUT)์„ ํ†ตํ•ด ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค.
ํ•˜์ง€๋งŒ, ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋„์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜๋‚˜ ๊ฒฝ๊ณ , ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€์˜ ๊ฒฝ์šฐ ํ‘œ์ค€ ์ถœ๋ ฅ (STDERR)์„ ํ†ตํ•ด ๋‚˜์˜ค๊ฒŒ ๋˜๋Š”๋ฐ, ์˜ˆ๋ฅผ ๋“ค์–ด ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†๊ฑฐ๋‚˜, ์ž˜๋ชป๋œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ ๊ฐ™์€, '๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋„์ค‘'์— ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜์— ๋Œ€ํ•ด์„œ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค.

 

๋‚˜๋Š” ์Šคํ”„๋ง์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์—๋Ÿฌ์— ๋Œ€ํ•œ ๋กœ๊ทธ ํ•ธ๋“ค๋ง์„ ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

@ControllerAdvice
public class ControllerExceptionHandler {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Void> exception(Exception e) {
        log.error(e.getMessage(), e);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    }
}

๋ฌผ๋ก , ์ถ”ํ›„ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๊ณ ๋„ํ™”ํ•˜๊ฒ ์ง€๋งŒ ์šฐ์„  ๋ชจ๋“  ์˜ˆ์™ธ์— ๋Œ€ํ•ด ๋กœ๊ทธ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ด๋ ‡๊ฒŒ ์ง„ํ–‰ํ•˜์˜€๋‹ค.

์—ฌ๊ธฐ์„œ log.error()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ถœ๋ ฅํ•œ ๊ฒƒ์€ ๋‹จ์ˆœํžˆ ๋กœ๊น… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ์˜ค๋ฅ˜ ๋ ˆ๋ฒจ์˜ ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•˜๊ฒŒ ๋˜๋ฉฐ, ์‹ค์ œ ์ถœ๋ ฅ ๋Œ€์ƒ์€ ๋ณ„๋„์˜ ์„ค์ •์„ ํ†ตํ•ด์„œ ์ฒ˜๋ฆฌํ•ด์ค˜์•ผ ํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ, ๋งŒ์•ฝ ์Šคํ”„๋ง์—์„œ ํ‘œ์ค€ ์—๋Ÿฌ๋กœ ์ถœ๋ ฅํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ง„ํ–‰ํ•˜๋ฉด ๋œ๋‹ค.

@ControllerAdvice
public class ControllerExceptionHandler {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Void> exception(Exception e) {
        System.err.println(e);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    }
}
The "standard" error output stream.
This stream is already open and ready to accept output data.

err์— ๋Œ€ํ•ด์„œ ์œ„์™€ ๊ฐ™์ด 'ํ‘œ์ค€ ์—๋Ÿฌ' ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ง€์ •ํ•œ๋‹ค๊ณ  ๋˜์–ด ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ... System.out.println์„ ํ†ตํ•ด์„œ ๋กœ๊น… ์ฒ˜๋ฆฌ๋ฅผ ์•ˆ ํ•˜๋“ฏ์ด, ์—๋Ÿฌ ์—ญ์‹œ ์ €๋Ÿฐ ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๋‘๊ณ  ๋ณผ ์ˆ˜ ์—†๋‹ค.

 

 

๐Ÿ’ฌ ๊ทผ๋ฐ ์™œ System.out.println์„ ์“ฐ๋ฉด ์•ˆ ๋ ๊นŒ?

๋กœ๊น… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋กœ๊ทธ ์ถœ๋ ฅ ๋ ˆ๋ฒจ์„ ํ†ตํ•ด ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ๋”ฐ๋ฅธ ๋กœ๊ทธ ๋ ˆ๋ฒจ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, System.out.println์€ ๊ทธ๋Ÿฐ ๊ฒŒ ์•ˆ ๋œ๋‹ค.

๋ชจ๋‘ ๋™์ผํ•œ ๋กœ๊ทธ๊ฐ€ ์ถœ๋ ฅ๋˜๋‹ค ๋ณด๋‹ˆ ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ๋Š” debug ๋ ˆ๋ฒจ๋ถ€ํ„ฐ, ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ warn ๋ ˆ๋ฒจ๋ถ€ํ„ฐ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์กฐ์ ˆํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋˜ํ•œ, ๋‚ด๋ถ€์ ์œผ๋กœ synchorized๋ฅผ ํ†ตํ•ด ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฝ์ด ๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ ์œผ๋กœ๋„ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค๊ณ  ํ•œ๋‹ค.

์ž์„ธํ•œ ๊ฑด ์ด ๋ ˆํผ๋Ÿฐ์Šค์—์„œ ๋” ์ฐธ๊ณ ํ•ด๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค ๐Ÿ˜Š 

 

๊ทธ๋ ‡๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ์–ด๋–ป๊ฒŒ ์—๋Ÿฌ์— ๋Œ€ํ•œ ๋กœ๊น…์„ ์ง„ํ–‰ํ•ด์•ผ ํ• ๊นŒ?

 


 

๐ŸŒฑ Logback ํ™œ์šฉํ•˜๊ธฐ

๋ฐ”๋กœ, Logback์ด๋ผ๋Š” ์นœ๊ตฌ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

Logback์€ ๋Œ€ํ‘œ์ ์ธ ๋กœ๊น… ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ํ•˜๋‚˜๋กœ, Log4j๋ฅผ ๋Œ€์ฒดํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋‚˜์™”๋‹ค๊ณ  ํ•œ๋‹ค.

์Šคํ”„๋ง๋ถ€ํŠธ์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ dependency๋ฅผ ์„ค์ •ํ•ด์ค„ ํ•„์š”๊ฐ€ ์—†์–ด์„œ ๊ฐ„ํŽธํ•˜๋‹ค.

 

๊ธฐ๋ณธ์ ์œผ๋กœ Logback์˜ ๊ฒฝ์šฐ Logger, Appender, Layout์ด๋ผ๋Š” 3๊ฐ€์ง€์˜ ํด๋ž˜์Šค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

Logger: ๋กœ๊ทธ ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•œ ์ผ์ข…์˜ ์ปจํ…์ŠคํŠธ๋กœ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.

Appender: ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐฐ์น˜ํ•˜๋Š” ์—ญํ• ๋กœ, Logger๋Š” ๋‘˜ ์ด์ƒ์˜ Appender๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

Layout: ์ถœ๋ ฅ๋  ๋ฉ”์‹œ์ง€๋ฅผ ์ค€๋น„ํ•˜๋ฉฐ, ๋ฉ”์‹œ์ง€ ํฌ๋งคํŒ…์„ ์œ„ํ•œ ํด๋ž˜์Šค ์ƒ์„ฑ์„ ์ง€์›ํ•œ๋‹ค.

 

๋˜ํ•œ, '๋กœ๊ทธ ๋ ˆ๋ฒจ'์ด๋ผ๋Š” ๊ฐœ๋…์„ ์ดํ•ดํ•ด์•ผ ํ•˜๋Š”๋ฐ, Logback์˜ ๋กœ๊ทธ ๋ ˆ๋ฒจ์€ ์ด 5๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

Trace - Debug - info - Warn - Error ์ˆœ์ด๋ฉฐ, ๋ณดํ†ต ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค.

TRACE: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด๋ถ€์˜ ์ž‘์€ ๋‹จ์œ„ ๋™์ž‘์ด๋‚˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ, ๋ณ€์ˆ˜ ๊ฐ’ ๋“ฑ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•œ๋‹ค. (์—„์ฒญ ๋ฐฉ๋Œ€ํ•œ ์–‘์˜ ๋กœ๊ทธ๊ฐ€ ์Œ“์ด๊ฒŒ ๋œ๋‹ค.) ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.

DEBUG: Trace๋ณด๋‹ค ์กฐ๊ธˆ ๋” ์ƒ์œ„ ์ˆ˜์ค€์˜ ๋ ˆ๋ฒจ์ด๋ฉฐ, SQL์— ๋Œ€ํ•œ ๋กœ๊น…์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. (๊ฒฝํ—˜์ƒ ๋กœ์ปฌ, ๊ฐœ๋ฐœ ์„œ๋ฒ„๊นŒ์ง€ debug ๋ ˆ๋ฒจ์„ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.)

INFO: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฃผ์š” ๋™์ž‘์ด๋‚˜ ์ด๋ฒคํŠธ, ์š”์ฒญ ์ฒ˜๋ฆฌ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์—ฌ ์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ๋Š” ๋””ํดํŠธ๋กœ INFO ๋ ˆ๋ฒจ๋ถ€ํ„ฐ ๋ณด์ธ๋‹ค.

WARN: ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ๊ธฐ๋กํ•˜๋ฉฐ, ์„œ๋น„์Šค ์šด์˜ ์ž์ฒด์—๋Š” ์˜ํ–ฅ์ด ์—†์ง€๋งŒ, ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•œ ๋ถ€๋ถ„์— ๋“ค์–ด๊ฐ„๋‹ค.

ERROR: ๊ฐ€์žฅ ์‹ฌ๊ฐํ•œ ๋‹จ๊ณ„์ด๋‹ค. ์ฆ‰์‹œ ์กฐ์น˜๋ฅผ ์ทจํ•ด์•ผ ํ•˜๋Š” ์ˆ˜์ค€์˜ ๋ ˆ๋ฒจ์ด๋ผ๊ณ  ํ•œ๋‹ค.

์‚ฌ์‹ค ๊ฐœ์ธ์ ์œผ๋กœ ExceptionHandler์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ๊น…์€ ์–ด๋Š ๋ ˆ๋ฒจ์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ์ง€ ๊ณ ๋ฏผ์ธ๋ฐ...

๊ฐœ์ธ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์™€ ๊ณ„์† ๊ฐœ๋ฐœํ•˜๋Š” ๋‹จ๊ณ„์—์„œ๋Š” ERROR๋กœ ํ•ธ๋“ค๋งํ•ด์•ผ ์–ด๋–ค ์ƒํ™ฉ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ํด๋ผ์ด์–ธํŠธ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ „ํ•ด์ฃผ๊ธฐ ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์„œ ExceptionHandler์˜ ๋กœ๊น… ๋ ˆ๋ฒจ์„ ERROR๋กœ ์„ค์ •ํ•˜์˜€๋‹ค.

 

@ControllerAdvice
public class ControllerExceptionHandler {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(AuthenticationException.class)
    public ResponseEntity<Void> handlerAuthenticationException(AuthenticationException e) {
        log.error(e.getMessage(), e);
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
    }

    @ExceptionHandler(CartItemException.IllegalMember.class)
    public ResponseEntity<Void> handleException(CartItemException.IllegalMember e) {
        log.error(e.getMessage(), e);
        return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Void> exception(Exception e) {
        log.error(e.getMessage(), e);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    }
}

๊ทธ๋ž˜์„œ ์šฐ์„ , ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์˜ˆ์™ธ ์ƒํ™ฉ์— ๋Œ€ํ•ด์„œ log.error๋กœ ๋กœ๊น… ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•ด์ฃผ์—ˆ๋‹ค.

 

๋กœ๊ทธ๋ฐฑ์„ ํ™œ์šฉํ•ด์„œ ๋‚ด๊ฐ€ ํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1. ๊ธฐ๋ณธ์ ์œผ๋กœ info ํ•˜์œ„ ๋ ˆ๋ฒจ์˜ ๋กœ๊ทธ๋Š” console์— ์ถœ๋ ฅํ•˜๊ธฐ

2. โญ๏ธ ์ด๋•Œ, error ๋ ˆ๋ฒจ์˜ ๋กœ๊ทธ๋Š” ์ฝ˜์†” ๋ฐ ๋ณ„๋„์˜ ํŒŒ์ผ์— ํ•จ๊ป˜ ์ถœ๋ ฅํ•˜๊ธฐ

3. error ๋ ˆ๋ฒจ์˜ ๋กœ๊ทธ๋Š” ๋‚ ์งœ๋ณ„๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

 


 

๐ŸŒฑ Logback ๋ถ„์„ํ•˜๊ธฐ

์ฒœ์ฒœํžˆ ๋”ฐ๋ผํ•ด๋ณด์ž.

src/resources ํ•˜์œ„์— logback-spring.xml์ด๋ผ๋Š” ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

<configuration>
  <property resource="logback-variables.properties"/>

  <timestamp key="ToDay" datePattern="yyyy-MM-dd"/>

  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>
        ${LOG_PATTERN}
      </Pattern>
    </layout>
  </appender>

  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>error</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

    <file>${LOG_PATH}/${ToDay}/${LOG_FILE_NAME}.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <fileNamePattern>
        ${LOG_PATH}/%d{yyyy-MM-dd}/${LOG_FILE_NAME}_%i.log
      </fileNamePattern>
      <maxFileSize>10MB</maxFileSize>
      <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>${LOG_PATTERN}</pattern>
    </encoder>
  </appender>

  <root level="INFO">
    <appender-ref ref="FILE"/>
    <appender-ref ref="CONSOLE"/>
  </root>

</configuration>

๊ทธ๋ฆฌ๊ณ , logback-variables.properties๋ผ๋Š” ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

LOG_PATH=./logs
LOG_FILE_NAME=jwp-shopping-order
LOG_PATTERN=%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%logger{36}] - %msg%n

์ „์—ญ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ๋ณ€์ˆ˜๋กœ ๋ถ„๋ฆฌํ•ด๋‘์—ˆ๋‹ค.

 


 

๐Ÿ’ฌ ํ”„๋กœํผํ‹ฐ์™€ ํƒ€์ž„์Šคํƒฌํ”„ ์„ ์–ธํ•ด์ฃผ๊ธฐ

์ฝ”๋“œ๊ฐ€ ๊ธธ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์”ฉ ๋ถ„๋ฆฌํ•ด์„œ ์ฐจ๋ก€๋Œ€๋กœ ํŒŒ์•…ํ•ด๋ณด์ž.

๋จผ์ € ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜จ ๋‹ค์Œ, 3๋ฒˆ ์กฐ๊ฑด (๋‚ ์งœ๋ณ„๋กœ ๋กœ๊ทธ ๊ด€๋ฆฌ) ๊ตฌํ˜„ ์‹œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋‚ ์งœ ํŒจํ„ด์„ ์ •์˜ํ•ด๋‘์—ˆ๋‹ค.

 


 

๐Ÿ’ฌ ์ฝ˜์†” ์ถœ๋ ฅ์„ ์œ„ํ•œ ๋กœ๊น… ์„ค์ • ์ง„ํ–‰ํ•˜๊ธฐ

 

๋‹ค์Œ์œผ๋กœ ์ฝ˜์†” ์ถœ๋ ฅ์— ๋Œ€ํ•œ appender๋ฅผ ์ •์˜ํ•˜์˜€๋‹ค.

์ฝ˜์†” ์ถœ๋ ฅ ์‹œ ์–ด๋–ค ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๊น…์„ ํ•  ๊ฒƒ์ธ์ง€ ์ •์˜ํ•œ ๊ฒƒ์ธ๋ฐ, ์‹ค์ œ๋กœ ์ฝ˜์†” ์ถœ๋ ฅ๊ณผ ๋น„๊ตํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋ฐœ์ƒ ์‹œ๊ฐ„ - ๋กœ๊ทธ ๋ ˆ๋ฒจ - ์Šค๋ ˆ๋“œ ์ด๋ฆ„ - ๋กœ๊ทธ ๋ฐœ์ƒ ์ฃผ์ฒด์˜ ์ด๋ฆ„ - ๋ฉ”์‹œ์ง€

ํ•˜๋‚˜์”ฉ ๋–ผ์–ด์„œ ๋ณด๋‹ˆ๊นŒ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ์ฃ ...? ๐Ÿ˜‡

 


 

๐Ÿ’ฌ ํŒŒ์ผ ์ถœ๋ ฅ์„ ์œ„ํ•œ ๋กœ๊น… ์„ค์ • ์ง„ํ–‰ํ•˜๊ธฐ

์—ฌ๊ธฐ๋Š” ๊ฝค ๊ธธ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์”ฉ ํŒŒ์•…ํ•ด๋ณด์ž.

์ฝ˜์†” ๋•Œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ appender๋ฅผ ์ •์˜ํ•ด์ค€๋‹ค. 

์ด๋•Œ, ์šฐ๋ฆฌ๋Š” 2๋ฒˆ ์กฐ๊ฑด (error ๋ ˆ๋ฒจ์˜ ๋กœ๊ทธ๋Š” ํŒŒ์ผ๋กœ ์ €์žฅ)์„ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ filter๋ฅผ ์ •์˜ํ•ด์ฃผ์—ˆ๋‹ค.

๋งŒ์•ฝ ERROR ๋ ˆ๋ฒจ์ด๋ผ๋ฉด ํ—ˆ์šฉ, ์•„๋‹ˆ๋ผ๋ฉด ๊ฑฐ์ ˆํ•˜๋„๋ก ๋งŒ๋“ค์–ด์ค€ ๋ถ€๋ถ„์ด๋‹ค.

 

๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ์ •์˜ํ•œ fileSize์™€ maxHistory์— ๋”ฐ๋ผ์„œ ์ƒˆ๋กœ์šด ๋กœ๊ทธ ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜๋„๋ก ์ •์˜ํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์ƒˆ๋กœ์šด ๋กœ๊ทธํŒŒ์ผ์€ _0, _1์ด๋ผ๋Š” postfix์™€ ํ•จ๊ป˜ ๊ณ„์† ์ƒ์„ฑ๋˜๊ฒŒ ๋œ๋‹ค.

 

์—ฌ๊ธฐ์„œ file๊ณผ fileNamePattern์„ ์™œ ๋‚˜๋ˆ„์—ˆ๋‚˜ ์‹ถ์„ ๊ฒƒ์ด๋‹ค.

์šฐ์„ , rollingPolicy๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” fileNamePattern ์˜ต์…˜์„ ๊ผญ ๋„ฃ์–ด์ค˜์•ผ ํ•œ๋‹ค. (์•„๋‹ˆ๋ฉด ์˜ค๋ฅ˜๋‚จ)

 

ํ•˜์ง€๋งŒ, fileNamePattern๋งŒ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋กค๋ง ์ •์ฑ…์— ์˜ํ•ด ์ƒˆ๋กœ์šด ๋กœ๊ทธ ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜๊ธฐ ์ „, ์ฒซ ๋ฒˆ์งธ ํŒŒ์ผ์„ ์ƒ์„ฑํ•  ๋•Œ ์œ„์™€ ๊ฐ™์ด _0๋ผ๋Š” postfix๊ฐ€ ๋ถ™์–ด์„œ ์˜ˆ์˜์ง€ ์•Š๋‹ค.

์˜ˆ์จ ์ฃผ๋„ ๊ฐœ๋ฐœ์„ ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฐธ์„ ์ˆ˜ ์—†๋‹ค. (ํ˜„์žฌ ๊ฐœ๋ฐœ ์ˆ˜์ค€์—์„œ๋Š” 10MB๊ฐ€ ์ฑ„์›Œ์ง€๋ ค๋ฉด ์—„์ฒญ๋‚œ ์š”์ฒญ์ด ๋“ค์–ด์™€์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋กค๋ง ์ •์ฑ…์ด ์ ์šฉ๋˜๋Š” ๊ฑด ๊ฑฐ์˜ ๋ณด์ง€ ๋ชปํ–ˆ๋‹ค.)

๊ทธ๋ž˜์„œ ์ „์—ญ์ ์œผ๋กœ ์ฒซ ํŒŒ์ผ์ด ์ƒ์„ฑ๋  ๋•Œ๋Š” _0์„ ์ œ๊ฑฐ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ file ํƒœ๊ทธ๋ฅผ ํ†ตํ•ด ์ •์˜ํ•ด์ฃผ์—ˆ๋‹ค.

์•„๋ฌดํŠผ, file๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ์ƒˆ๋กœ์šด ๋กœ๊ทธ ํŒŒ์ผ์ด ์ƒ์„ฑ๋  ๋•Œ _0์„ ํ†ตํ•ด ๋กœ๊ทธ ํŒŒ์ผ์ด ์ƒ์„ฑ๋œ๋‹ค.

 


 

๐Ÿ’ฌ ๋ฃจํŠธ ๋กœ๊ฑฐ์— ์„ค์ •ํ•ด์ฃผ๊ธฐ

All loggers are descendants of the predefined root logger

๋ชจ๋“  ๋กœ๊ทธ์˜ ๊ฒฝ์šฐ ์‚ฌ์ „์— ์ •์˜๋œ root logger์˜ ์ž์†์ด๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์œ„์—์„œ ์—ด์‹ฌํžˆ ์ •์˜ํ•œ ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฃจํŠธ ๋กœ๊ฑฐ๋ฅผ ์„ค์ •ํ•ด์•ผ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

โญ๏ธ ๋ฃจํŠธ ๋กœ๊ฑฐ์˜ ๊ฒฝ์šฐ ํ•˜๋‚˜๋งŒ ์ง€์ •์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๋‹ค์ค‘์œผ๋กœ ์„ค์ •ํ•˜๋”๋ผ๋„ ๋งˆ์ง€๋ง‰์— ์„ ์–ธํ•œ ๊ฒƒ๋งŒ ์ฒ˜๋ฆฌ๋œ๋‹ค.

 

์ฐธ๊ณ ๋กœ, ์ด ์„ค์ •์„ ๋นผ๋ฉด ์Šคํ”„๋ง์„ ์ผค ๋•Œ ์•„๋ฌด๊ฒƒ๋„ ์•ˆ ๋œฌ๋‹ค.

๋ฉ๊ทธ๋Ÿฌ๋‹ˆ... ๋‚˜์ค‘์— ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“คํ•œํ…Œ ์ด๊ฑธ๋กœ ๋ชฐ๋ž˜ ์นด๋ฉ”๋ผ ํ•ด์ฃผ๊ณ  ์‹ถ๋‹ค ๐Ÿ˜‡

 

์•„๋ฌดํŠผ! ์ตœ์ข…์ ์œผ๋กœ ์ด๋ ‡๊ฒŒ ์ง„ํ–‰ํ•˜๊ณ  ๋‚˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์—๋Ÿฌ ๋ ˆ๋ฒจ์˜ ๋กœ๊น…์— ๋Œ€ํ•ด์„œ๋งŒ ํŽธํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์ด๊ฑด ์ฝ˜์†”์—์„œ INFO ๋ ˆ๋ฒจ ์ด์ƒ์˜ ๋กœ๊ทธ๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์ด๊ณ !

์š”๋ ‡๊ฒŒ ํŒŒ์ผ๋กœ๋„ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค ๐Ÿ˜Š

 

๊ฝค๋‚˜ ์žฌ๋ฐŒ์—ˆ๋˜ ์‚ฝ์งˆ์ด์—ˆ๋‹ค~~!

Comments