diff --git a/app/Commands/NaverWorker.php b/app/Commands/NaverWorker.php index ef66274..0d7d274 100644 --- a/app/Commands/NaverWorker.php +++ b/app/Commands/NaverWorker.php @@ -17,6 +17,9 @@ class NaverWorker extends BaseCommand // DB 객체를 담을 변수 선언 protected $db; + protected $redisHost; + protected $redisPort; + protected $redisDatabase; public function run(array $params) { @@ -29,13 +32,13 @@ class NaverWorker extends BaseCommand $redis = new \Redis(); try { // 두 가지 환경 변수 형식 지원 (REDIS_HOST 또는 redis.default.host) - $redisHost = getenv('REDIS_HOST') ?: (getenv('redis.default.host') ?: '127.0.0.1'); - $redisPort = getenv('REDIS_PORT') ?: (getenv('redis.default.port') ?: 6379); - $redisDatabase = getenv('REDIS_DATABASE') ?: (getenv('redis.default.database') ?: 9); + $this->redisHost = getenv('REDIS_HOST') ?: (getenv('redis.default.host') ?: '127.0.0.1'); + $this->redisPort = getenv('REDIS_PORT') ?: (getenv('redis.default.port') ?: 6379); + $this->redisDatabase = getenv('REDIS_DATABASE') ?: (getenv('redis.default.database') ?: 9); - $redis->connect($redisHost, (int)$redisPort); - $redis->select((int)$redisDatabase); - CLI::write(CLI::color('🟢 Naver Worker running... (Redis: ' . $redisHost . ':' . $redisPort . ' DB:' . $redisDatabase . ')', 'green')); + $redis->connect($this->redisHost, (int)$this->redisPort); + $redis->select((int)$this->redisDatabase); + CLI::write(CLI::color('🟢 Naver Worker running... (Redis: ' . $this->redisHost . ':' . $this->redisPort . ' DB:' . $this->redisDatabase . ')', 'green')); } catch (\Exception $e) { CLI::error("Redis 연결 불가: " . $e->getMessage()); return; @@ -45,7 +48,37 @@ class NaverWorker extends BaseCommand while (true) { - $result = $redis->brPop(['naver:raw_queue'], 30); + // Redis brPop with retry logic + $maxRetries = 3; + $retryCount = 0; + $result = null; + + while ($retryCount < $maxRetries) { + try { + $result = $redis->brPop(['naver:raw_queue'], 30); + break; // 성공하면 루프 탈출 + } catch (\RedisException $e) { + $retryCount++; + CLI::write(CLI::color("⚠️ Redis error (attempt {$retryCount}/{$maxRetries}): " . $e->getMessage(), 'yellow')); + + if ($retryCount >= $maxRetries) { + CLI::error("❌ Redis reconnection failed after {$maxRetries} attempts"); + break; + } + + // Redis 재연결 시도 + try { + CLI::write(CLI::color('🔄 Reconnecting to Redis...', 'yellow')); + $redis->close(); + $redis->connect($this->redisHost, (int)$this->redisPort); + $redis->select((int)$this->redisDatabase); + CLI::write(CLI::color('✅ Redis reconnected', 'green')); + } catch (\Exception $reconnectError) { + CLI::error("Redis reconnection error: " . $reconnectError->getMessage()); + sleep(2); // 재연결 실패 시 잠시 대기 + } + } + } if (!$result) { // 데이터가 없어서 타임아웃 난 경우. diff --git a/app/Commands/TestLog.php b/app/Commands/TestLog.php new file mode 100644 index 0000000..e061ba0 --- /dev/null +++ b/app/Commands/TestLog.php @@ -0,0 +1,32 @@ + */ - public $threshold = (ENVIRONMENT === 'production') ? 4 : 9; + public $threshold = 9; // Always log everything for debugging /** * -------------------------------------------------------------------------- diff --git a/app/Controllers/Article/Receipt.php b/app/Controllers/Article/Receipt.php index ee68a46..c0122ea 100644 --- a/app/Controllers/Article/Receipt.php +++ b/app/Controllers/Article/Receipt.php @@ -23,7 +23,7 @@ class Receipt extends BaseController public function lists(): string { - error_log('========== Receipt::lists() CALLED =========='); + log_message('error', '========== Receipt::lists() CALLED =========='); $usr_id = $this->request->getGet('usr_id') ?: ''; $sBonbu = $this->request->getGet('bonbu') ?: ''; @@ -56,7 +56,7 @@ class Receipt extends BaseController public function getResultList() { - error_log('========== Receipt::getResultList() CALLED =========='); + log_message('info', '========== Receipt::getResultList() CALLED =========='); $start = (int) $this->request->getGet('start') ?: 0; $end = (int) $this->request->getGet('length') ?: 10; @@ -96,13 +96,13 @@ class Receipt extends BaseController 'srchTxt' => $this->request->getGet('srchTxt'), // 검색어 ]; - error_log('[Receipt::getResultList] START - start=' . $start . ' length=' . $end); + log_message('info', '[Receipt::getResultList] START - start=' . $start . ' length=' . $end); $totalCount = $this->model->getTotalCount($data); - error_log('[Receipt::getResultList] TotalCount = ' . $totalCount); + log_message('info', '[Receipt::getResultList] TotalCount = ' . $totalCount); $datas = $this->model->getResultList($start, $end, $data); - error_log('[Receipt::getResultList] END - returned ' . count($datas) . ' rows'); + log_message('info', '[Receipt::getResultList] END - returned ' . count($datas) . ' rows'); return $this->response->setJSON(body: [ 'recordsTotal' => $totalCount, diff --git a/app/Controllers/LogTest.php b/app/Controllers/LogTest.php new file mode 100644 index 0000000..cb31ae0 --- /dev/null +++ b/app/Controllers/LogTest.php @@ -0,0 +1,27 @@ +"; + echo "Log file: " . $logFile . "
"; + echo "Exists: " . (file_exists($logFile) ? 'YES' : 'NO') . "
"; + echo "Writable: " . (is_writable(dirname($logFile)) ? 'YES' : 'NO') . "
"; + + if (file_exists($logFile)) { + echo "

Last 20 lines:

"; + echo "
";
+            echo htmlspecialchars(shell_exec('tail -20 ' . escapeshellarg($logFile)));
+            echo "
"; + } + } +} diff --git a/app/Helpers/query_log_helper.php b/app/Helpers/query_log_helper.php new file mode 100644 index 0000000..d98018b --- /dev/null +++ b/app/Helpers/query_log_helper.php @@ -0,0 +1,35 @@ +select("COUNT(*) AS cnt", false); $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner'); - $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'inner'); + $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'left'); $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left'); $builder->join('users u', 'b.usr_sq = u.usr_sq', 'left'); $builder->join('result_imgs e', "e.rsrv_sq = b.rsrv_sq AND e.img_type = 'I1' AND e.use_yn = 'Y'", 'left'); @@ -410,7 +410,7 @@ class ReceiptModel extends Model } $row = $builder->get()->getRowArray(); - error_log('[getTotalCount] SQL = ' . $this->db->getLastQuery()); + // log_message('debug', '[getTotalCount] SQL = ' . $this->db->getLastQuery()); return (int) ($row['cnt'] ?? 0); } @@ -536,7 +536,7 @@ class ReceiptModel extends Model ", false); $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner'); - $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'inner'); + $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'left outer'); $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left outer'); $builder->join('users u', 'b.usr_sq = u.usr_sq', 'left outer'); $builder->join('result_imgs e', "e.rsrv_sq = b.rsrv_sq AND e.img_type = 'I1' AND e.use_yn = 'Y'", 'left outer'); @@ -754,8 +754,8 @@ class ReceiptModel extends Model $result = $builder->get()->getResultArray(); - error_log('[getResultList] SQL = ' . $this->db->getLastQuery()); - error_log('[getResultList] Result count = ' . count($result)); + // log_message('debug', '[getResultList] SQL = ' . $this->db->getLastQuery()); + // log_message('info', '[getResultList] Result count = ' . count($result)); return $result; @@ -826,7 +826,7 @@ class ReceiptModel extends Model ", false); $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner'); - $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'inner'); + $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'left'); $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left'); $builder->join('users u', 'b.usr_sq = u.usr_sq', 'left'); $builder->join('result_imgs e', "e.rsrv_sq = b.rsrv_sq AND e.img_type = 'I1' AND e.use_yn = 'Y'", 'left'); @@ -1213,7 +1213,7 @@ class ReceiptModel extends Model ", false); $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner'); - $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'inner'); + $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'left'); $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left'); diff --git a/app/Views/pages/article/receipt/lists.php b/app/Views/pages/article/receipt/lists.php index a9a31b1..7418e3d 100644 --- a/app/Views/pages/article/receipt/lists.php +++ b/app/Views/pages/article/receipt/lists.php @@ -880,14 +880,16 @@ $usr_nm = session('usr_nm'); function fn_addr_render(data, type, row) { var str = ""; + var addr = row.addr || ''; + var lineBreak = addr ? "
" : ""; if (row.rcpt_jibun_addr == null || row.rcpt_jibun_addr == "") { - str = row.addr + "
" + row.rcpt_hscp_nm + " " + row.rcpt_dtl_addr + " " + row.rcpt_ho; + str = addr + lineBreak + (row.rcpt_hscp_nm || '') + " " + (row.rcpt_dtl_addr || '') + " " + (row.rcpt_ho || ''); } else { - str = row.addr + "
" + row.rcpt_hscp_nm + " " + row.rcpt_li_addr + " " + row.rcpt_jibun_addr + " " + row.rcpt_etc_addr; + str = addr + lineBreak + (row.rcpt_hscp_nm || '') + " " + (row.rcpt_li_addr || '') + " " + (row.rcpt_jibun_addr || '') + " " + (row.rcpt_etc_addr || ''); } - return str; + return str.trim(); } function fn_prd_render(data, type, row) { diff --git a/public/check_env.php b/public/check_env.php new file mode 100644 index 0000000..6f4474b --- /dev/null +++ b/public/check_env.php @@ -0,0 +1,2 @@ +systemDirectory . 'bootstrap.php'; + +$app = Config\Services::codeigniter(); +$app->initialize(); + +echo "ENVIRONMENT: " . ENVIRONMENT . "
\n"; + +// 로그 테스트 +log_message('error', '===== TEST CI LOG MESSAGE ===== ' . date('Y-m-d H:i:s')); +echo "log_message() 호출 완료
\n"; + +$logFile = WRITEPATH . 'logs/log-' . date('Y-m-d') . '.log'; +echo "로그 파일: " . $logFile . "
\n"; +echo "로그 파일 존재: " . (file_exists($logFile) ? 'YES' : 'NO') . "
\n"; + +if (file_exists($logFile)) { + echo "
";
+    echo "마지막 10줄:\n";
+    echo shell_exec("tail -10 " . escapeshellarg($logFile));
+    echo "
"; +} diff --git a/public/test_log.php b/public/test_log.php new file mode 100644 index 0000000..4f1d3c5 --- /dev/null +++ b/public/test_log.php @@ -0,0 +1,18 @@ +"; +echo "writable/logs 쓰기 가능: " . (is_writable($writablePath) ? 'YES' : 'NO') . "
"; +echo "writable/logs 소유자: "; +system("ls -ld " . $writablePath); +echo "
"; + +// 직접 파일 쓰기 테스트 +$testFile = $writablePath . '/test-' . date('Y-m-d') . '.log'; +$result = file_put_contents($testFile, date('Y-m-d H:i:s') . " - Direct write test\n", FILE_APPEND); +echo "직접 쓰기 결과: " . ($result !== false ? 'SUCCESS' : 'FAILED') . "
"; +echo "테스트 파일: " . $testFile . "
"; + +if (file_exists($testFile)) { + echo "파일 내용:
" . file_get_contents($testFile) . "
"; +}