본문 바로가기

전체 글

(120)
PDF 여러 개 중 텍스트가 안 뽑히는 스캔본만 골라내기 (PyMuPDF로 텍스트 레이어 판별) PDF 파일을 한꺼번에 처리하다가 몇 개만 결과가 텅 비어 나올 때, 어떤 파일이 스캔본인지 미리 골라내고 따로 처리하는 방법입니다.서류 PDF 여러 개에서 내용을 뽑아 정리하려고 파이썬으로 한꺼번에 돌렸는데, 대부분은 잘 뽑히고 몇 개만 빈 결과가 나왔습니다. 오류도 없고 파일도 정상적으로 열렸습니다.열어보면 화면에는 글자가 멀쩡히 보입니다. 그런데 마우스로 글자를 드래그해 보면 선택이 안 되고 페이지 전체가 한 덩어리로 잡힙니다. 종이 서류를 스캐너로 찍어서 만든 PDF, 즉 글자가 아니라 사진이 들어 있는 파일이었습니다.- PDF 에는 글자가 들어 있는 파일과 글자 사진이 들어 있는 파일이 섞여 있다- 스캔본은 텍스트를 뽑아도 오류 없이 빈 값이 나온다- 페이지마다 글자 수와 이미지 면적을 보면 스..
1원만 넘어도 혜택이 통째로 사라지는 세법 기준선 (금융소득 2,000만원과 월세 세액공제 총급여 8,000만원) 세금과 공제에는 "얼마 이하"라는 기준선이 많은데, 이 선을 조금만 넘어도 초과분이 아니라 혜택 전체가 바뀌는 경우가 있습니다. 직장인이 자주 걸리는 두 가지 기준선을 정리한 글입니다.연봉 협상이나 예금 만기를 앞두고 계산을 하다 보면, 조금 더 받는 게 오히려 손해인 구간이 나옵니다. 세율이 올라서가 아니라, 기준선을 넘는 순간 다른 혜택이 통째로 사라지기 때문입니다.이런 기준선은 대부분 "넘은 만큼만" 불이익을 주는 게 아니라 넘었는지 아닌지로 판정합니다. 그래서 1원 차이로 결과가 크게 갈립니다.- 금융소득(이자와 배당)은 연 2,000만원을 넘으면 종합소득에 합산된다- 합산되면 세금보다 건강보험료와 다른 공제 요건이 더 크게 흔들릴 수 있다- 월세 세액공제는 총급여 8,000만원을 1원만 넘어도 ..
상용 DB 라이선스가 컨테이너에서 "Corrupted license string"으로 거부될 때 (Altibase 버전과 하드웨어 바인딩) 기존에 받은 알티베이스(Altibase) 라이선스를 도커 이미지에 넣었더니 라이선스가 깨졌다며 기동이 안 되는 원인과, 라이선스가 무엇에 묶여 있는지 확인하는 방법입니다.개발용 DB 를 컨테이너로 띄우려고 했습니다. 라이선스 키는 이미 있었고, 공식 도커 이미지도 있었으니 키만 넣으면 뜰 거라고 생각했습니다.그런데 기동하자마자 "Corrupted license string" 이 나오며 멈췄습니다. 키를 잘못 복사했나 싶어 다시 넣어봤고, 실제로 다른 서버에서 멀쩡히 돌고 있는 라이선스 파일을 그대로 가져와 넣어도 결과가 같았습니다.원인은 키가 깨진 게 아니었습니다. 이 라이선스는 특정 버전, 특정 장비, 특정 운영체제에 묶여 있었고, 그중 버전이 먼저 어긋나서 키를 읽는 단계에서부터 거부된 것이었습니다...
레거시 서비스를 모노레포로 묶을 때 분류 기준 (API와 배치를 가르는 법) 여러 저장소에 흩어져 있던 오래된 서비스들을 저장소 하나로 모으면서, 폴더를 어떤 기준으로 나눌지 정했던 과정입니다.서비스별로 따로 있던 저장소를 하나로 합치기로 하고 폴더 구조를 잡기 시작했는데, 막상 해보니 어려운 건 폴더 모양이 아니라 이 서비스를 어디에 넣을지였습니다.API 와 배치로 나누자는 큰 틀은 금방 정해졌습니다. 그런데 오래된 서비스일수록 요청도 받고 스케줄도 도는 애매한 것들이 많았고, 이름만 보고 넣었다가는 같은 성격의 서비스가 양쪽에 흩어지게 됐습니다.- 기준은 이름이나 기술이 아니라 "무엇을 제공하는가"로 잡는다- 한 제품이라도 역할이 다르면 나눠서 넣을 수 있다- DB 도 다르고 연동도 거의 없는 제품은 따로 떼어 둔다- 합친 뒤 섞이는 커밋은 접두어와 경로 지정 로그로 구분한다..
같은 소스를 두 서비스로 배포할 때 태그 붙이는 법 (서비스별 접두어 태그) 소스 저장소 하나로 웹과 관리자 화면처럼 서비스 두 개를 따로 배포할 때, 태그가 겹쳐서 무엇을 어디에 반영했는지 헷갈리는 문제를 푸는 방법입니다.사용자용 웹과 관리자용 화면이 같은 저장소에서 빌드되는 구조였습니다. 코드 대부분을 같이 쓰고, 빌드할 때 설정만 달리해서 두 서비스로 나눠 배포합니다.문제는 태그였습니다. 웹을 배포하려고 만든 태그로 관리자 화면도 같이 배포하고 있어서, 태그 목록만 봐서는 그 태그가 웹 배포였는지 관리자 배포였는지, 둘 다였는지 알 수가 없었습니다.평소에는 큰 문제가 없다가 두 서비스를 같은 날 따로 반영하는 날에 터집니다. 웹은 새 태그로 나가고 관리자는 예전 태그 그대로인데, 기록상으로는 둘이 구분되지 않습니다.- 태그 하나를 두 서비스가 같이 쓰면 무엇을 어디에 반영했..
오래 쓴 젠킨스 잡 목록 정리하기 (이름 규칙과 안 쓰는 잡 격리) 몇 년 동안 쌓인 젠킨스 잡을 정리하면서 잡았던 이름 규칙과, 안 쓰는 잡을 안전하게 걷어내는 순서입니다.검수용 젠킨스의 잡을 운영 젠킨스로 합치면서 잡 목록을 처음부터 훑어보게 됐는데, 목록만 봐서는 어느 잡이 무엇을 어디에 배포하는지 알기 어려웠습니다.같은 서비스인데 잡마다 이름 붙이는 방식이 달랐고, 운영 환경을 가리키는 말도 팀에서만 통하는 real 같은 표기가 섞여 있었습니다. 몇 년 전에 끝난 서비스의 잡도 그대로 남아 있어서, 지워도 되는지 아무도 확신하지 못하는 상태였습니다.- 이름만 보고 서비스, 환경, 역할이 읽히게 규칙을 정한다- 환경 표기는 팀 안의 관행어 대신 누구나 아는 말로 통일한다- 안 쓰는 잡은 바로 지우지 말고 표시하고 비활성화한 뒤 지운다- 빌드 화면의 파라미터도 누르는..
git sparse-checkout 명령이 없는 구버전 git에서 폴더 하나만 받을 때 (core.sparseCheckout) 여러 서비스를 한 저장소에 모아둔 상태에서, 오래된 서버의 구버전 git 으로 필요한 폴더만 골라 받는 방법입니다.서비스 여러 개를 저장소 하나로 합친 뒤, 배포 서버에서는 자기 서비스 폴더만 받아서 빌드하게 하려고 했습니다. 요즘 git 이라면 git sparse-checkout 명령 한 줄이면 되는 일입니다.그런데 배포 서버에서 실행해 보니 그런 명령이 없다는 오류가 났습니다. 오래된 서버라 git 버전이 낮았고, 이 명령은 2.25 버전에서 처음 생긴 것이었습니다.git 을 올리면 간단하지만, 폐쇄망이거나 여러 서비스가 같이 쓰는 서버는 패키지 하나 올리는 것도 쉽지 않습니다. 다행히 명령만 없을 뿐 기능 자체는 훨씬 전부터 있어서, 설정 파일로 같은 결과를 낼 수 있었습니다.- git sparse..
apt autoremove 한 번에 우분투 자동 보안 업데이트가 조용히 꺼질 때 (unattended-upgrades 삭제) 우분투 서버에서 패키지를 정리하다가 자동 보안 업데이트 프로그램까지 같이 지워져, 설정은 켜진 그대로인데 몇 달 동안 패치가 안 된 원인과 확인 방법입니다.서버 두 대를 나란히 점검하다가 이상한 걸 발견했습니다. 둘 다 자동 보안 업데이트를 켜 둔 서버인데, 한 대만 몇 달째 업데이트 기록이 없었습니다.설정 파일을 열어보면 자동 업데이트는 켜짐으로 되어 있었고, 누가 일부러 끈 흔적도 없었습니다. 그런데 정작 업데이트를 실행하는 프로그램인 unattended-upgrades 가 설치돼 있지 않았습니다.설치 기록을 거슬러 올라가 보니, 석 달 반 전에 데스크톱 패키지를 지우고 apt autoremove 로 정리한 날 함께 지워져 있었습니다.- apt autoremove 는 다른 패키지 때문에 따라 설치된 ..