저번주에 퇴근하고 집에 오는 길에 문득 그런 생각이 들었다.
'내가 직접 이걸 쓸 게 아니라, 제공하는 서비스에서 사용자에게 요구하는 것들을 어느 정도 대신해줄 수 있게 프롬프트엔지니어링 된 프롬프트를 제공해주면 어떨까?'
집에 와서 이래저래 해봤는데 생각보다 원하는 수준의 답을 못 받아서, 주말에도 이래저래 해보곤 팀내에 공유를 했는데 다들 관심도 없고, 그냥 쓰는 거 가이드 페이지 만드는 게 더 초점이 맞춰져 있는 거 같아서 주말에 시간 쓴 것도 아깝고 해서 혼자 삽질한 거 정리나 좀 해봤다.
[23-Apr-2020 14:18:49] PHP Warning: Invalid argument supplied for foreach() in /foo/bar/a.php on line 204
[23-Apr-2020 14:19:22] PHP Notice: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75
[23-Apr-2020 14:24:47] PHP Fatal Error: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7
PHP 오류 로그인데, 원래는 PHP Warning인데 다양한 상황에 대한 정규표현식을 받으려고 Notice와 Fatal Error로 수정 했다.
추출하려는 건
시간: 23-Apr-2020 14:18:49
오류 수준: PHP Warning
오류 내용: Invalid argument supplied for foreach() in /foo/bar/a.php on line 204
이렇게 세 개고, 각각 time, level, message라고 해서 추출을 하려고 했다.
ChatGPT에게는 로그에서 각 항목을 추출해달라고 해야 해서, 처음에는 그냥 내가 하는 것처럼 적었다.
질문
[23-Apr-2020 14:18:49] PHP Warning: Invalid argument supplied for foreach() in /foo/bar/a.php on line 204
[23-Apr-2020 14:19:22] PHP Notice: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75
[23-Apr-2020 14:24:47] PHP Fatal Error: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7
위 세 줄에서 정규표현식으로 항목별 값을 추출하려고 한다.
23-Apr-2020 14:18:49 = time
PHP Warning = level
Invalid argument supplied for foreach() in /foo/bar/a.php on line 204 = message
23-Apr-2020 14:19:22 = time
PHP Notice = level
unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75 = message
23-Apr-2020 14:18:49 = time
PHP Fatal Error = level
unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7 = message
위처럼 추출 하려면 어떤 정규표현식을 써야할까?
답변
다음과 같은 정규 표현식을 사용하여 각 항목에서 값을 추출할 수 있습니다.
regex
/^(\[.*?\])\s*(\w+\s+\w+):\s*(.*)$/
이 정규 표현식은 다음과 같이 작동합니다:
/^: 문자열의 시작
(\[.*?\]): 대괄호 안의 모든 문자열을 일치시킴.
\s*: 공백이 0개 이상 일치
(\w+\s+\w+): 두 개의 단어와 공백이 일치
:\s*: ":"과 공백이 일치
(.*): 문자열의 나머지 부분을 일치
$: 문자열의 끝
따라서, 다음과 같이 PHP에서 사용할 수 있습니다.
php
$log1 = "[23-Apr-2020 14:18:49] PHP Warning: Invalid argument supplied for foreach() in /foo/bar/a.php on line 204";
$log2 = "[23-Apr-2020 14:19:22] PHP Notice: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75";
$log3 = "[23-Apr-2020 14:24:47] PHP Fatal Error: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7";
$regex = "/^(\[.*?\])\s*(\w+\s+\w+):\s*(.*)$/";
if (preg_match($regex, $log1, $matches)) {
$time1 = $matches[1];
$level1 = $matches[2];
$message1 = $matches[3];
// 추출한 값 사용
echo $time1 . "\n";
echo $level1 . "\n";
echo $message1 . "\n";
}
if (preg_match($regex, $log2, $matches)) {
$time2 = $matches[1];
$level2 = $matches[2];
$message2 = $matches[3];
// 추출한 값 사용
echo $time2 . "\n";
echo $level2 . "\n";
echo $message2 . "\n";
}
if (preg_match($regex, $log3, $matches)) {
$time3 = $matches[1];
$level3 = $matches[2];
$message3 = $matches[3];
// 추출한 값 사용
echo $time3 . "\n";
echo $level3 . "\n";
echo $message3 . "\n";
}
이 코드는 각 로그 항목에서 시간, 레벨 및 메시지를 추출하여 $time, $level, $message 변수에 저장합니다. 해당 변수를 사용하여 추출한 값을 출력하거나 다른 목적으로 사용할 수 있습니다.
친절하게 PHP로 예제 코드까지 작성해줬는데, 막상 해보면 로그 한 줄은 처리가 안 된다.
[23-Apr-2020 14:18:49]
PHP Warning
Invalid argument supplied for foreach() in /foo/bar/a.php on line 204
[23-Apr-2020 14:19:22]
PHP Notice
unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75
이에 대한 것도 ChatGPT가 한 답변에 있는데,
(\w+\s+\w+): 두 개의 단어와 공백이 일치
바로 이부분이다. PHP Fatal Error는 가운데 공백이 있어서 두 개의 단어가 아니라 세 개의 단어이기 때문.
질문을 조금씩 바꾸면서 결국 어느 정도 원하는 답을 받긴 했는데, 질문 자체를 잘못하고 있다는 생각이 들었다.
그래서 질문을 간단하게 로그 + 질문 + 결과의 형태로 다시 물었다.
질문
[23-Apr-2020 14:18:49] PHP Warning: Invalid argument supplied for foreach() in /foo/bar/a.php on line 204
[23-Apr-2020 14:19:22] PHP Notice: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75
[23-Apr-2020 14:24:47] PHP Fatal Error: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7
위 로그에서 아래 내용들을 추출하는 정규표현식을 알고 싶어.
"23-Apr-2020 14:18:49"
"PHP Warning"
"Invalid argument supplied for foreach() in /foo/bar/a.php on line 204"
"23-Apr-2020 14:19:22"
"PHP Notice"
"unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75"
"23-Apr-2020 14:18:49"
"PHP Fatal Error"
"unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7"
결과
다음은 주어진 로그에서 필요한 정보를 추출하기 위한 정규표현식입니다:
(\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}).*?(PHP \w+).*?(.*)$
위의 정규표현식은 로그의 각 라인에서 다음과 같은 세 개의 정보를 추출합니다:
날짜와 시간 (23-Apr-2020 14:18:49)
로그 레벨 (PHP Warning, PHP Notice, PHP Fatal Error)
로그 메시지 (Invalid argument supplied for foreach() in /foo/bar/a.php on line 204, unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75, unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7)
위의 정규표현식을 사용하여 각 라인에서 필요한 정보를 추출할 수 있습니다. 예를 들어 Python에서는 다음과 같이 사용할 수 있습니다:
import re
log = "[23-Apr-2020 14:18:49] PHP Warning: Invalid argument supplied for foreach() in /foo/bar/a.php on line 204\n[23-Apr-2020 14:19:22] PHP Notice: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75\n[23-Apr-2020 14:24:47] PHP Fatal Error: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7"
regex = r"(\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}).*?(PHP \w+).*?(.*)$"
matches = re.findall(regex, log, re.MULTILINE)
for match in matches:
print("Date and Time:", match[0])
print("Log Level:", match[1])
print("Log Message:", match[2])
print()
이 코드는 다음 출력을 생성합니다:
Date and Time: 23-Apr-2020 14:18:49
Log Level: PHP Warning
Log Message: Invalid argument supplied for foreach() in /foo/bar/a.php on line 204
Ωate and Time: 23-Apr-2020 14:19:22
Log Level: PHP Notice
Log Message: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 75
Date and Time: 23-Apr-2020 14:24:47
Log Level:PHP Fatal Error
Log Message: unlink(/foo/bar): No such file or directory in /foo/bar/a.php on line 7
원하는 답을 받긴 했는데, 기존에는 PHP 코드를 예제로 주더니 파이썬 코드로 줬다.
계속 이거저거 더 해보니 PHP 코드보다는 파이썬 코드로 답변을 할 때가 정답이거나 정답에 가까웠다.
영어로 물어보면 나을까 싶긴 했는데, 내 입장에서는 질문 내용이 그리 어렵지 않아서 크게 영향은 없었을 거 같다.