如何从错误日志文件中获取每个错误?
How to get each error from error log file?
我想在日志错误文件中获取每个错误。
所以如果文件包含:
[08-Jul-2018 08:12:04 UTC] PHP Fatal error: Call to undefined method DateTime::fomat() in C:\xampp\htdocs\wordpress\wp-content\themes\theme\index.php on line 44
[08-Jul-2018 08:22:22 UTC] PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'database.table' doesn't exist' in C:\xampp\htdocs\wordpress\wp-content\themes\theme\index.php:37
Stack trace:
#0 C:\xampp\htdocs\wordpress\wp-content\themes\news_theme\index.php(37):
PDOStatement->execute()
#1 C:\xampp\htdocs\wordpress\wp-includes\template-loader.php(74):
include('C:\xampp\htdocs...')
#2 C:\xampp\htdocs\wordpress\wp-blog-header.php(19):
require_once('C:\xampp\htdocs...')
#3 C:\xampp\htdocs\wordpress\index.php(17): require('C:\xampp\htdocs...')
#4 {main}
thrown in C:\xampp\htdocs\wordpress\wp-content\themes\theme\index.php on line 37
这是两个错误,但其中一个很长,超过一行。
我想把它们的每一个错误都放在一个变量中。
我试过了:
$contents = file(get_template_directory().'/errors.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($contents as $key => $content) {
echo $key . $content . '<br>';
}
但这会获取每一行,因此第二行将存储在几个变量中,我想在一个变量中获取每个错误。
这可能吗?
您的代码只是打印 每个 输入行及其编号。
为了将输入分成块,关于每个错误,你可以采取
以下方法:
- 将整个文件读入变量。
- 执行例如
preg_match_all
就可以了。
要使用的正则表达式应该匹配:
^\[[^\]]+\]
- 初始部分 - 括号之间的日期/时间,从
行首(由于 m
选项)。
[^\n]+
- \n
以外的字符序列 - 这一行的其余部分。
现在剩下的 - 可选的非捕获组 - (?:...)?
,包含:
\nStack trace:
- "longer" 消息的开始部分,再次
从行首开始。
.+
- "middle part" - 堆栈跟踪的实际内容。
由于 s
选项,它也匹配 \n
个字符,结束这些 "middle" 行。
\nthrown
- 要匹配的最后一行 - 从行首抛出。
.+?$
- 任意数量的任意字符,直到本(最后)行的末尾。
要匹配多行和每行的开始/结束,
使用 m
和 s
正则表达式选项。
下面有一个示例程序,匹配常量文本,而不是
输入文件:
<?php
$text = <<<'EOD'
[08-Jul-2018 08:12:04 UTC] PHP Fatal error: on line 44
[08-Jul-2018 08:22:22 UTC] PHP Fatal error: in ...:37
Stack trace:
#0 C:\xampp\htdocs\wordpress\wp-content\themes\news_theme\index.php(37):
PDOStatement->execute()
#1 C:\xampp\htdocs\wordpress\wp-includes\template-loader.php(74):
include('C:\xampp\htdocs...')
thrown in ... on line 37
[08-Jul-2018 08:12:45 UTC] PHP Fatal error: on line 155
EOD;
$pattern = '/^\[[^\]]+\]\D+\d+\n(?:Stack trace:.+\nthrown.+?$)?/ms';
if (preg_match_all($pattern, $text, $matches))
print_r($matches[0]);
?>
根据需要它只打印 3 个匹配项。
编辑
如果您还有其他错误情况,请尝试另一个正则表达式:
^\[[^\]]+\][^\n]+(?:\n[^\[\n][^\n]+)*
这次,只有 m
选项。它匹配:
^\[[^\]]+\][^\n]+
- "starting" 行 - [...]...
.
(?:\n[^\[\n][^\n]+)*
- 任意数量(包括0)的非空以下
行,不是从 [
. 开始
有关最后一个正则表达式的工作示例,请参阅
https://regex101.com/r/0IUkc0/1
将文件作为 单个字符串 和 file_get_contents
读取,然后使用
$splits = preg_split('/\s+(?=^\[\d{2}-\w{3}-\d{4} \d+(?::\d{2}){2} \w{3}])/m', $contents);
模式匹配
\s+
- 1+ 白色spaces 后跟...
(?=^\[\d{2}-\w{3}-\d{4} \d+(?::\d{2}){2} \w{3}])
- 正前瞻,紧靠当前位置的右侧,需要:
^
- 行首(由于 m
修饰符)
\[
- 一个 [
字符
\d{2}-\w{3}-\d{4}
- 2 位数字,-
,3 个字符,-
,4 位数字
- 一个space
\d+
- 1+ 位数
(?::\d{2}){2}
- 出现 2 次 :
和 2 个数字(与 :\d{2}:\d{2}
相同)
- 一个space
\w{3}
- 3 个单词字符(字母、数字或 _
)
]
- 一个 ]
字符。
参见regex demo。
我想在日志错误文件中获取每个错误。
所以如果文件包含:
[08-Jul-2018 08:12:04 UTC] PHP Fatal error: Call to undefined method DateTime::fomat() in C:\xampp\htdocs\wordpress\wp-content\themes\theme\index.php on line 44
[08-Jul-2018 08:22:22 UTC] PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'database.table' doesn't exist' in C:\xampp\htdocs\wordpress\wp-content\themes\theme\index.php:37
Stack trace:
#0 C:\xampp\htdocs\wordpress\wp-content\themes\news_theme\index.php(37):
PDOStatement->execute()
#1 C:\xampp\htdocs\wordpress\wp-includes\template-loader.php(74):
include('C:\xampp\htdocs...')
#2 C:\xampp\htdocs\wordpress\wp-blog-header.php(19):
require_once('C:\xampp\htdocs...')
#3 C:\xampp\htdocs\wordpress\index.php(17): require('C:\xampp\htdocs...')
#4 {main}
thrown in C:\xampp\htdocs\wordpress\wp-content\themes\theme\index.php on line 37
这是两个错误,但其中一个很长,超过一行。
我想把它们的每一个错误都放在一个变量中。
我试过了:
$contents = file(get_template_directory().'/errors.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($contents as $key => $content) {
echo $key . $content . '<br>';
}
但这会获取每一行,因此第二行将存储在几个变量中,我想在一个变量中获取每个错误。
这可能吗?
您的代码只是打印 每个 输入行及其编号。
为了将输入分成块,关于每个错误,你可以采取 以下方法:
- 将整个文件读入变量。
- 执行例如
preg_match_all
就可以了。
要使用的正则表达式应该匹配:
^\[[^\]]+\]
- 初始部分 - 括号之间的日期/时间,从 行首(由于m
选项)。[^\n]+
-\n
以外的字符序列 - 这一行的其余部分。
现在剩下的 - 可选的非捕获组 - (?:...)?
,包含:
\nStack trace:
- "longer" 消息的开始部分,再次 从行首开始。.+
- "middle part" - 堆栈跟踪的实际内容。 由于s
选项,它也匹配\n
个字符,结束这些 "middle" 行。\nthrown
- 要匹配的最后一行 - 从行首抛出。.+?$
- 任意数量的任意字符,直到本(最后)行的末尾。
要匹配多行和每行的开始/结束,
使用 m
和 s
正则表达式选项。
下面有一个示例程序,匹配常量文本,而不是 输入文件:
<?php
$text = <<<'EOD'
[08-Jul-2018 08:12:04 UTC] PHP Fatal error: on line 44
[08-Jul-2018 08:22:22 UTC] PHP Fatal error: in ...:37
Stack trace:
#0 C:\xampp\htdocs\wordpress\wp-content\themes\news_theme\index.php(37):
PDOStatement->execute()
#1 C:\xampp\htdocs\wordpress\wp-includes\template-loader.php(74):
include('C:\xampp\htdocs...')
thrown in ... on line 37
[08-Jul-2018 08:12:45 UTC] PHP Fatal error: on line 155
EOD;
$pattern = '/^\[[^\]]+\]\D+\d+\n(?:Stack trace:.+\nthrown.+?$)?/ms';
if (preg_match_all($pattern, $text, $matches))
print_r($matches[0]);
?>
根据需要它只打印 3 个匹配项。
编辑
如果您还有其他错误情况,请尝试另一个正则表达式:
^\[[^\]]+\][^\n]+(?:\n[^\[\n][^\n]+)*
这次,只有 m
选项。它匹配:
^\[[^\]]+\][^\n]+
- "starting" 行 -[...]...
.(?:\n[^\[\n][^\n]+)*
- 任意数量(包括0)的非空以下 行,不是从[
. 开始
有关最后一个正则表达式的工作示例,请参阅 https://regex101.com/r/0IUkc0/1
将文件作为 单个字符串 和 file_get_contents
读取,然后使用
$splits = preg_split('/\s+(?=^\[\d{2}-\w{3}-\d{4} \d+(?::\d{2}){2} \w{3}])/m', $contents);
模式匹配
\s+
- 1+ 白色spaces 后跟...(?=^\[\d{2}-\w{3}-\d{4} \d+(?::\d{2}){2} \w{3}])
- 正前瞻,紧靠当前位置的右侧,需要:^
- 行首(由于m
修饰符)\[
- 一个[
字符\d{2}-\w{3}-\d{4}
- 2 位数字,-
,3 个字符,-
,4 位数字\d+
- 1+ 位数(?::\d{2}){2}
- 出现 2 次:
和 2 个数字(与:\d{2}:\d{2}
相同)\w{3}
- 3 个单词字符(字母、数字或_
)]
- 一个]
字符。
参见regex demo。