Commit 90e5436c authored by platyhouse's avatar platyhouse

# ptyRun 로그 기능 개선

## 문서 업데이트

### CLAUDE.md
- ptyRun 설명 업데이트: 로그 출력 및 저장 기능에 대한 설명 추가
- 기본 사용 예시 수정: 로그 저장 위치 및 보관 기간 명시
- 새로운 옵션 예시 추가: --no-log, --log-rotate-date, --log-rotate-count, --log-dir
- 옵션 목록에 --no-log, --log-dir, --log-rotate-date, --log-rotate-count 추가
- 로그 파일 섹션 추가: 파일명 형식, 저장 위치, 기록 내용 설명

## 스크립트 기능 개선

### ptyRun
- --no-log 옵션 추가: 로그 파일 저장을 비활성화하는 기능
- log-rotate-date 기본값 변경: 0(무제한)에서 90일로 변경
- 로그 활성화 조건 처리: $noLog 변수를 통해 로그 관련 동작 제어
- 로그 디렉토리 생성 조건화: 로그 활성화 시에만 디렉토리 생성
- 로그 로테이션 조건화: 로그 활성화 시에만 로테이션 실행
- 로그 파일 핸들링 개선: null 체크를 통한 안전한 파일 쓰기
- stdout/stderr 쓰기 로직 개선: 로그 활성화 여부에 따른 조건부 기록
- 도움말 문구 업데이트: 새로운 옵션 및 변경된 기본값 반영
parent d82e93c4
......@@ -167,10 +167,10 @@ charset=utf8mb4
### ptyRun - 스크립트 중복 실행 제어
스크립트의 중복 실행을 제어하고 타임아웃을 관리하는 래퍼 스크립트입니다.
스크립트의 중복 실행을 제어하고 타임아웃을 관리하는 래퍼 스크립트입니다. 모든 stdout/stderr 출력을 실시간으로 표시하고 로그 파일에 저장합니다.
```bash
# 기본 사용 (중복 실행 차단)
# 기본 사용 (중복 실행 차단, 로그는 ./ptyRun_logs/에 90일 보관)
ptyRun "php /path/to/script.php"
# 중복 실행 허용
......@@ -178,11 +178,29 @@ ptyRun "php script.php" --run-duplicate=true
# 최대 실행 시간 설정 (60분)
ptyRun "php script.php" --max-run-time=60
# 로그 저장 안 함
ptyRun "php script.php" --no-log
# 로그 7일만 보관
ptyRun "php script.php" --log-rotate-date=7
# 로그 10개만 보관 + 커스텀 로그 폴더
ptyRun "php script.php" --log-rotate-count=10 --log-dir=/var/log/myapp
```
**옵션:**
- `--run-duplicate=true|false`: 중복 실행 허용 여부 (기본값: **false**)
- `--max-run-time=분`: 최대 실행 시간(분), 초과 시 강제 종료 후 재실행 (기본값: 0 - 무제한)
- `--no-log`: 로그 파일 저장 비활성화 (기본값: 로그 저장 **활성화**)
- `--log-dir=경로`: 로그 저장 폴더 (기본값: 스크립트폴더/ptyRun_logs)
- `--log-rotate-date=일수`: 로그 보관 일수, 초과 시 오래된 로그 삭제 (기본값: **90**)
- `--log-rotate-count=개수`: 로그 보관 개수, 초과 시 오래된 로그 삭제 (기본값: 0 - 무제한)
**로그 파일:**
- 파일명 형식: `스크립트명_YYYYMMDD_HHMMSS.log`
- 저장 위치: 기본값은 ptyRun 스크립트가 있는 폴더의 `ptyRun_logs/`
- stdout/stderr 모두 기록 (stderr는 `[STDERR]` 프리픽스 추가)
### ptyCronBuild - 크론탭 자동 등록
......
......@@ -8,14 +8,15 @@
* 옵션:
* --run-duplicate=true|false 중복 실행 허용 여부 (기본값: false)
* --max-run-time=분 최대 실행 시간(분), 초과 시 강제 종료 후 재실행 (기본값: 0 - 무제한)
* --no-log 로그 파일 저장 비활성화 (기본값: 로그 저장 활성화)
* --log-dir=경로 로그 저장 폴더 (기본값: 스크립트폴더/ptyRun_logs)
* --log-rotate-date=일수 로그 보관 일수 (기본값: 0 - 무제한)
* --log-rotate-date=일수 로그 보관 일수 (기본값: 90)
* --log-rotate-count=개수 로그 보관 개수 (기본값: 0 - 무제한)
* --help 도움말 출력
*
* 예제:
* ./ptyRun "php /path/to/script.php" --max-run-time=20
* ./ptyRun "php script.php" --log-rotate-date=7
* ./ptyRun "php script.php" --no-log
*/
namespace platyFramework;
......@@ -35,8 +36,9 @@ if (empty($positionalArgs) || isset($options['help'])) {
echo "옵션:\n";
echo " --run-duplicate=true|false 중복 실행 허용 여부 (기본값: false)\n";
echo " --max-run-time=분 최대 실행 시간(분), 초과 시 강제 종료 후 재실행 (기본값: 0 - 무제한)\n";
echo " --no-log 로그 파일 저장 비활성화 (기본값: 로그 저장 활성화)\n";
echo " --log-dir=경로 로그 저장 폴더 (기본값: 스크립트폴더/ptyRun_logs)\n";
echo " --log-rotate-date=일수 로그 보관 일수 (기본값: 0 - 무제한)\n";
echo " --log-rotate-date=일수 로그 보관 일수 (기본값: 90)\n";
echo " --log-rotate-count=개수 로그 보관 개수 (기본값: 0 - 무제한)\n";
echo " --help 도움말 출력\n";
echo "\n";
......@@ -44,7 +46,7 @@ if (empty($positionalArgs) || isset($options['help'])) {
echo " {$argv[0]} \"php /path/to/script.php\" --max-run-time=20\n";
echo " {$argv[0]} \"php script.php\" --run-duplicate=true\n";
echo " {$argv[0]} \"./myScript.sh\"\n";
echo " {$argv[0]} \"php script.php\" --log-rotate-date=7\n";
echo " {$argv[0]} \"php script.php\" --no-log\n";
echo " {$argv[0]} \"php script.php\" --log-rotate-count=10 --log-dir=/var/log/myapp\n";
echo "\n";
exit(isset($options['help']) ? 0 : 1);
......@@ -53,12 +55,13 @@ if (empty($positionalArgs) || isset($options['help'])) {
$scriptCommand = $positionalArgs[0];
$runDuplicate = isset($options['run-duplicate']) && $options['run-duplicate'] === 'true';
$maxRunTime = isset($options['max-run-time']) ? (int)$options['max-run-time'] : 0;
$noLog = isset($options['no-log']);
$logDir = $options['log-dir'] ?? __DIR__ . '/ptyRun_logs';
$logRotateDate = isset($options['log-rotate-date']) ? (int)$options['log-rotate-date'] : 0;
$logRotateDate = isset($options['log-rotate-date']) ? (int)$options['log-rotate-date'] : 90;
$logRotateCount = isset($options['log-rotate-count']) ? (int)$options['log-rotate-count'] : 0;
// 로그 디렉토리 생성
if (!is_dir($logDir)) {
// 로그 디렉토리 생성 (로그 활성화 시에만)
if (!$noLog && !is_dir($logDir)) {
if (!mkdir($logDir, 0755, true)) {
echo "Error: 로그 디렉토리 생성 실패: {$logDir}\n";
exit(1);
......@@ -107,9 +110,11 @@ function rotateLogsByCount($logDir, $count) {
}
}
// 로그 로테이션 실행
rotateLogsByDate($logDir, $logRotateDate);
rotateLogsByCount($logDir, $logRotateCount);
// 로그 로테이션 실행 (로그 활성화 시에만)
if (!$noLog) {
rotateLogsByDate($logDir, $logRotateDate);
rotateLogsByCount($logDir, $logRotateCount);
}
// 로거 인스턴스 생성
$log = ptyCliLog("RUN", ptyCliLog::COLOR_CYAN, true);
......@@ -160,25 +165,31 @@ try {
}
}
// 로그 파일 준비
$logFile = getLogFileName($scriptCommand, $logDir);
$logHandle = fopen($logFile, 'w');
if (!$logHandle) {
throw new \Exception("로그 파일 생성 실패: {$logFile}");
}
// 로그 파일 준비 (로그 활성화 시에만)
$logFile = null;
$logHandle = null;
if (!$noLog) {
$logFile = getLogFileName($scriptCommand, $logDir);
$logHandle = fopen($logFile, 'w');
if (!$logHandle) {
throw new \Exception("로그 파일 생성 실패: {$logFile}");
}
// 로그 헤더 작성
$logHeader = sprintf(
"[%s] ptyRun 시작\n명령어: %s\n%s\n",
date('Y-m-d H:i:s'),
$scriptCommand,
str_repeat('-', 60)
);
fwrite($logHandle, $logHeader);
// 로그 헤더 작성
$logHeader = sprintf(
"[%s] ptyRun 시작\n명령어: %s\n%s\n",
date('Y-m-d H:i:s'),
$scriptCommand,
str_repeat('-', 60)
);
fwrite($logHandle, $logHeader);
}
// 스크립트 실행
$log->info("스크립트 실행: {$scriptCommand}");
$log->info("로그 파일: {$logFile}");
if ($logFile) {
$log->info("로그 파일: {$logFile}");
}
// proc_open으로 실행하여 stdout/stderr 캡처
$descriptorspec = [
......@@ -190,7 +201,7 @@ try {
$process = proc_open($scriptCommand, $descriptorspec, $pipes, null, null);
if (!is_resource($process)) {
fclose($logHandle);
if ($logHandle) fclose($logHandle);
throw new \Exception("프로세스 실행 실패");
}
......@@ -224,15 +235,19 @@ try {
// stdout 읽기
while ($line = fgets($pipes[1])) {
echo $line;
fwrite($logHandle, $line);
fflush($logHandle);
if ($logHandle) {
fwrite($logHandle, $line);
fflush($logHandle);
}
}
// stderr 읽기
while ($line = fgets($pipes[2])) {
fwrite(STDERR, $line);
fwrite($logHandle, "[STDERR] " . $line);
fflush($logHandle);
if ($logHandle) {
fwrite($logHandle, "[STDERR] " . $line);
fflush($logHandle);
}
}
// 프로세스가 종료되었으면 남은 출력 읽고 종료
......@@ -240,12 +255,12 @@ try {
// 남은 stdout 읽기
while ($line = fgets($pipes[1])) {
echo $line;
fwrite($logHandle, $line);
if ($logHandle) fwrite($logHandle, $line);
}
// 남은 stderr 읽기
while ($line = fgets($pipes[2])) {
fwrite(STDERR, $line);
fwrite($logHandle, "[STDERR] " . $line);
if ($logHandle) fwrite($logHandle, "[STDERR] " . $line);
}
break;
}
......@@ -259,15 +274,17 @@ try {
$exitCode = proc_close($process);
// 로그 푸터 작성
$logFooter = sprintf(
"\n%s\n[%s] ptyRun 종료 (Exit Code: %d)\n",
str_repeat('-', 60),
date('Y-m-d H:i:s'),
$exitCode
);
fwrite($logHandle, $logFooter);
fclose($logHandle);
// 로그 푸터 작성 (로그 활성화 시에만)
if ($logHandle) {
$logFooter = sprintf(
"\n%s\n[%s] ptyRun 종료 (Exit Code: %d)\n",
str_repeat('-', 60),
date('Y-m-d H:i:s'),
$exitCode
);
fwrite($logHandle, $logFooter);
fclose($logHandle);
}
// 락 파일 제거
if (!$runDuplicate) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment