회사에서 웹에서 검색하고 정보를 취합하는 일이 생겨서 고민하다가, 그전부터 알고 있던 툴을 이용하여 자동화했습니다. 원래 3 M/M 정도 예상했었는데 4시간 정도 투자해서 자동화에 거의 성공했습니다. 자동화해서 돌리면 넉넉하게 5일 정도면 돌릴수 있을거 같네요.

AutoIT은 스크립팅 언어로 마우스와 키보드 입력을 자동화하는 툴로, 시스템 관리자들이 많이 쓴다고 합니다. 스크립팅 언어이지만 EXE로 만들어서 배포할수 있으며, 이 경우 AutoIT을 설치하지 않아도 되므로, 간단한 어플은 AutoIT을 통해서 만들어서 EXE로 배포되는것도 있습니다.

윈도우즈가 기본적으로 GUI기반으로 되어있기때문에 유닉스의 쉘에서는 쉽게 할수 있는게 처리할 자료의 양이 많아지면 난감해지는 경우가 있죠. 그럴 경우 AutoIT이 아주 유용할수 있죠.

어제 AutoIT을 배우면서 시험삼아 예전에 사용하던 Zope 웹서버의 쌓인 스팸을 지웠습니다. 5만개 정도(!)가 쌓였었는데... Zope 인터페이스가 웹기반이라 마우스로 하나씩 찍어서 지워야합니다. 이게 귀찮아서 그냥 냅뒀었는데... 간단히 마우스와 키보드를 저장하여 프로그램화하여 한 10분만에 모두 지웠습니다 ^^v

AutoIT을 설치하면 에디터가 같이 설치되는데 개발할때 정말 유용하네요. 에디터에서 F5(실행), Ctrl-Break(중지)는 필수죠. 그리고 디버깅할때도 ConsoleWrite 함수를 이용하면 에디터 하단에 출력내용이 표시됩니다.

사실 AutoIT에서 사용하는 스크립트가 좀 현대적이지 못해서 불편합니다. 자바스크립트나 파이썬 정도의 언어로 이런일을 할수 있으면 더 편할것 같더군요. 그리고 웹에서 괜찮은 튜토리얼이 별로 없더군요. 제가 작업하면서 배운 내용들을 간단하게 설명할께요.

설치하시면 AutoIt Window Info라는 툴이 있습니다. 여기서 창 이름, 마우스의 위치 등을 확인할수 있습니다. 옵션에 보면 Coord Mode를 Window에 맞추세요. 아니면 창위치가 바뀌면 곤란해집니다. 그리고 스크립트 맨앞에 아래를 추가하세요.

AutoItSetOption("MouseCoordMode", 0)


기본적인 사용방법은 아주 간단합니다.
먼저 입력할 윈도우를 찾고 마우스 클릭이나 키보드 입력을 전달하면 됩니다. 아래는 메모장을 띄우고 텍스트를 입력하고 마우스로 메뉴를 클릭하면 종료하는 내용입니다.

AutoItSetOption("MouseCoordMode", 0)

Send("#r")                        ;    Windows-r (실행)
WinWaitActive("실행")            ; 실행창 기다리기
Send("notepad{ENTER}")            ; 메모장 실행
WinWaitActive("제목 없음 - 메모장")    ; 메모장 창 기다리기
Send("Hello AutoIT!")            ; 메모장에 키 입력
MouseClick("left",26,38)        ; 파일 클릭
Sleep(500)                           ; 500ms (0.5초) 기다리기
MouseClick("left",26,185)         ; 끝내기 클릭

Send에서 #은 윈도우키, ^은 Ctrl, -는 Shift, !은 Alt입니다. 그리고 {}에 들어가는 키들은 메뉴얼을 참고하세요.

WinWaitActive는 새창으로 뜨는 창을 기다리는 것이고, 이미 떠있는 창을 찾으려면 WinActivate 함수를 이용하면 됩니다.

Sleep함수 호출은 위에서 필요없지만... 시스템이 느리거나 네트웍을 통해서 정보를 받아오거나 하면 Sleep를 얼마나 줄지 정하는게 매우 중요해집니다.

한글을 Send로 보내면 깨지는데 이럴경우 클립보드를 이용해서 보내면 안깨집니다. 클립보드로 복사하고 Ctrl-v로 붙이기하면 됩니다.

ClipPut("한글을 클립보드를 통해서 보내면 됩니다.")
Send("^v")

디버깅은 WriteConsole 함수 이용하면 됩니다. 변수는 아래처럼 쓰고, 문자열은 &로 합칠수 있고, @CRLF가 다음줄로 넘어가는 겁니다.

$var = "value"
WriteConsole("var =" & $var & @CRLF)

프로그램이 복잡해지다보면 함수를 정의하시면 됩니다. 다만 함수 내에서 사용하는 인자를 제외한 변수들이 전역 변수로 취급됩니다! 아래 프로그램 실행하면 "2, 3"이 출력됩니다.

$g = "1"
$x = "3"
testFunction($x)
ConsoleWrite($g & ", " & $x & @CRLF)

Func testFunction($z)
   $z = "4"
   $g = "2"
EndFunc


위에 설명한 내용과 조건문과 반복문 정도(메뉴얼 참고하세요) 알면 어느정도 자동화를 할수 있습니다. 문제는 화면 출력이 일정하지 않을때인데... 대부분 웹페이지들의 출력이 일정하지 않습니다. 이럴때 필요한 것이 IE.au3 입니다. Internet Explorer 모듈인데 사용하기 전에 아래처럼 사용한다고 포함해야합니다.

#include <IE.au3>

함수들은 모두 _IE로 시작합니다. IE에 네이버 띄우고 검색창에 AutoIT입력하고 검색하는 예제입니다.

#include "IE.au3"

$oIE = _IECreate("www.naver.com")
$query = _IEGetObjById($oIE, "query")
_IEDocInsertText($query, "AutoIT")
$form = _IEFormGetObjByName($oIE, "search")
_IEFormSubmit($form)

AutoIT의 버그인지 모르겠으나 이미 존재하는 창에 _IEAttach가 잘 안되었는데 윈도우 핸들을 먼저 구해서 붙이면 잘 붙더군요...

$hWnd = WinGetHandle ($winname)
$oIE = _IEAttach($hWnd, "HWND")



ffmpeg 관련하여 자료 찾다가 발견한 정보! Dr. Dobb's Journal은 프로그래밍 관련한 잡지중 제일 알아주는 잡지죠. 이걸 온라인으로 볼수 있는 곳이 있네요.

codeluv님의 블로그를 통해서 알게 되었습니다.

http://codeluv.tistory.com/entry/Dr-Dobbs-Journal

현재 2006년 8월부터 2008년 4월까지 있습니다.

2006년
http://www.nxtbook.com/nxtbooks/cmp/ddj0806/index.php : 2006년 8월
http://www.nxtbook.com/nxtbooks/cmp/ddj0906/index.php : 2006년 9월
http://www.nxtbook.com/nxtbooks/cmp/ddj1006/index.php : 2006년 10월
http://www.nxtbook.com/nxtbooks/cmp/ddj1106/index.php : 2006년 11월
http://www.nxtbook.com/nxtbooks/cmp/ddj1206/index.php : 2006년 12월

2007년
http://www.nxtbook.com/nxtbooks/cmp/ddj0107/index.php : 2007년 1월
http://www.nxtbook.com/nxtbooks/cmp/ddj0207/index.php : 2007년 2월
http://www.nxtbook.com/nxtbooks/cmp/ddj0307/index.php : 2007년 3월
http://www.nxtbook.com/nxtbooks/cmp/ddj0407/index.php : 2007년 4월
http://www.nxtbook.com/nxtbooks/cmp/ddj0507/index.php : 2007년 5월
http://www.nxtbook.com/nxtbooks/cmp/ddj0607/index.php : 2007년 6월
http://www.nxtbook.com/nxtbooks/cmp/ddj0707/index.php : 2007년 7월
http://www.nxtbook.com/nxtbooks/cmp/ddj0807/index.php : 2007년 8월
http://www.nxtbook.com/nxtbooks/cmp/ddj0907/index.php : 2007년 9월
http://www.nxtbook.com/nxtbooks/cmp/ddj1007/index.php : 2007년 10월
http://www.nxtbook.com/nxtbooks/cmp/ddj1107/index.php : 2007년 11월
http://www.nxtbook.com/nxtbooks/cmp/ddj1207/index.php : 2007년 12월

2008년
http://www.nxtbook.com/nxtbooks/cmp/ddj0108/index.php : 2008년 1월
http://www.nxtbook.com/nxtbooks/cmp/ddj0208/index.php : 2008년 2월
http://www.nxtbook.com/nxtbooks/cmp/ddj0308/index.php : 2008년 3월
http://www.nxtbook.com/nxtbooks/cmp/ddj0408/index.php : 2008년 4월

링크열고 위에 SAVE 버튼 누르시면 저장할 수 있습니다.
pdf와 exe(플래시)로 만든게 있는데, exe가 편하고, 파일 크기도 작네요.


Nikon 디카를 사용하는데 동영상을 찍으면 QuickTime으로 저장됩니다. PC에서 보는거야 코덱깔면 문제없지만, 사용중인 디빅 플레이어인 랩소디에서 재생이 안됩니다. 그리고 엑박에서도 재생이 안됐었던거 같네요.

바닥 프로그램에서는 변환은 되지만, 뭐가 문제인지 소리가 안나더군요. 몇가지 변환 프로그램을 구해서 써봤는데 대부분 mencoder나 ffmpeg를 내부엔진으로 사용하는듯하더군요. 바닥이 mencoder 기반이라 ffmpeg로 직접 변환을 해보니 문제 없이 변환이 되네요.

ffmpeg은 http://ffdshow.faireal.net/mirror/ffmpeg/ 에서 최신 버전을 구했으며, python으로 간단히 프로그램을 짜서 여러 파일들을 한꺼번에 변환했습니다. 처음에는 msmpeg4v2, msmpeg4, mpeg4 등의 비디오 코덱으로 변환했는데 랩소디에서 xvid가 가장 무리없이 재생이 되는군요. video bitrate는 1500, audio는 lame mp3로 변환합니다. 640x480, 15 frames/sec QuickTime에서 avi로 변환하면 약 반에서 3분의 1 정도로 줄고 화질은 약간 나빠지는 정도입니다.

변환하는 파일명에 공백등이 포함되면 변환이 안되는 버그가 생겨서 os.system대신 os.spawnv를 사용했습니다. os.system에 여러곳에 "따옴표"를 쓰면 실행파일 경로를 제대로 인식못하는 버그가 있는거 같습니다.


import os
import glob

ffmpeg_path = 'C:/Program Files/Free/ffmpeg.rev12665/ffmpeg'

def converted_name(filename):
  filename = filename.replace(".MOV", ".AVI")
  filename = filename.replace(".mov", ".avi")
  return filename

def convert(filename):
  aviname = converted_name(filename)
  if os.path.exists(aviname):
    print "skipping %s" % filename
    return
  args = '-i "%s" -g 15 -b 1500k -vcodec libxvid -acodec libmp3lame -ab 64k -ar 22050 "%s"' % (filename, aviname)
  os.spawnv(os.P_WAIT, ffmpeg_path, ['"%s"' % ffmpeg_path, args])

def main():
  filelist = glob.glob("*/*.mov")
  for filename in filelist:
    convert(filename)

if __name__=='__main__':
  main()
 



사용자별 최근 변경 사항 보는데 Trac report 만드는게 쉽지 않더군요. 더 쉬운 방법이 있는지 잘 모르겠지만... SQL 잘 하시는 분의 도움을 받아 만든 쿼리입니다. 저는 SQL을 잘게 짤라서 만드는 편인데, SQL 조금 복잡해지면 어렵고, 최적화도 어려워지죠.. 사용자 아이디와 출력되는 갯수가 하드코딩 되어야 해서 좀 그렇긴 하지만... 그래도 원하는대로 출력은 잘 해줍니다.


select
   p.value AS __color__,
   owner AS __group__,
   id AS ticket,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   summary,
   component,
   priority,
   t.type AS type,
   status,
   time AS _created,
   changetime AS modified,
   description AS _description,
   reporter AS _reporter

from (

  select * from (SELECT * FROM ticket WHERE owner='mix1009' ORDER by changetime desc limit 0,5) u1

union

  select * from (SELECT * FROM ticket WHERE owner='user2' ORDER by changetime desc limit 0,5) u2

union

  select * from (SELECT * FROM ticket WHERE owner='user3' ORDER by changetime desc limit 0,5) u3

union

  select * from (SELECT * FROM ticket WHERE owner='user4' ORDER by changetime desc limit 0,5) u4

union

  select * from (SELECT * FROM ticket WHERE owner='user5' ORDER by changetime desc limit 0,5) u5


) t, enum p

where p.name = t.priority AND p.type = 'priority'
order by owner, changetime desc
 


cccc.sf.net 에 있는 오픈 소스 프로젝트입니다.

CI(Continuous Integration)에 대한 내용을 보면, 일차적으로 빌드 서버를 구축하여, 컴파일 오류등이 있을때 바로 개발자에게 피드백을 줍니다. 더 나아가, 테스트 케이스 등을 추가하여 테스트가 모두 통과하는지도 체크하고, 소스 구조 등을 체크하여 문제점을 점검하여 알려주도록 하고 있습니다. CI라는게 자바와 밀접한 관련이 있어서 대부분의 툴들이 자바를 위해서 개발되어 있습니다.

C++에서 사용할만한 소스 코드 체크 프로그램이 있나 찾다가 http://www.laatuk.com/tools/review_tools.html 에서 많은 정보를 얻을수 있었습니다. 많은 툴들이 있는데 종류도 좀 다양한 것 같습니다. 소스에서 문제점을 찾아주는 툴들도 있지만, 이런건 Numega Boundschecker를 사용하면 될거 같고, 자동으로 소스 코드의 문제점을 찾아주는 것은 한계가 있습니다.

여기 툴중에 CI에 통합해서 소스의 건전성을 나타내주는 잣대(metric) 정도로 활용할수 있는 툴을 골라봤습니다. CCCC의 이름을 보면 단순히 소스 라인수를 세는 툴 같지만 훨씬 더 많은 정보를 제공합니다. 아직 CI에 통합해서 쓸수 있을만큼 자유롭게 커스터마이징이 가능한지는 확인 못했지만, 여러가지 의미있는 분석 결과들이 나옵니다.

소스를 클래스별로 구분하여 소스라인수, 주석라인수, 복잡도 등을 분석하여 어떤 클래스가 일을 많이 하는지, 문서화가 덜 되어 있는지를 보여줍니다. 출력이 HTML로 나오는데 정렬이 안되는게 좀 아쉽네요. 액셀에 원하는 부분 붙여넣기하여 정렬하면 어느정도 편하게 결과를 볼수 있긴 합니다. 그리고, 클래스별로 정리해서 보여주기 때문에 전역 함수는 따로 봐야합니다. 전역 함수들은 anonymous 모듈에 들어갑니다.

분석 결과가 여러 항목별로 정리되어 나오는데, 아직까지는 Procedural Metrics Summary에 대한 내용만 대충 이해하고, 나머지는 좀더 연구해야 할것 같네요.

분석하면 5가지 항목으로 나누어 결과가 나옵니다.

  1. Project Summary : 전체 종합 정리입니다.
  2. Procedural Metrics Summary : 절차 중심 분석 (소스라인수, 주석라인수, 복잡도)
  3. Object Oriented Design : 얼만큼 객체 지향적으로 설계되었는지?
  4. Structural Metrics Summary: 각 모듈별 연관성을 분석
  5. Other Extents: 분석 실패한 부분에 대한 내용

여기서 나오는 약자와 용어들이 있는데...
  • NOM : Number of Modules 모듈수 (클래스수)
  • LOC : Line of Code (소스 라인수 - 주석 제외)
  • MVG : McCabe's Cyclomatic Number (함수의 복잡도를 측정하는 단위)
  • Fan-out : 현재 모듈에서 사용하는 다른 모듈의 수 (현재 모듈에서 다른 모듈로 정보 전달)
  • Fan-in : 현재 모듈을 사용하는 다른 모듈의 수 (다른 모듈에서 현재 모듈로 정보 전달)
  • IF4 : Information Flow measure : 모듈간 정보 전달의 복잡도를 측정하는 단위

MVG나 IF4는 높을수록 복잡한겁니다. 낮게 해야 유지관리하기 편한 소스가 되겠죠.

MVG는 위키피디아에 잘 나와있으며, 복잡도 측정하는 단위로 소스에 얼마나 많은 실행 경로가 있는지를 분석하는 방법입니다. 분기가 전혀 없으면 1, if문이 하나 추가되면 2. 이런식으로 계산되는데 C에서 조건문 안의 (a && b)나 a?b:c 같은것도 분기에 해당하니 사람의 손으로 직접 계산하는 거는 쉽지 않습니다.

그럼 이제 CCCC의 사용방법을 보죠. 사용법은 간단합니다. 소스 분석 원하는 경로에서
유닉스라면 쉘에서
% find . | cccc -

윈도우즈에서는 CCCC Command Line에서
> dir /b/s | cccc -


하면 현재 디렉토리 밑의 모든 소스를 분석하여, .cccc 폴더 안에 cccc.html을 비롯하여 여러파일들이 출력됩니다. 종합 결과는 cccc.html에 있고, 각 클래스별로 html이 따로 생성되고 상세 정보를 포함하고 있습니다.

자세한 내용은 몰라도 빨간색과 노란색으로 문제 있는 부분을 보여줍니다.
위에서 언급한대로 필요한 부분 액셀로 복사해서 정렬해서 보고 있으며, 아직 Procedural Metrics Summary 부분만 유심히 보고 있습니다.

요즘 Varnish Cache를 본격적으로 도입하기 위해서 노력중입니다. 설계 문서를 보면 많이 사용하는 Squid는 70/80년대 하드웨어에 적합하게 설계되었기 때문에 요즘 하드웨어에서는 퍼포먼스가 아주 많이 떨어진다는 흥미로운 얘기가 있습니다.

Squid에서는 소프트웨어적으로 캐시를 따로 구현해서, 커널에서 메모리 관리하는 것과 같이 잘 동작하지 않는다고 합니다. 소프트웨어적으로 캐시를 따로 구현하면 필요하지 않은 메모리 영역을 swap out할때, 똑똑한 커널에서 이미 swap out됐던 데이터를 메모리 영역으로 불러왔다가 다시 swap out 하는 과정이 일어난다고 합니다. 옛날 OS에서는 메모리 관리가 최적화가 안되어있었지만 요즘은 메모리 관리를 커널에서 알아서 하게 하면 퍼포먼스가 많이 빨라진다고 하네요.

Varnish Cache 최적화는 크게 3가지 정도로 요약할수 있을거 같습니다.

1. 메모리 관리를 커널에 위임
2. 메모리 할당/해제 부분을 최소화 (workspace 단위 할당, 한번에 해제)
3. 설정 파일 컴파일러로 컴파일

메모리 관리는 mmap을 통해서 관리합니다. 파일 시스템 영역과 메모리 영역을 연결하여 사용하고, storage_file.c에서 직접 메모리 쪼개서 관리합니다. 메모리 영역을 쪼개서 free list(VTAILQ)에 넣고, 할당할때 free list에서 꺼내서 쓰는 방식입니다. 프로그램에서는 무엇이 메모리에 있고, 파일로 swap 할지 결정하지 않고 커널이 하도록 내버려둡니다.

메모리 할당은 workspace 단위로 하고 그 안에서 쪼개서 쓰는 거 같습니다. 이 부분은 좀더 분석이 필요할거 같습니다.

설정 파일은 c로 변경한 다음 저장하고, 직접 cc를 호출해서 오브젝트 파일을 생성하며, dlopen으로 로드하게 되어있습니다.  mgt_vcc.c의 mgt_CallCc 함수를 참고하세요. dlopen을 사용하기 위해서 컴파일러에 -fpic -shared 등의 옵션을 넘기게 되어있습니다.

Varnish의 개발자가 FreeBSD 커널 개발자 출신입니다. 지금도 개발하는지는 모르겠네요..Varnish는 정말 BSD커널 소스처럼 짜놨네요. BSD 커널 소스보면 데이타 구조가 대부분 queue.h로 되어있는데, 여기서도 VTAILQ 등으로 이름만 조금 바꿔서 사용하고 있습니다. queue.h는 여러가지 데이타 구조를 C 매크로만으로 구현한 헤더파일 라이브러리입니다. 구현할때 struct 안에 포인터가 내장되서 여러가지 방법으로 메모리 사용을 최적화할수 있습니다. 커널에서는 대부분 블럭단위로 메모리 할당하여, 그걸 쪼개서 free 리스트에 넣어놓고 그걸 꺼내써서 사용하는 방식으로 메모리를 관리합니다. 메모리 할당과 해제가 간단한 포인터 연산으로 끝나기 때문에 매우 효율적이고, 메모리 fragmentation도 많이 줄여줍니다. 메모리 할당과 해제가 자주 일어나는 경우 아주 큰 도움이 되죠.

2000년에 FreeBSD에서 방화벽 커널 모듈을 개발한 적이 있었는데, 메모리 관리를 queue.h와 "Redesigning the BSD Callout and Timer Facilities (1995)"를 참고해서 구현했었습니다. 퍼포먼스 최적화에 아주 큰 도움이 됐었습니다. Redesigning the BSD Callout... 논문을 어떻게 알게 되었는지는 기억은 안나지만, 정말 많은 도움을 받았던 논문이네요. 지금 찾아보니 첫번째 저자는 구글에 있고, 두번째 저자는 벤처 만들었다가 시스코에 인수됐다고 하네요. 지금은 UCSD 교수로 있네요. 이 논문에 대해서는 블로그에 글을 한번 정리해서 올리도록 노력하겠습니다.

2008년 1월 26일 파리에서 OCaml 미팅이 있었나봅니다.

프리젠테이션과 mp3 파일이 올라왔네요. 평소에 관심만 있고 실제적으로는 활용을 아직 못하고 있는 언어인데... (LISP도 마찬가지) 여러가지로 관심이 가는 언어입니다. 요즘은 다이나믹 언어가 추세이긴 하지만, static type checking도 프로그램 안정성에 많은 기여를 하죠. Ocaml에서는 type inference 지원으로 자바처럼 열심히 type 선언을 안해줘도 됩니다. static type checking을 위해서 프로그래머가 노가다할 필요도 없고, 안전하면서도 유연한 소스가 나오죠... 언어적인 측면도 좋고, 컴파일러도 구현도 아주 잘 되어있지만, 라이브러리(특히 윈도우 관련 라이브러리)가 풍성하지 못해서 아직 활용을 못하고 있습니다.

아래 페이지에서 프리젠테이션과 mp3를 구할수 있습니다.
http://wiki.cocan.org/events/europe/ocamlmeetingparis2008

프랑스 파리에서 했는데, 모두 영어로 되어있는거 같긴 하네요. 다만 mp3가 너무 작게 녹음됐네요. mp3gain으로 볼륨 조절하시면 됩니다.

제가 요즘 실제로 사용하는 언어는:
   C++
   Python
   PHP
   Javascript
   Actionscript

관심있는 언어는:
   LISP
   Objective Caml
   D언어
   Smalltalk

입니다.

전에 Visual Studio에서 precompiled header 설정을 바꿔서 컴파일 시간을 대폭 줄인 글을 올렸었습니다. 그때 여러가지 컴파일 속도를 향상할수 있는 방법을 찾다가 발견한게 Incredibuild인데 평가판(30일)을 설치해서 회사에서 적용해 보았습니다.

최근 접한 프로그램 중에 개념도 신선하고, 구현도 아주 잘 된 소프트웨어네요.

Coordinator와 Agent로 설치할수 있는데, Coordinator는 빌드를 전체적으로 관리해주는 서버 프로그램으로 네트워크에 하나만 설치하면 되고, Agent는 Coordinator 서버에 연결해 있다가 작업을 할당 받아 처리하는 프로그램입니다. Agent를 많이 깔아주면 속도 향상이 그만큼 되죠.

신기한거는 Agent 설치하는 피씨에 개발툴이 없어도 된다는 겁니다. 컴파일러까지 전송해서 실행하는 방법으로, 처음 빌드를 요청한 컴퓨터의 빌드시스템을 그대로 받아서 실행하기 때문에 시스템간의 버전 차이, 헤더파일 차이 문제 때문에 빌드가 이상하게 되는거를 방지할수 있습니다. PC에 Agent만 설치하면 되기 때문에, 개발툴을 설치하지않고 쉽게 여러 컴퓨터에 설치할수 있는것도 큰 장점입니다.

또한, Visual Studio 6.0이 Multi CPU를 전혀 활용하지 않기 때문에 하나의 피씨에만 깔아도 속도 향상을 시킬수 있습니다.

아래는 coordinator 상황을 볼수 있는 모니터 프로그램입니다. 8개의 PC가 등록되어 있으며, 현재 온라인이 4개입니다. 요즘은 거의 Dual Core이기 때문에 CPU는 16개 입니다.



아래는 빌드했을때 모습입니다. 빌드는 Visual Studio안에 Incredibuild 메뉴에서 Rebuild로 할수 있습니다. 6개의 PC가 사용되었고, 사용한 CPU는 12개 입니다.



아주 비주얼하게 보여주기 때문에 눈도 즐겁죠^^ 설치하고 몇번을 rebuild all하면서 빌드 속도에 만족하고 있습니다. Visual Studio안에 창이 나타나며, 별도로 창을 띄워서 볼수도 있습니다. 원래 네모 상자안에 소스 파일명이 나왔지만 회사 보안상(?) 지웠습니다. 초록색이 이상없이 컴파일 된거고, 오류가 나면 빨간색, 경고가 있으면 노란색으로 표시됩니다. 하늘색은 초기에 종속성 분석과정과 링크 과정입니다. 위에 그래프는 여러가지 중에 선택해서 보여줄수 있도록 되어있는데, 파란색이 실제로 사용한 CPU 사용량(GHz 단위), 빨간색이 유효하게 사용한 CPU 사용량입니다. 차이가 나는 이유는 일을 시키고 늦게 처리되는거나 종속성 때문에 따로 돌릴수 있는 작업이 없을때는 중복적으로 일을 시키고 그중 빨리 처리되는 결과를 받아서 처리하기 때문입니다. 위 그래프 상에서 최대값이 27.5GHz입니다 ^^.

원래 5:21.9 초 걸리던 빌드 시간이, precompiled header 설정 오류를 고치고 1:32.8 초로 incredibuild를 도입하고 나서는 23.5 초로 줄었습니다. 원래보다 13.7배, precompiled header 설정 오류를 고치고 나서 기준으로 보면 3.9배 빨라졌습니다. 사용한 CPU에 비해서 아주 많이 빨라진건 아니지만 컴파일하고 기다리는 시간이 즐겁고 짧아졌네요.

하지만, 실제적으로 개발할때 rebuild all하지 않고 바뀐 부분만 컴파일하기 때문에 incredibuild 도입효과는 생각보다 크지 않습니다. 링크과정 자체는 분산해서 처리하기가 애매하기도 하고, 컴파일된 결과를 모두 받아와서 링크하는 과정을 거쳐야하기 때문에 그런거 같습니다. 그리고 Agent를 추가한다고 지속적으로 속도가 비례해서 증가하지 않습니다. 네트워크 Bandwidth의 영향도 있고, 소스간 종속성 때문에 분산해서 한꺼번에 처리할수 있는 일의 수가 어느정도 정해져 있기 때문입니다. 소스간 종속성을 줄이면 개선이 가능하겠지만, 중소규모의 소프트웨어 프로젝트에서는 도입 효과가 크지 않을거라 생각합니다. 단, 빌드 서버를 구축한다면 아주 좋은 방법이 될거 같네요. 그런데, 가격이 문제입니다! 카피당 $350.

30일간 평가판을 사용해볼수 있으니, 빌드시간이 문제가 된다면 한번 사용해보시기 바랍니다.
http://www.xoreax.com/download.htm

Trac report

프로그래밍 2008/01/04 01:36
2008년 들어서 회사 개발팀에서 모든 일을 Trac의 티켓으로 관리하기로 했습니다.

Trac이 한글화 되어있지 않은거 같아서 몇가지 간단한거는 한글로 바꿨습니다.

현재 0.10.4 버전을 사용중인데, 설정 변경은 TracWebAdmin 플러그인을 통해서 했습니다. 새버전에는 Admin 기능이 Trac에 통합된다고 하는데, 정말 없으면 안되는 필수 기능입니다.

Priority를 영어에서 1,2,3,4,5로 바꾸고,
Type은 버그수정, 기능개선, 새로운기능으로 변경했습니다.

개발팀 밖에서 티켓 등록 및 모니터링을 할수 있도록, Permission을 바꿨습니다.
먼저 개발자(developers) 그룹을 생성하고, TIMELINE_VIEW와 BROWSER_VIEW 액션을 anonymous에서 developers로 옮겼습니다. (삭제하고 다시 등록)

Trac의 사용자 인증은 htpasswd를 사용하며, 웹서버는 lighttpd를 사용하고 있습니다.

View Tickets 페이지 보면 report를 편집할수 있는데,  편집해서 TODO와 최근변경사항을 만들었습니다. TODO는 아직 완료되지 않은 일(티켓)을 내거와 다른사람거로 나누어 보여주며, 우선도에 따라 정렬해 보여줍니다. 바탕색도 우선도에 따라서 보여줍니다. 아래는 report를 위한 SQL Query입니다.


SELECT p.value AS __color__,
   (CASE owner
     WHEN '$USER' THEN 'My Tickets'
     ELSE 'Active Tickets'
    END) AS __group__,
   id AS ticket,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
  summary, component, priority, t.type AS type,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY (owner = '$USER') DESC, p.value, milestone, t.type, time
 


최근변경사항은 티켓에 일어난 최근 변경 사항을 20개 보여줍니다. 물론 Timeline에서도 볼수 있지만, Timeline을 개발자만 볼수 있고, 소스 커밋과는 별도로 볼수 있도록 하는게 편리할것 같아서 따로 report를 생성했습니다.


SELECT
   id AS ticket,
  summary,
   changetime AS modified,
  status,
  component,
   t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   description AS description,
   reporter AS _reporter
  FROM ticket t
  ORDER BY changetime desc limit 0,20
 



trac report 만드는데 참고할 문서가 별로 없어서 좀 헤맸는데... 위에서 reporter as _reporter식으로 "as _*"로 하면 테이블에서 항목이 표시가 안됩니다. 기본 예제들을 자세히 보면 항목이 뭐가 있는지 볼수 있으므로 기본 예제들을 참고하시고 조금씩 바꾸면 원하는 출력을 얻을수 있습니다.

TODO와 최근변경사항 링크를 메뉴로 쉽게 접근할 수 있도록, http://trac-hacks.org/wiki/NavAddPlugin를 설치했습니다.

얼마전(12월6일)에 TortoiseSVN에서 Merge기능을 사용하다가 새로운 기능을 찾았습니다.
Commit 통계를 그래프로 그려주는 기능이 있더군요! 이제 회사 생긴지도 6년이 넘었고, 연말이고 해서 지난 Commit 통계를 그래프로 그려봤습니다.

회사는 2001년 말에 만들어졌고, APP 개발만 SVN으로 관리하고 있습니다. 원래 CVS로 관리했었는데 작년에 SVN으로 갈아탔습니다. CVS에서 파일단위로 커밋이 관리되는데, SVN으로 가져올때 커밋단위로 변경해서 가져와서 통계내는데도 전혀 문제가 없네요.

먼저 회사의 SVN은 세가지로 관리됩니다. 내부 개발이 Develop, 외부 프로젝트가 Project, 실험 프로젝트가 Test. Test에서 어느정도 쓸만하게 되면 Develop으로 옮겨갑니다. 외부 프로젝트의 경우 외부 저장소에서 관리되는 경우도 있어서 이런 경우는 포함되어 있지 않습니다.



예상외로 그래프가 들쑥날쑥하지는 않네요. 2002년까지는 3명정도, 그 이후로는 4명 정도가 개발인원으로 유지되고 있는거 같네요. 예전엔 외부 프로젝트가 많아서 인당 프로젝트가 할당되서 스트레스 받았었는데, 요즘은 외부 프로젝트를 안해서 그래도 살만합니다.

현재 revision 10948으로 대략 한달에 20일 일한다고 하면 하루 8회 정도 commit이 일어났네요..

아래는 올해 Develop commit 그래프 입니다.

새로 들어온 사람들이 잘 적응하고 있는거 같아서 다행이네요.

아래는 사용자별 그래프입니다. 제가 제일 commit은 많이 하는데... 다른 사람들은 commit하는 주기가 저에 비해서 좀 길어서 그런거 같습니다.


TortoiseCVS에도 이런 기능이 있는지는 모르겠지만 CVS에서 SVN으로 바꾼 이후 후회한적이 거의 없습니다. Trac의 소스보기가 CVSWeb하고 인터페이스가 좀 틀려서 Revision보느거하고 Diff보는게 헷갈렸던거 빼고는 정말 장점이 많네요.

위 그래프를 개발자들에게 보여주니 commit 자주해야겠다고 하네요. commit 횟수가 아닌 commit 라인수 단위로 그래프를 그려볼수 있는 방법이 없나 찾아봐야겠네요.