Commit 5b0630d2 authored by platyhouse's avatar platyhouse

# Elasticsearch 인덱스 관리 도구 추가 및 파일명 변경

## 새로운 도구 추가

### Elasticsearch 인덱스 초기화 도구
- ptyElasticTruncateIndex: Elasticsearch 인덱스의 모든 문서를 삭제하는 CLI 도구 추가
  - ~/.ptyElasticConfig.ini 설정 파일을 통한 연결 정보 관리
  - 삭제 전 인덱스 정보(상태, 문서 수, 저장 용량) 표시
  - 샘플 문서 10개 미리보기 기능 제공
  - 안전을 위한 'yes' 입력 확인 절차 구현
  - 컬러 출력을 통한 경고 및 결과 강조 표시

## 파일명 변경

### 명명 규칙 개선
- ptyCatLastFile → ptyFileCatLastFile: 파일 관련 도구임을 명확히 하기 위해 접두사 'ptyFile'로 변경
parent e99df3bf
#!/usr/bin/env php
<?php
/**
* ptyElasticTruncateIndex
*
* Elasticsearch 인덱스의 모든 문서를 삭제하는 도구
* 설정 파일: ~/.ptyElasticConfig.ini
*
* Usage: ./ptyElasticTruncateIndex <index_name>
*/
// 커맨드 라인 인자 확인
if ($argc < 2) {
echo "Usage: $argv[0] <index_name>\n";
echo "Example: $argv[0] my_index\n";
echo "\nWarning: This will DELETE ALL DOCUMENTS in the index!\n";
exit(1);
}
$indexName = $argv[1];
// 설정 파일 경로
$configFile = getenv('HOME') . '/.ptyElasticConfig.ini';
// 설정 파일 확인
if (!file_exists($configFile)) {
echo "Error: 설정 파일을 찾을 수 없습니다: $configFile\n";
echo "\n설정 파일 예시:\n";
echo "[elastic]\n";
echo "host=https://localhost:9200\n";
echo "user=elastic\n";
echo "password=yourpassword\n";
exit(1);
}
// 설정 파일 읽기
$config = parse_ini_file($configFile, true);
if (!isset($config['elastic'])) {
echo "Error: 설정 파일에 [elastic] 섹션이 없습니다.\n";
exit(1);
}
$elasticConfig = $config['elastic'];
$host = $elasticConfig['host'] ?? '';
$user = $elasticConfig['user'] ?? '';
$password = $elasticConfig['password'] ?? '';
if (empty($host)) {
echo "Error: host 설정이 필요합니다.\n";
exit(1);
}
// Elasticsearch API 호출
function callElasticAPI($url, $user, $password, $method = 'GET', $body = null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
if ($body !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
}
if (!empty($user) && !empty($password)) {
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new Exception("cURL Error: $error");
}
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("HTTP Error: $httpCode - $response");
}
return $response;
}
// 바이트를 읽기 쉬운 형식으로 변환
function formatBytes($bytes) {
if ($bytes >= 1073741824) {
return number_format($bytes / 1073741824, 2) . ' GB';
} elseif ($bytes >= 1048576) {
return number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
return number_format($bytes / 1024, 2) . ' KB';
} else {
return $bytes . ' bytes';
}
}
try {
// 색상 코드 정의
$redColor = "\033[1;31m"; // 밝은 빨간색
$yellowColor = "\033[1;33m"; // 밝은 노란색
$greenColor = "\033[1;32m"; // 밝은 녹색
$cyanColor = "\033[1;36m"; // 밝은 청록색
$resetColor = "\033[0m";
echo "{$redColor}WARNING: Elasticsearch 인덱스 전체 삭제{$resetColor}\n";
echo "Host: $host\n";
echo "Index: {$yellowColor}$indexName{$resetColor}\n";
echo str_repeat("=", 100) . "\n\n";
// 1. 인덱스 정보 조회
echo "{$cyanColor}[ 인덱스 정보 ]{$resetColor}\n";
echo str_repeat("-", 100) . "\n";
$catUrl = rtrim($host, '/') . '/_cat/indices/' . urlencode($indexName) . '?v&format=json&bytes=b';
$catResponse = callElasticAPI($catUrl, $user, $password);
$catData = json_decode($catResponse, true);
if (empty($catData)) {
throw new Exception("인덱스를 찾을 수 없습니다: $indexName");
}
$indexInfo = $catData[0];
printf("상태(Health): %s\n", $indexInfo['health'] ?? 'N/A');
printf("상태(Status): %s\n", $indexInfo['status'] ?? 'N/A');
printf("문서 수: {$yellowColor}%s{$resetColor}\n", number_format($indexInfo['docs.count'] ?? 0));
printf("저장 용량: {$yellowColor}%s{$resetColor}\n", formatBytes($indexInfo['store.size'] ?? 0));
echo "\n";
// 2. 샘플 문서 10개 표시
echo "{$cyanColor}[ 샘플 문서 10개 ]{$resetColor}\n";
echo str_repeat("-", 100) . "\n";
$searchUrl = rtrim($host, '/') . '/' . urlencode($indexName) . '/_search';
$searchBody = json_encode([
'size' => 10,
'query' => ['match_all' => (object)[]]
]);
$searchResponse = callElasticAPI($searchUrl, $user, $password, 'POST', $searchBody);
$searchData = json_decode($searchResponse, true);
if (isset($searchData['hits']['hits']) && count($searchData['hits']['hits']) > 0) {
$hits = $searchData['hits']['hits'];
foreach ($hits as $idx => $hit) {
$docId = $hit['_id'];
echo "\n문서 #" . ($idx + 1) . " (ID: {$greenColor}{$docId}{$resetColor})\n";
$source = $hit['_source'];
$displayCount = 0;
foreach ($source as $key => $value) {
if ($displayCount >= 3) {
$remainingFields = count($source) - $displayCount;
if ($remainingFields > 0) {
echo " ... 외 $remainingFields 개 필드 더 있음\n";
}
break;
}
if (is_array($value) || is_object($value)) {
$valueStr = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (strlen($valueStr) > 80) {
$valueStr = substr($valueStr, 0, 80) . "...";
}
echo " $key: $valueStr\n";
} else {
$valueStr = is_string($value) ? $value : json_encode($value);
if (strlen($valueStr) > 80) {
$valueStr = substr($valueStr, 0, 80) . "...";
}
echo " $key: $valueStr\n";
}
$displayCount++;
}
}
echo "\n총 샘플 문서 수: " . count($hits) . "\n";
echo "전체 문서 수: {$yellowColor}" . number_format($searchData['hits']['total']['value'] ?? 0) . "{$resetColor}\n";
} else {
echo "문서가 없습니다.\n";
}
echo "\n" . str_repeat("=", 100) . "\n";
// 3. 삭제 확인
echo "\n{$redColor}경고: 이 작업은 인덱스 '$indexName'의 모든 문서를 삭제합니다!{$resetColor}\n";
echo "{$redColor}인덱스 자체는 삭제되지 않지만, 모든 데이터가 사라집니다.{$resetColor}\n";
echo "\n계속하시겠습니까? 삭제하려면 '{$greenColor}yes{$resetColor}'를 입력하세요: ";
$handle = fopen("php://stdin", "r");
$line = trim(fgets($handle));
fclose($handle);
if ($line !== 'yes') {
echo "\n취소되었습니다. 아무 변경도 일어나지 않았습니다.\n";
exit(0);
}
// 4. 모든 문서 삭제
echo "\n{$yellowColor}삭제 중...{$resetColor}\n";
$deleteUrl = rtrim($host, '/') . '/' . urlencode($indexName) . '/_delete_by_query?conflicts=proceed';
$deleteBody = json_encode([
'query' => ['match_all' => (object)[]]
]);
$deleteResponse = callElasticAPI($deleteUrl, $user, $password, 'POST', $deleteBody);
$deleteData = json_decode($deleteResponse, true);
// 5. 결과 표시
echo "\n" . str_repeat("=", 100) . "\n";
echo "{$greenColor}삭제 완료!{$resetColor}\n";
echo str_repeat("=", 100) . "\n";
printf("삭제된 문서 수: {$greenColor}%s{$resetColor}\n", number_format($deleteData['deleted'] ?? 0));
printf("실패한 문서 수: %s\n", number_format($deleteData['failures'] ?? 0));
printf("소요 시간: %s ms\n", number_format($deleteData['took'] ?? 0));
if (isset($deleteData['failures']) && $deleteData['failures'] > 0) {
echo "\n{$redColor}일부 문서 삭제에 실패했습니다. 로그를 확인하세요.{$resetColor}\n";
}
echo "\n";
} catch (Exception $e) {
echo "{$redColor}Error: " . $e->getMessage() . "{$resetColor}\n";
exit(1);
}
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