こんにちは!今回は、PHPのerror_log関数について詳しく解説していきます。
error_log関数とは?
error_log関数は、エラーメッセージをログファイル、サーバーのエラーログ、あるいはメールで指定した宛先に送信するための関数です。
基本構文
bool error_log ( string $message [, int $message_type = 0 [, string $destination [, string $additional_headers ]]] )
メッセージタイプ
- 0: PHP のシステムロガーを使用(デフォルト)
- 1: メールを送信
- 3: 指定したファイルに追加
- 4: SAPI のロガーに送信
基本的な使用例
1. システムログへの記録
<?php
// システムログに記録
error_log("データベース接続エラーが発生しました");
// より詳細な情報を含める
error_log(sprintf(
"エラー: %s, ファイル: %s, 行: %d",
"接続タイムアウト",
__FILE__,
__LINE__
));
?>
2. ファイルへの記録
<?php
$message = date('Y-m-d H:i:s') . " - エラーが発生しました\n";
error_log($message, 3, "app_error.log");
?>
実践的な使用例
1. エラーログクラス
<?php
class ErrorLogger {
private $logFile;
private $emailTo;
public function __construct($logFile, $emailTo = null) {
$this->logFile = $logFile;
$this->emailTo = $emailTo;
}
public function log($message, $level = 'ERROR') {
$logMessage = sprintf(
"[%s] [%s] %s\n",
date('Y-m-d H:i:s'),
$level,
$message
);
// ファイルに記録
error_log($logMessage, 3, $this->logFile);
// 重要なエラーの場合はメール送信
if ($level === 'CRITICAL' && $this->emailTo) {
$this->sendEmail($message);
}
}
private function sendEmail($message) {
$headers = 'From: system@example.com' . "\r\n" .
'Reply-To: system@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
error_log($message, 1, $this->emailTo, $headers);
}
}
// 使用例
$logger = new ErrorLogger('app.log', 'admin@example.com');
$logger->log("データベース接続エラー", 'CRITICAL');
?>
2. 例外ハンドリング
<?php
class ExceptionHandler {
private static $logger;
public static function initialize($logFile) {
self::$logger = new ErrorLogger($logFile);
set_exception_handler([self::class, 'handleException']);
set_error_handler([self::class, 'handleError']);
}
public static function handleException($exception) {
$message = sprintf(
"例外: %s\nファイル: %s\n行: %d\nスタックトレース:\n%s",
$exception->getMessage(),
$exception->getFile(),
$exception->getLine(),
$exception->getTraceAsString()
);
self::$logger->log($message, 'EXCEPTION');
}
public static function handleError($errno, $errstr, $errfile, $errline) {
$message = sprintf(
"エラー(%d): %s\nファイル: %s\n行: %d",
$errno,
$errstr,
$errfile,
$errline
);
self::$logger->log($message, 'ERROR');
}
}
?>
3. アプリケーションログ
<?php
class ApplicationLogger {
private $context;
private $logFile;
public function __construct($context, $logFile) {
$this->context = $context;
$this->logFile = $logFile;
}
public function info($message) {
$this->log($message, 'INFO');
}
public function warning($message) {
$this->log($message, 'WARNING');
}
public function error($message) {
$this->log($message, 'ERROR');
}
private function log($message, $level) {
$logMessage = sprintf(
"[%s] [%s] [%s] %s\n",
date('Y-m-d H:i:s'),
$level,
$this->context,
$message
);
error_log($logMessage, 3, $this->logFile);
}
}
// 使用例
$logger = new ApplicationLogger('UserService', 'application.log');
$logger->info('ユーザーがログインしました');
$logger->warning('パスワード試行回数が多すぎます');
$logger->error('ユーザー認証に失敗しました');
?>
高度な使用例
1. ログローテーション
<?php
class RotatingLogger {
private $baseLogFile;
private $maxSize;
public function __construct($baseLogFile, $maxSize = 5242880) { // 5MB
$this->baseLogFile = $baseLogFile;
$this->maxSize = $maxSize;
}
public function log($message) {
$this->rotateIfNeeded();
$logMessage = sprintf(
"[%s] %s\n",
date('Y-m-d H:i:s'),
$message
);
error_log($logMessage, 3, $this->baseLogFile);
}
private function rotateIfNeeded() {
if (!file_exists($this->baseLogFile)) {
return;
}
if (filesize($this->baseLogFile) >= $this->maxSize) {
$backup = $this->baseLogFile . '.' . date('Y-m-d-H-i-s');
rename($this->baseLogFile, $backup);
}
}
}
?>
2. JSON形式のログ
<?php
class JsonLogger {
private $logFile;
public function __construct($logFile) {
$this->logFile = $logFile;
}
public function log($message, array $context = []) {
$logData = [
'timestamp' => date('Y-m-d H:i:s'),
'message' => $message,
'context' => $context,
'server' => $_SERVER['SERVER_NAME'] ?? 'unknown',
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown'
];
$jsonLog = json_encode($logData) . "\n";
error_log($jsonLog, 3, $this->logFile);
}
}
?>
注意点とベストプラクティス
1. パフォーマンスへの配慮
<?php
class BufferedLogger {
private $buffer = [];
private $maxBufferSize = 100;
private $logFile;
public function __construct($logFile) {
$this->logFile = $logFile;
register_shutdown_function([$this, 'flush']);
}
public function log($message) {
$this->buffer[] = sprintf(
"[%s] %s\n",
date('Y-m-d H:i:s'),
$message
);
if (count($this->buffer) >= $this->maxBufferSize) {
$this->flush();
}
}
public function flush() {
if (!empty($this->buffer)) {
error_log(implode('', $this->buffer), 3, $this->logFile);
$this->buffer = [];
}
}
}
?>
2. セキュリティ考慮
<?php
class SecureLogger {
public function log($message, $sensitiveData = false) {
if ($sensitiveData) {
// 機密データはマスク
$message = $this->maskSensitiveData($message);
}
error_log($message);
}
private function maskSensitiveData($message) {
// パスワードなどの機密情報をマスク
return preg_replace(
'/password[:=]\s*[^\s,]+/i',
'password=*****',
$message
);
}
}
?>
まとめ
error_log関数の主なポイント:
- 複数のログ出力先に対応
- シンプルで使いやすい
- エラーハンドリングシステムの基礎として有用
- カスタマイズ可能な柔軟性
活用シーン:
- アプリケーションログの記録
- エラー監視
- デバッグ情報の収集
- システム診断
注意点:
- ログローテーションの実装
- パフォーマンスへの配慮
- セキュリティ考慮
- ディスク容量の管理
これらの点を理解して使用することで、より効果的なログ管理が実装できます。
以上で、error_log関数の解説を終わります。
ご質問やご不明点があれば、お気軽にコメントしてください!