django로 만든 웹 서버가 메모리 릭이 있는 것 같아서, 임시로 클라이언트 요청 수에 제한을 걸고 새로 실행되도록 설정했다. 임시가 길어져 1년이 돼가는 동안 잊고 있다가 개발자의 자존심을 건드는 설정인지라 다시 봐야했다.

이 글은 메모리 릭을 잡았다는 것이 아니다.

서버들 중 적당히 스왑을 사용하고 있는 녀석을 골라서 들어갔다. gunicorn 들 중에 제일 pid가 큰 것을 골라낸 후, 해당 PID 에 strace 를 걸어서 GET/POST와 URL PATH에 해당하는 것만 출력하도록 awk 파이프 질을 했다. 동시에 "ps -efl" 로 해당 PID만 골라낸 다음 awk로 적당히 메모리 사용량 부분만 출력한다.

대략 512 개의 요청만 하면 사라지는 gunicorn의 PID이므로, 위 두 작업을 백그라운드로 실행시켜 놓고 fork되어 나간 bash 스크립트의 PID를 저장해 놓는다. 그리고 예의 주시 중인 PID를 1초에 한 번씩 kill -0로 죽었는지를 확인한다. 죽었다면 fork된 녀석들을 죽이고 종료하면 된다.

매우 민첩하게 위 작업들을 생각의 순서대로 뱉어 낸다. 물론 처음에는 바로 쉘상에서 작업하지만, 조금 커질 것을 알고 a.sh 정도로 vim 스크립트로 편집을 하고 실행시키도록 한다.

메모리가 증가되는 순간의 URL을 몇 개 수집한다. 수 분을 기다린다. 화면은 그저 URL과 메모리 사용량만 계속 올라간다.

아뿔싸, 접속한 서버가 오토스케일 정책에 따라 반납되면서 접속이 끊긴다. 뭐야 이거, a.sh 다시작성하기 귀찮은데... 아, 1년만에 들어온 생각인데...

터미널 버퍼를 위로 올려 봐도 vim으로 작업한 것은 남아 있지 않다. 그저 화면에 스크립트의 결과물만 장황하게 넘어간다.

당황하지 말고, terminal에는 vim, less 등이 사용 될 땐 alternative screen으로 작성된다는 것을 알고 있다. ansi terminal이 제공하는 매우 오래된 기능이다.

"ansi show alternative screen" 로 검색을 한다. 

ESC [ Ps ;...; Ps h             Set Mode
ESC [ Ps ;...; Ps l             Reset Mode
      Ps = 4            (A)     Insert Mode
           20           (A)     ‘Automatic Linefeed’ Mode.
           34                   Normal Cursor Visibility
           ?1           (V)     Application Cursor Keys
           ?3           (V)     Change Terminal Width to 132 columns
           ?5           (V)     Reverse Video
           ?6           (V)     ‘Origin’ Mode
           ?7           (V)     ‘Wrap’ Mode
           ?9                   X10 mouse tracking
           ?25          (V)     Visible Cursor
           ?47                  Alternate Screen (old xterm code)
           ?1000        (V)     VT200 mouse tracking
           ?1047                Alternate Screen (new xterm code)
           ?1049                Alternate Screen (new xterm code)

Set은 h로 끝나며, Ps로는 "?47"이면 되겠다. 내 로컬 console은 zsh이니까 몇가지 escape 처리해서 echo 해주면 되겠다. 될까?

echo -e \\e\[\?47h

으허허 보인다. 반납된 서버에 잠시 삽질했던 코드를 다시 치고 싶지 않은 그 임시 코드가 보인다.

#!/bin/bash

P=$(ps -ef | grep guni | grep python2 | sort -k2 -n | awk '($3 != 1) {print $2}' | head -1)
strace -tt -s 100 -p $P 2>&1 | stdbuf -o0 egrep "recvfrom\(.*(GET|POST)" | stdbuf -o0 awk '{print substr($3,2), $4}' &
PID1=$!
while true; do ps -efl | grep gunicorn | grep -w $P | awk '{print $10}'; sleep .5; done &
PID2=$!

trap "kill $PID1 $PID2; exit" SIGINT
while true
do
        if kill -0 $P; then
                sleep 1
                continue
        fi
        kill $PID1 $PID2
        exit
done

귀찮다... 이 시간에 이거 할 게 아닌데.

대표적인 명령행 입력 라이브러리인 readline의 입력 모드를, 이제부터 vi mode로 바꿔 볼 생각.


$ cat ~/.inputrc

set input-meta on

set output-meta on

set convert-meta off

set editing-mode vi


2015년부턴 마지막 한 줄 더 추가하는 것으로...

vi, vim 을 쓰지만 정말 안쓰는 명령이 "s" 다. 가끔 :help를 볼 때 마다 저 명령의 존재를 알 정도인데, 알파벳으로 되어 있는 명령중에서 거의 안쓰지 않나 싶다.


VIM
키보드 작업을 마구마구하다보면, 두 개 파일을 열어서 작업해야할 일이 있다.
vim -o a.txt b.txt
그러나
vim a.txt b.txt
로 열었을 때, 아차차 하면서 :q 로 나오지 마시고..
:sba
하면 된다.


(:sbl 은 마지막 창을 여는 것이었군..)
VIM
Vim 7.0이 나온지  한참됐지만, 6.x에 만족하고 있다가, 요사이 태그리스트나 몇몇 화려(?)해진 기능을 그냥 무시하고 지나치다가...

:Tex

명령을 발견하고는 놀랬습니다. 주로 :Ex 와 :Sex 만 쓰다가 저런!
LaTex 같은 것이 아니라 Tab Explore라는 기능인데, 현재 편집중인 파일이 들어 있는 디렉토리를 보는 명령입니다. 전엔 주로 :Sex (혹은 :Se)로 만족(?)하며 살았는데 이거 뭡니까.

뒤져봤더니 gt 를 누르면 생긴 탭을 왔다 갔다 할 수 있더군요.
gt : 다음창
gT : 이전창
c-w gf : 커서아래 파일이름을 새탭으로 열기
c-w gF : 커서아래 파일이름을 새탭으로 열고 커서 다음에 있는 행 표시로 이동하기
:tabnew : 빈 탭 만들기

종료는 늘 하던대로 c-w c 로 하나씩 없애면되겠습니다.

GUI 환경에서라면 C-PgUp C-PgDn 으로 이동하면됩니다.

신입사원들에게 쑥스럽군요... ㅋㅋ. 게을러지면 안돼요.

vim tab screen shot

세 개의 탭이 열려 있는 화면입니다. 세번째는 두번째 QuickFix 에서 c-w gF 로 연 탭입니다.
탭의 맨 앞의 2 라는 숫자는 그 탭에 열려 있는 창의 수입니다.

권태혁, 잘쓰삼.
  1. 프리버즈 2007.03.21 15:08

    너무 공격적이예요 -0-

  2. 준호 2007.03.21 17:38

    오늘은 K 리그 Day~~

    • 최호진 2007.03.21 17:57

      왜 여기에 이런 댓글을 다는 것이야..!

  3. lacrimas 2007.03.21 21:49

    K 리그 ~
    ㅠㅠ

    근데 :Sex 혹시 명령어예요?
    아니 어떻게 이런 일이~

    • 최호진 2007.03.21 22:45

      카카.. 사실 :Sexplore 인데.. 이것도 이상하지 않어?
      가장 줄이면 :Se 로 해도 돼..

  4. nainu 2007.03.22 00:01

    그런데 제가 우분투 edge, feisty에서 해봤는데 :Tex가 안됩니다..
    혹시 플러긴을 더 설치하신 건 아닌지요? 더 알려주세요..ㅎㅎ

    • 최호진 2007.03.22 00:33

      /usr/share/vim/vim70/plugin/netrwPlugin.vim

      이것이 있어야하는 군요...!

  5. nainu 2007.03.22 02:04

    오웅.. 기존에 들어있는 것은 60에 있던 버전이었네요. vim.sf.net 에서 받아서 깔았더니 잘 됩니다. 감사합니다 ㅎㅎ

  6. 실버 2007.03.29 20:42

    오호. 탭 기능이 있었네요. 감사합니다.
    vimgrep 만 열심히 쓰고 있었는데, 저도 공부좀 더 해야겠군요.

  7. 2015.08.21 10:55 신고

    vim에서 화면을 2개로 나누어 파일 탐색기를 실행합니다. 그리고 나서 서로다른 경로의 파일을 바로 diff할 수 있을까요?

    1. vim을 실행한다.
    2. :e ./ 명령으로 파일 탐색기를 실행한다.
    3. v 버튼을 눌러 화면을 분할하여 파일을 하나 연다
    4. :e ./ 명령으로 파일 탐색기를 실행한다. <<< 이 과정을 지나면 화면은 두개로 분할이되고 각 화면은 파일 탐색기 역할을 합니다.

    • Coolen 2015.08.22 13:29 신고

      :diffsplit
      :diffthis
      명령에 대해 알아보세요.. ^^

VIM
1. 다들 아는 지식

- vim 에서 :make 하면 현재 디렉토리의 Makefile로 컴파일을 합니다. 그리고 컴파일 결과가 quick fix 창에 나타나게 되지요.
- 이 때, :copen 으로 quick fix 창을 열어 :cn, :cN 등으로 오류가 난 곳을 이동할 수 있습니다.


2. 얼마전에 안 지식
- 빌드 로봇이 출력한 결과가 build.log 로 남게 되면, 여기에는 warning, error 들이 있을 수 있습니다.
- vim -q build.log 를 사용하면 비슷하게 수정할 수 있습니다.
VIM
vim 뒤에 파일명이 압축 확장자(.gz, .Z, .bz2)로 되어 있다면,

$ vim maillog.1.gz

바로 읽을 수 있다. /usr/local/share/vim/vim60/plugin/gzip.vim 이라는 플러그인이 확장자를 알아서 인식하여 전처리를 해주기 때문이다. 물론, 저장할 때 후처리로 다시 압축하여 저장하는 센스도 발휘 해준다.

로그가 압축되어 있을 때, 그 얼마나 편리한 기능인가!
  1. 황정택 2008.10.15 10:18

    새로운 사실이군요.
    폴더 리스트 여는 것도 정말 신기했는데,
    압축파일 내부 목록도 열어준다니..
    좋은 정보 감사합니다.

+ Recent posts