라라벨에서 페이지 한 번을 로드하는데 layouts.title
뷰가 거의 100번 로드되고 있었습니다. 근데 이게 어디에서 인클루드되고 있는지 찾을 수가 없었습니다. 라라벨 디버그바는 어떤 뷰가 몇 번 컴파일됐는지는 알려 주는데 어디에서 인클루드를 했는지까지는 알려 주지 않습니다.
debug_backtrace 함수
그래서 별도 코드가 필요했는데요. 인클루드되는 파일에 아래처럼 넣으면 간단하게 찾을 수 있습니다(debug_backtrace PHP 문서). 특정 함수가 어디에서 실행되는지 찾는 거라면 그 함수에 넣으면 됩니다.
print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10))
// 로그에 남기려면 아래처럼 합니다.
// print_r의 두 번째 파라미터로 true를 넘긴 것입니다.
// Log::debug는 가상의 코드입니다. 자신의 프로젝트에 맞게 사용하세요.
Log::debug(print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10), true));
이렇게 하면 아래처럼 깔끔하게 백트레이스(이 코드가 어떤 경로를 거쳐 실행됐는지 보여 주는 것)를 찍어 줍니다.
Array
(
[0] => Array
(
[file] => /project/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php
[line] => 107
[function] => require
)
...
[9] => Array
(
[file] => /project/storage/framework/views/ce86911781e5428b862d0801e580faa5538e6e02.php
[line] => 25
[function] => getTitleHtml
[class] => App\Content
[type] => ->
)
)
9번 배열에 들어 있는 값을 보면 storage/framework/views/ce86911781e5428b862d0801e580faa5538e6e02.php
파일의 25번째 라인에서 getTitleHtml()
이 호출되면서 이 뷰가 호출됐다는 것을 알 수 있습니다.
위 경우는 라라벨 뷰인데요. 그래서 ce86911781e5428b862d0801e580faa5538e6e02.php
처럼 컴파일된 결과물이 찍혔습니다. 블레이드가 아니라면 프로젝트의 PHP 파일 경로가 나올 겁니다.
라라벨 블레이드의 컴파일 결과물은 보통의 PHP 코드입니다. 이 파일의 맨 맽에는 원본 블레이드 파일 경로가 주석으로 적혀 있습니다. 아래처럼 말입니다.
<?php /**PATH /project/resources/views/unexpected-list.blade.php ENDPATH**/ ?>
매개변수 설명
DEBUG_BACKTRACE_IGNORE_ARGS
: 이 옵션을 지정하면 반환되는 배열에서 함수의 인수들은 제외됩니다. 다 나오게 하려면 0을 넣으면 됩니다. 그런데 그렇게 하니 저는 메모리 초과가 뜨는군요. 웬만하면 이 옵션을 사용하는 게 좋을 것 같습니다.10
: 보여 줄 최대 단계수를 설정하는 값입니다. 10으로 하면 10단계까지만 거슬러 올라갑니다. 깊이가 깊은 경우 필요한 정보만 보는 데 유용하겠죠. 다 나오게 하려면 0을 넣으면 됩니다. 기본값이 0이니 그냥 안 쓰면 됩니다.
로그용 코드라면
참고로 영구적으로 사용할 디버그 로깅 코드라면 print_r
을 거쳐 여러 줄로 만들기보다는 아래처럼 한 줄로 남기는 편이 나을 겁니다. 이렇게 남기면 모든 데이터를 한 줄로 남기게 됩니다. 사람이 읽기는 힘들지만 grep
같은 도구로 로그를 검색할 때는 좋습니다. (아래 코드는 라라벨에서 로그를 남기는 코드이므로 라라벨이 아닌 경우엔 다르게 하셔야 합니다.)
Log::debug('title.blade.php is rendered.', ['trace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10)]);
결론
기본적으로는 수동으로 백트레이스를 찍는 방법을 사용한 것입니다. 그래서 핵심은 debug_backtrace
함수를 기억하자는 것이죠.
(참고로 debug_print_backtrace
함수도 있습니다. 이건 바로 출력을 합니다.)
댓글 남기기