모든 것이 새롭다 – rrdtool 1.2

압도적인 인기의 오픈소스 라운드 로빈 데이터베이스인
RRDTool이 1.2가 릴리스 되었습니다. 그동안의 버전이었던
1.0에서 상당히 오래 머물러 있었는데, 갑자기 1.2로 올라오고
나서는 요새 유행하는 모든 것이 새롭다 스타일이군용~ 쿠쿠~

  • 베이스 그래픽 라이브러리가 바뀌었습니다. 원래 gd 라이브러리를 사용했었기에, 국제화에 한계가 있었으며 비트맵 그래픽만 가능했었지만, 이제는 기반 라이브러리가 libart로 바뀌고, freetype으로 폰트 렌더링을 하기 때문에, 이제 anti-alias 벡터 그래픽이 가능해졌고, 트루타입 폰트 (한글도 가능!)도 지원됩니다. 와와!
  • 새로운 출력 포맷: 이제 기존 포맷 외에도 SVG, PDF, EPS가 지원됩니다.
  • VDEF 지원: 기존에 CDEF와 DEF와 LINE등을 써서는 최대값이나 평균값 같은 것을 무척 단순하게 밖에 표현할 수가 없었는데, 이제 VDEF로 그래프 전역에 있는 다른 값들을 다룰 수가 있게 되었습니다.
  • 예상값 밖으로 튀는 것 검사: Holt-Winters Forecasting 라는 것을 사용해서, 이제 원래 진행되던 것 외로 데이터가 튀는 것에 대해서 표시를 할 수 있게 되었습니다.
  • COMPUTE 데이터 타입: 이제 로깅 남길 때 데이터 타입을 지정해서 로그를 남길 때 미리 계산해서 RRD에 넣을 수 있게 되었습니다.
  • 외부 라이브러리 별도 배포: rrdtool에서는 그동안 gd라이브러리, png, jpg같이 외부 라이브러리들을 모두 소스에도 같이 묶고 static 링크를 하는 방식으로 배포하고 있었는데, 동적 라이브러리를 최대 활용하는 최근 트렌드에 맞춰서 이제 모두 외부 소스를 쓰며, 동적 링크를 하게 되었습니다. 그래서, 이제 컴파일하기가 간단하지가 않습니다. 으흐흐 -ㅇ-; 포트 없으면 이제 컴파일도 못하겠 -.,-;
  • mmap 지원: 이제 파일 I/O를 할 때 mmap을 씁니다. mmap은 lazy on-demand I/O를 하다보니 아무래도 rrd 파일을 관리할 때 좀 더 시간을 절약할 수도 있을 것 같군요.

rrdtool 1.2로 만든 anti-alias 이미지

한편, 마티즈같이 바뀌지 않은 것이 하나 있는데.. 바로 이것! 🙂

그런데, 오늘 어떤 사람이 py-rrdtool을 rrdtool 안에 넣으려고 Oetiker씨와 얘기를 하고 있다고 라이선스에 대해서 저에게 문의를 해 왔는데, 잘 되면 다음 1.2버전 부터는 rrdtool만 깔면 파이썬에서도 쓸 수 있게 되겠군용.~

파이썬에 다시 불어오는 봄바람

요새 파이썬 개발팀의 주요 이슈는 PEP-340 Anonymous Block 입니다. 거의 다른 이슈들을 완전히 누르고 하루에도 수십통씩 관련 메일이 올라올 정도로 다들 열에 올라 있는데, 이 논의와 비슷한 얘기는 이전에도 몇번 있긴 했지만 딱히 어디로 결론이 나지는 않았었습니다. (PEP-310, PEP-325) 그러나 4월 중순에 C++ 프로그래머였던 사람이 조심스럽게 질문을 한 것에 대한 답글들에서 개발자들이 열을 내기 시작해서, 귀도가 4월 27일에 직접 PEP를 쓰기에 이릅니다.

이번 PEP-340은 현재 드래프트 상태이고, 확실히 의견이 모아진 것도 아니며, 그냥 실험적으로 논의되는 상태를 정리하는 것을 위한 안이지만, 이전의 유사 주제의 PEP들에 비해 상당히 여러 분야를 한꺼번에 통합하고 있고, 신선한 개념을 많이 제공하고 있다는 점에서 뭔가 유사한 것이 약간의 부분이라도 파이썬 2.5에 들어갈 것 같은 감이 듭니다. 으흐흐~ 파이썬 2.5에는 특히 AST가 거의 들어갈 것이 확실시되고 있으니까.. 그 김에 문법도 확 -.-,;;

PEP-340에서 소개하는 Anonymous Block은 파이썬 1.5 이후의 문법 상의 가장 획기적인 변화라고 부를 수도 있겠는데, 사실 많은 수의 개발자들이 2.4까지 계속 문법 변화가 많았으니 이제 2.5부터는 문법은 바꾸지 말자하고 암묵적인 동의를 했음에도 불구하고, 이번에 예전에 수년동안 있었던 문법 변화보다 더 많은 변화가 들어가 버리니.. 파이썬 중도보수파들도 이제 파이썬의 변화에 반감을 느낄 것 같기도 합니다. 으흐~

Anonymous Block이 해결하려는 이슈를 소개해 드리자면, PEP에서 언급된 대로 “좋은 프로그래머들은 자주 나오는 코드를 재사용 가능한 함수로 분리”를 합니다. 그런데, 함수나 클래스로 쉽게 분리가 되는 경우도 많이 있지만, 어떤 경우에는 루틴의 앞부분과 끝부분, 오류처리부분과 루틴의 중간 중간이 드문드문 반복되는 패턴으로 자꾸 나오는 경우가 있습니다. 예를 들면, 공유 자원의 접근을 위한 뮤텍스라던지, DB 접근을 위한 트랜잭션 처리 블럭, HTML의 헤더/푸터나 table 앞뒤 장식, 임시 파일의 생성 등 수많은 경우가 해당이 될 수 있겠는데요. 이런 경우에는 콜백으로 빼서 클래스를 생성하자니 배보다 배꼽이 크게 되고, 그렇다고 매번 풀어쓰기에는 반복되는 로직을 자꾸 중복하게 되는 찝찝한 경우가 생기는데, 이런 경우를 극복하기 위해서 Anonymous Block (현재 파이썬 메일링에서는 그냥 “block”이라고 부르고 있습니다.)가 제안되었습니다.

즉, “block”에 진입하는 시점, 오류또는 정상 종료로 인한 이탈 시점, 반복을 하는 시점, 중간에 루프의 인자가 약간 바뀌는 시점 같은 것들을 기존의 문법인 제너레이터를 확장한 것과 짬뽕을 해서 멋지게 만들어 보자는 것이 요점입니다. 2.3부터 지원되고 있는 제너레이터는 이미 상당히 다양한 용도에 사용할 수 있는 성공한 문법이지만, next 메쏘드에 인자를 전달할 수가 없어서, 상태 관리가 매우 힘들다는 점이나 try: finally 블럭이나 try: except 블럭을 yield와 걸쳐서 사용할 수 없어서, 자원의 정상적인 해제가 불가능하다는 점에서 아쉬움이 있었는데 이러한 문제점도 여기서 완전히 해결되었습니다.

현재 상태에서 PEP-340에서 변경하는 기본 statement 변화는 이런 것들이 있습니다.

  • __next__ 메쏘드 신설: 기존의 이터레이터 프로토콜에서는 __next__가 아니라 next메쏘드를 쓰고 있었는데, 이 이름이 범용으로는 아무래도 맞지가 않았기에, __next__로 새로운 메쏘드를 신설하고, __next__에 이제 인자 1개가 None이 기본값인 옵셔널 인자로 들어갑니다.
  • __exit__ 메쏘드 신설: 이터레이터 프로토콜에 자원 해제를 위한 메쏘드가 없어서, 그동안 lock 해제 같은 것이 매우 곤란했었는데, 그 경우를 위해서 예외 발생 여부에 상관없이 항상 호출되는 __exit__ 메쏘드를 새로 만듭니다.
  • next() 빌트인 함수: i.__next__()라고 맨날 쓰기에는 너무 보기가 안 좋아서, next(i)로 사용할 수 있도록 빌트인 함수가 신설됩니다.
  • for 루프 변경: for 루프의 정의가 변경됩니다. 아래의 인자 있는 continue나 탈출 함수 호출을 위한 정의 변경이고, 예전 사용법으로 쓰는 경우는 똑같습니다.
  • continue 인자 추가: continue 키워드 뒤에 이제 인자를 붙일 수 있게 되었습니다. continue 키워드 뒤에 인자를 쓰는 경우에는 바깥에서 돌고 있는 for또는 “block” 블럭의 이터레이터에게 전달됩니다. 즉, for 루프의 본문과 이터레이터가 직접 통신이 가능하게 되었습니다.
  • Anonymous block 추가: 아직 이름이 정해지지 않은 (아직 “block”이라고 부르고 있습니다.) 새로운 블럭 키워드가 추가됩니다. 이 키워드는 for과 유사한 목적으로 사용될 수도 있지만, 이터레이터 인자를 항상 대상으로 하고 있다는 점에서 좀 다릅니다. 자세한 설명은 아래에서..
  • 제너레이터 예외 처리: 이제 제너레이터의 yield statement가 try: except 블럭 안에도 들어갈 수 있게 되었으며, try: finally 블럭 안에도 들어갈 수 있습니다.
  • yield statement 리턴값: 제너레이터의 __next__로 들어오는 인자를 받기 위해서 이제 yield statement가 들어온 값을 리턴합니다.

대충 훑어봐도 엄청난 변화임이 확실히 느껴지는데, 이게 아직 확실히 정해진 것은 아니니 허어억~ 하고 미리 놀라실 필요는 없습니다. (나중에 들어가면 그때 놀라면;; -o-) Anonymous Block을 사용하는 예제로 가장 많이 나오는 DB 트랜잭션 처리 같은 경우에는 이렇게 됩니다.

그리고, 이제 yield가 리턴값을 갖을 수 있기 때문에 유사-클로져나 유사-코루틴을 이제 쓸 수가 있게 되었습니다. 예를 들어서, 이런 코드가..

흐흐.. 결국 껍데기 부분의 루틴 분리에 획기적인 개선을 가져올 수 있는 좋은 도구가 될 수 있을 만한 것 같이 보입니다. 여전히 수많은 이슈들과 특히 키워드 이름을 무엇으로 할 것인가 등의 많은 문제들이 남아있지만, 아무래도 파이썬 2.5에 들어가면 가장 멋있을 것 같은 기능임에는 틀림이 없군요. 🙂 문법 변화라는 점에서는 원래 예정과는 좀 다르게 간다는 점에서는 약간 찝찝한 감이 있긴 하지만.. 뭐 이제 류창우님의 말씀 대로.. 파이썬도 C++이 가던 길을 걷고 있는 건지도.. (먼산)

FreeBSD에도 패키지를 자동으로!

얼마 전에 회사에서 새로운 서버를 세팅하면서, 데비안에 없는 패키지 몇 개를 깔끔하게 설치하기 위해 방법을 알아보던 중, 회사 동료인 상현씨의 조언으로 checkinstall를 이용해서 설치하게 되었습니다. checkinstall은 인스톨하는 도중에 preload된 동적 라이브러리가 파일 변경사항을 로그로 남겨서, 그 로그를 기반으로 마치 패키지를 이용해서 깐 것처럼 해 주는 도구이더군요. 물론 바이너리 패키지도 만들어 주고 해서, 패키징되지 않은 프로그램을 임시로 재빠르게 깔아야하는 경우에 매우 편리했습니다.

사실 예전에 autoplist.py라고 ktrace기반의 pkg-plist 자동 생성기를 만들었습니다. 그런데, 당시 FreeBSD의 베이스가 정적 링크되어 있었기에 LD_PRELOAD 트릭을 사용할 수가 없어서 ktrace를 기반으로하다보니 너무 부하가 심해서 mozilla같은 대형 포트를 깔 때에는 거의 5분 이상이 걸리는데다 로그를 남기는 하드디스크 용량도 너무 많이 들고 해서 아주 간단한 포트 외에는 쓰기가 힘들었습니다.

FreeBSD는 그래도 간단한 임시 포트를 만들기가 데비안에 비해서는 쉬운 편이긴 하지만, 아무래도 pkg-plist 만드는 압박이 있기에 FreeBSD에도 그런 것이 있으면 삶을 활기차게 사는 데에 큰 도움이 되겠구나. 하는 생각이 들었습니다. 🙂 이제 FreeBSD도 베이스가 완전 동적으로 되었기에, FreeBSD 사용자도 이제 젖과 꿀이 흐르는 자동 plist 생성의 세계로! 그런데, 우선 인스톨 로그를 위한 sysutils/installwatch포트가 워낙 오래된 것이어서 그런지, 5.x에서는 log 심볼의 중복이라던지 여러가지 문제점으로 계속 버스에러로 죽었는데 그 문제를 약간 추적해서 수정해서 메인테이너에게 보냈습니다. (아직 커밋되지는 않았습니다.)

그래서 그걸 이용해서 결국 주말에 pkg_trackinst와 pkg_genplist를 LD_PRELOAD기반으로 만들었습니다.
우선, pkg_trackinst는 패키징이 안 되어있는 소프트웨어를 make install할 때에 당시에 설치되는 파일들을 분석해서 자동으로 패키지로 설치한 것처럼 만들어주고 바이너리 패키지도 만들어서 다른데서도 똑같이 설치할 수 있도록 만들어주는 도구입니다.
그리고, pkg_genplist는 다른 패키징은 다 끝나고 pkg-plist파일만 생성하면 끝나는 상태에서 pkg-plist를 자동으로 생성해 주는 도구입니다.

pkg_trackinst는 오늘까지 만든 부분에서 거의 잘 돌아가고 있지만, 아직 pkg_genplist는 mtree를 사용하지 않고 있어서, 중복된 파일도 막 올려대고 특히 manpage쪽이 문제가 많이 있습니다. 그렇지만, 주말도 거의 끝난데다가.. 다른 시스템들에서도 잘 돌아가는지 보고 싶어서 일단 버전 0.1을 릴리스했습니다. (파이썬 2.4, FreeBSD 5.2이상이 필요하고, 앞에 언급된 installwatch 포트 패치가 적용되어 있어야 합니다.)

패키지 만드는 법이 귀찮지만 pkg_delete는 하고 싶은 분이나 plist 만드는 것이 귀찮아진 분들 한번씩 테스트해봐 주세용. 🙂