이 세상에 하나는 남기고 가자

세상에 필요한 소스코드 한줄 남기고 가자

라라벨(laravel) log 파일 권한 변경

아사마루

laravel 에서는 기본적으로 오류 로그를 "storage/logs"에 저장한다. 별다른 설정이 없다면 해당 경로에 실행 프로세스의 권한으로 로그 파일이 저장되는데 이것이 문제가 되는 경우가 있다.

예를들어 web server는 nobody 권한을 사용하고 crontab의 경우 root를 사용한다고 가정하다. crontab에 의해서 실행된 laravel 프로세스에서 오류가 발생하여 로그 파일이 생성 되었다면 이 파일의 권한은 기본적으로 root permission 에 644(-rw-r--r--)로 저장된다(서버 설정에 따라 다소 다를 수 있음). 이 상태에서 web server에서 실행한 프로세스에서 오류가 발생한다면 로그 파일에 접근할 권한이 없어 파일 저장 오류가 발생한다.

이 문제를 권한 변경없이 해결 할 수 있는 방법은 다음과 같다.

<?php
$app->configureMonologUsing(function(Monolog\Logger $monolog) {
    $filename = storage_path('/logs/laravel-' . php_sapi_name() . '.log');
    $handler = new Monolog\Handler\RotatingFileHandler($filename, 5);
    $monolog->pushHandler($handler);
});

위 내용을 bootstrap이나 Provider에 추가한다.

이 방법은 php_sapi_name() 함수를 사용해서 인터페이스 형식을 로그 파일명에 추가함으로써 shell과 web의 로그 파일을 분리하는 것이다(권한 문제와는 상관없지만 RotatingFileHandler의 두번째 인자로 5가 추가되어 일단위로 5개의 파일까지 로그를 분할 저장하도록 되어있다).

일반적인 경우라면 이 정도로 문제는 모두 해결된다. 그리고 대부분 권한을 변경하기 보다는 위 방법을 권장한다. 하지만 다음의 경우를 생각해보자.

crontab은 root에서 실행되나 작업 또는 테스트 등의 이유로 root가 아닌 사용자 계정의 shell에서 laravel 프로세스를 실행하는 경우 이미 root에 의해 로그 파일이 이미 생성되었다면 위 방법으로는 완전히 해결되지 않는다. 이러한 경우라면 아래와 같이 직접 permisson을 변경하는 방법도 가능하다.

<?php
$app->configureMonologUsing(function(Monolog\Logger $monolog) {
    $filename = storage_path('/logs/laravel-' . php_sapi_name() . '.log');
    $handler = new Monolog\Handler\RotatingFileHandler($filename, 5, \Monolog\Logger::DEBUG, true, 0666);
    $monolog->pushHandler($handler);
});

RotatingFileHandler에 추가 인자를 넘겨주어 로그 파일의 권한을 666(-rw-rw-rw-)으로 주도록 변경한 것이다.

혹 로그 파일의 수를 줄이고 싶거나 shell과 web의 로그가 분리되는 것이 싫다면 $filename 부분에서 php_sapi_name()를 제거하면 된다.

Comment