문제: PHP 설정에서 로그 기록이 비활성화되어 있는 경우
// 현재 로그 설정 확인
echo "log_errors: " . ini_get('log_errors') . "\n";
echo "error_log: " . ini_get('error_log') . "\n";
// 런타임에서 로그 활성화
ini_set('log_errors', 1);
ini_set('error_log', '/var/log/php_errors.log');
문제: 존재하지 않는 디렉토리나 잘못된 경로 지정
function setupLogPath($log_path) {
$log_dir = dirname($log_path);
// 디렉토리가 없으면 생성
if (!is_dir($log_dir)) {
mkdir($log_dir, 0755, true);
}
// 로그 파일이 없으면 생성
if (!file_exists($log_path)) {
touch($log_path);
chmod($log_path, 0644);
}
}
setupLogPath('/var/log/myapp/app.log');
문제: 웹 서버가 로그 파일에 쓸 수 없는 경우
sudo chown www-data:www-data /var/log/php_errors.log
sudo chmod 664 /var/log/php_errors.log
// 권한 확인
$log_file = '/var/log/php_errors.log';
if (!is_writable($log_file)) {
echo "로그 파일에 쓰기 권한이 없습니다.";
// 임시 로그 파일 사용
ini_set('error_log', sys_get_temp_dir() . '/php_errors.log');
}
문제: 기록하려는 에러 레벨이 설정된 레벨보다 낮은 경우
// 모든 에러 기록
error_reporting(E_ALL);
ini_set('log_errors', 1);
// 특정 레벨만 기록
error_reporting(E_ERROR | E_WARNING | E_PARSE);
// 커스텀 에러 핸들러
set_error_handler(function($severity, $message, $file, $line) {
error_log("[$severity] $message in $file on line $line");
});
문제: error_log() 함수를 잘못 사용하는 경우
// 올바른 사용법
error_log("에러 메시지");
error_log("파일에 기록", 3, "/path/to/logfile.log");
error_log("이메일 발송", 1, "admin@example.com");
// 배열이나 객체 로깅
$data = ['user_id' => 123, 'action' => 'login'];
error_log("User data: " . json_encode($data));
// 디버그 정보 포함
error_log("Error in " . __FILE__ . " on line " . __LINE__);
문제: 로그가 즉시 기록되지 않고 버퍼에 남아있는 경우
// 로그 즉시 기록
error_log("중요한 에러 발생");
// 출력 버퍼 비우기
if (ob_get_level()) {
ob_end_flush();
}
// 파일 시스템 동기화 강제
if (function_exists('fsync')) {
$handle = fopen('/var/log/php_errors.log', 'a');
fsync($handle);
fclose($handle);
}
문제: 로그 파일이 너무 커져서 기록이 중단되는 경우
function rotateLogFile($log_file, $max_size = 10485760) { // 10MB
if (file_exists($log_file) && filesize($log_file) > $max_size) {
$backup = $log_file . '.' . date('Y-m-d-H-i-s');
rename($log_file, $backup);
touch($log_file);
chmod($log_file, 0644);
}
}
// 로그 기록 전에 로테이션 확인
rotateLogFile('/var/log/myapp.log');
error_log("새로운 로그 메시지");
문제: 자체 제작한 로거에서 발생하는 문제들
class SimpleLogger {
private $log_file;
public function __construct($log_file) {
$this->log_file = $log_file;
$this->ensureLogFile();
}
private function ensureLogFile() {
$dir = dirname($this->log_file);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
if (!file_exists($this->log_file)) {
touch($this->log_file);
chmod($this->log_file, 0644);
}
}
public function log($message, $level = 'INFO') {
$timestamp = date('Y-m-d H:i:s');
$formatted = "[$timestamp] [$level] $message" . PHP_EOL;
if (file_put_contents($this->log_file, $formatted, FILE_APPEND | LOCK_EX) === false) {
error_log("로그 기록 실패: " . $this->log_file);
}
}
}
$logger = new SimpleLogger('/var/log/myapp.log');
$logger->log('테스트 메시지');
문제: Apache나 Nginx 설정이 PHP 로그 설정과 충돌하는 경우
// 현재 SAPI 확인
echo "SAPI: " . php_sapi_name() . "\n";
// 웹 서버별 로그 설정
if (php_sapi_name() === 'apache2handler') {
// Apache 환경
ini_set('error_log', '/var/log/apache2/php_errors.log');
} elseif (php_sapi_name() === 'fpm-fcgi') {
// PHP-FPM 환경
ini_set('error_log', '/var/log/php-fpm/php_errors.log');
}
문제: 디스크 공간이 부족해서 로그가 기록되지 않는 경우
function checkDiskSpace($log_file) {
$free_bytes = disk_free_space(dirname($log_file));
$free_mb = $free_bytes / 1024 / 1024;
if ($free_mb < 100) { // 100MB 미만
error_log("디스크 공간 부족: {$free_mb}MB 남음");
return false;
}
return true;
}
if (checkDiskSpace('/var/log/myapp.log')) {
error_log("정상적으로 로그 기록");
}