config/*.php 와 .env 여기저기에 섞인 한글을 일괄로 영문 치환하는 작업을 맡았다. sed 한 줄짜리 치환 작업으로 보였는데 검토 과정에서 지적이 하나 나왔다.
Table of contents
Open Table of contents
배경 — 단순 치환으로 보이던 작업
[가-힣] 문자셋을 기준으로 대상을 고르면 기계적으로 처리할 수 있어서 작업이 편해진다. 다만 그 기준이 무엇을 놓치는지는 값을 하나하나 열어 봐야 드러난다.
같은 설정 파일 안의 문자열이라고 해서 전부 같은 성질을 갖는 것이 아니었다. 어떤 값은 사람이 읽는 설명이었고 어떤 값은 다른 시스템과 맺은 계약이었다.
원인 — 다른 시스템과 문자로 결합된 값
CloudWatch 지표 필터 설정에 배치 완료 마커 문자열이 있었는데 다른 저장소의 nightly.sh 가 로그에 찍는 문자열과 문자 단위로 같아야 했다. 지표 필터가 그 문자열을 찾아서 배치가 돌았는지를 판정하고 있었다.
이 마커를 바꾸면 배치가 정상인데도 지표가 영영 0이 되고 알람이 계속 켜져 있게 된다. 계속 켜져 있는 알람은 사람이 무시하기 시작하므로 꺼져 있는 알람과 같아진다.
조치 — 문자셋이 아니라 값의 성질
두 가지 방법이 있었는데 [가-힣] 문자셋으로 전부 잡아 치환하는 것과 값의 성질로 대상을 고르는 것이다. 뒤쪽을 골랐다. 이유는 문자셋 기준은 다른 시스템과 결합된 값을 못 가려서다. 대신 값을 하나하나 열어 성질을 판정하는 시간을 감수했다. 사람이 읽는 설명은 바꿔도 되고 내부에서만 참조하는 이름은 참조처까지 함께 바꾸면 된다.
다른 시스템과 매칭되는 문자열과 HMAC 서명이나 해시의 입력이 되는 값은 바꾸면 안 된다. 뒤의 둘은 문자 하나가 그대로 계약이므로 애초에 치환의 대상이 아니었다.
주의 — 제외에 이유를 붙이는 이유
지적의 요지는 판단이 틀렸다는 것이 아니라 그 판단이 어디에도 안 적혀 있다는 것이었다. 실제로 몇 가지는 대상에서 빼고 작업했는데 그 판단이 설명 어디에도 없었다.
검토하는 쪽에서는 일부러 뺀 것인지 그냥 빠뜨린 것인지 구분할 수 없다. 그래서 SWEEP.md 에 대상과 제외를 각각 적고 제외에는 이유를 붙였으며 값 옆에도 # DO NOT RENAME 주석을 남겼다.
검증 — 살아 있다는 증거의 출처
작업 전에 그 마커가 지금도 실제로 매치되고 있는지를 확인해야 했다. 로그를 뒤지기 전에 DEPLOY.md 에서 배포 직후 알람이 한 번 뜨고 다음 야간 배치에서 자동 복구된다는 문장을 찾았다.
그 자동 복구는 마커가 매치돼야만 일어나므로 그 한 줄이 지금 살아서 동작한다는 증거가 됐다. 문서에 적힌 운영 경험이 관측을 대신하는 증거가 되기도 했다.
정리
- 일괄 치환의 지뢰는 다른 시스템과 문자로 결합된 값이다
- 문자셋으로 대상을 정하면 그 결합이 안 보인다
- 값의 성질로 대상을 고른다
- 감시 마커를 바꾸면 영영 켜진 알람이 되고 그것은 꺼진 것과 같다
- 대상과 제외를 적고 제외에는 이유를 붙인다
- 이유 없는 제외는 빠뜨림과 구분되지 않는다
- 값 옆에 단독 변환 금지 주석을 남긴다
- 문서에 적힌 운영 경험이 살아 있다는 증거가 되기도 한다