Skip to content
isdnetworks
Go back

같은 조회를 매번 손으로 짰다

같은 종류의 확인 요청이 일주일에 몇 번씩 왔다. 어제 수집 안 된 장치 목록을 뽑아 달라는 것이었다.

올 때마다 SELECT 를 새로 짰는데 대충 기억하고 있으니 몇 분이면 되는 일로 봤다.

Table of contents

Open Table of contents

매번 조금씩 달랐다

같은 요청인데 짤 때마다 조금씩 달랐다.

-- 1차
SELECT device_id FROM device WHERE device_id NOT IN
  (SELECT DISTINCT device_id FROM device_data WHERE DATE(reg_date)='2017-02-18');

-- 2차
SELECT d.device_id FROM device d
LEFT JOIN device_data dd ON dd.device_id=d.device_id AND DATE(dd.reg_date)='2017-02-18'
WHERE dd.device_id IS NULL;

NOT IN 으로 짠 것과 LEFT JOIN 으로 짠 것인데 결과가 한 번 달랐다. 첫 번째가 비활성 장치까지 포함하고 있었다.

받는 쪽에서 보면 같은 질문에 다른 답이 온 것이다. 자료가 바뀐 것이 아니라 내가 짠 WHERE 가 달랐다.

매번 짜면 매번 다르고 기억에 의존하는 한 이 어긋남은 계속 생긴다.

조치 — 스크립트로 옮기기

한 번 제대로 짜고 그것만 쓰기로 했다.

#!/bin/sh
# 지정한 날짜에 자료를 안 보낸 장치 목록
# 사용법: no-data.sh [YYYY-MM-DD]   (기본: 어제)

D=${1:-$(date -d yesterday +%Y-%m-%d)}

mysql -h db -N -e "
SELECT d.device_id, d.name, d.location
FROM device d
LEFT JOIN (
  SELECT DISTINCT device_id FROM device_data
  WHERE reg_date >= '${D} 00:00:00' AND reg_date < '${D} 23:59:59'
) dd ON dd.device_id = d.device_id
WHERE d.use_yn = 'Y' AND dd.device_id IS NULL
ORDER BY d.device_id;
"

날짜를 인자로 받고 안 주면 date -d yesterday 로 어제를 쓰므로 다음부터는 실행만 하면 된다.

use_yn = 'Y' 조건이 핵심이었다. 이것을 넣었다 뺐다 해서 결과가 갈렸던 것이다.

검증 — 전체 개수 함께 내기

mysql -N 로 목록만 내면 0건일 때 판단이 안 선다.

TOTAL=$(mysql -h db -N -e "SELECT COUNT(*) FROM device WHERE use_yn='Y'")
echo "활성 장치 ${TOTAL}대 기준, ${D} 미수집 목록"
echo "---"
# ... 조회 ...
echo "---"
echo "미수집 ${CNT}대"

COUNT(*) 로 활성 장치 수를 먼저 세어 머리말에 찍는다.

활성 장치 42대 기준, 2017-02-18 미수집 목록
---
D012  3공장 A라인  ...
D019  3공장 B라인  ...
---
미수집 2대

TOTAL 이 42로 나오면 0건은 전부 수집됐다는 뜻이고 TOTAL 이 0이면 조회 쪽이 잘못된 것이다.

숫자가 없으면 이 둘이 같은 화면으로 보인다. 아무것도 안 잰 것과 재서 0인 것을 이 한 줄이 가른다.

자주 쓰는 것을 모았다

이런 스크립트가 늘어서 한 폴더에 모았다.

tools/
  no-data.sh          미수집 장치
  slow-query.sh       느린 쿼리
  disk-usage.sh       서버별 디스크
  error-summary.sh    오류 집계
  README.md

README.md 에 각각이 무엇을 하는지 적었다.

## no-data.sh

지정한 날짜에 자료를 안 보낸 활성 장치 목록.

    ./no-data.sh              어제
    ./no-data.sh 2017-02-15   특정 날짜

주의: use_yn='Y' 인 장치만 대상. 비활성 장치는 안 나옴.

주의 항목이 특히 중요했는데 무엇이 대상에서 빠지는지를 안 적으면 다음 사람이 결과를 오해한다.

숫자만 받아 든 사람은 그 숫자가 무엇을 안 셌는지 모르므로 도구를 넘길 때 그것도 같이 넘겨야 했다.

정기 실행으로 바꿨다

요청이 계속 오니 아예 매일 돌려 보내게 했다.

0 9 * * * /opt/tools/no-data.sh | mail -s "[일일] 미수집 장치" ops@example.com

cron 에 걸어 두니 물어보기 전에 먼저 가고 요청하고 기다리는 시간이 사라졌다.

결과가 0대여도 보내게 했는데 안 오면 스크립트가 죽은 것인지 0대인 것인지 알 수 없다.

조치 — 화면과 스크립트가 한 조회를 쓰게

메일보다 화면이 낫다는 얘기가 나와 관리자 화면에도 넣었는데 화면을 따로 짜면 숫자가 또 갈린다.

// models/Report_model.php
public function no_data_devices($date) { ... }

no_data_devices 하나를 두고 화면이 그것을 부르게 했다. 스크립트도 같은 것을 부르게 바꿨다.

php /opt/app/index.php report no_data "$D"

조회가 한 곳에 있으면 결과가 갈릴 자리가 없고 조건을 고칠 때도 한 번만 고치면 화면과 메일이 함께 바뀐다.

정리


Share this post on:

Previous Post
매칭의 결말이 셋이었다
Next Post
매칭 서비스의 양쪽