2008년 회사 SVN 로그 분석

작년에 TortoiseSVN의 통계 그래프 기능을 이용해서 분석을 했었는데, 올해는 약간의 프로그래밍으로 좀더 자세히 분석을 해보았습니다. 작년에는 단순히 commit 회수만 통계에 반영이 되었는데, 이번에는 commit 회수와 commit할때 라인수 (정확히는 svn diff 의 라인수)로 분석을 했습니다. 분석을 위해서 svn log, svn diff의 결과값을 python으로 취합하여 분석했습니다. svn log, svn diff에서 결과를 가져오는게 생각보다 시간이 오래걸려서 commit별로 결과를 파일에 저장하는 script와 분석하는 script를 따로 작성했습니다.

먼저 svn에 로그인할때 암호를 물어보지 않도록 .ssh/id_rsa 키를 생성, 패스워드를 제거하고, svn의 상위 디렉토리만 checkout 했습니다.

$ svn checkout -N svn+ssh://mix1009@www.company.com/SVNROOT/Develop

여기서 아래 python 스크립트(svnlog_dump.py)를 이용해서 svn_stat.txt 파일을 생생했습니다.

[CODE type=”python”]
import os

def main():
   log_s = os.popen(“svn log”)
   while 1:
       line = log_s.readline()
       if not line: break
       line = line.strip(“\n”)
       x = line.split(“|”)

       if len(x) != 4: continue

       rev = x[0].strip()[1:]
       user = x[1].strip()
       date = x[2].strip().split(” “)[0]
       comment = x[3].strip().split(” “)[0]

       #print(line)
       wc = os.popen(“svn diff -c %s | wc” % rev).read()
       wc = wc.strip(“\n”)
       wc = “,”.join(wc.split())
       wc = wc.strip(” “)
       open(“svn_stat.txt”, “a”).write(“%s, %s, %s, %s, %s\n” % (rev, user, date, comment, wc))
       print(“%s, %s, %s, %s, %s” % (rev, user, date, comment, wc))

if __name__ == ‘__main__’:
   main()
[/HTML][/CODE]

각 라인별로 하나의 commit의 내용을 저장합니다. revision, 커밋한사용자, 날짜, 커밋설명라인수, diff라인수 등이 저장됩니다.

아래 python 스크립트(svnlog_analyze.py)를  이용하여 svn_stat.txt 내용을 분석합니다.

[CODE type=”python”]
# diff length > 5000 -> source import or copy
validcommitthreshold = 5000

m = {} # year -> {user -> [comment, commitcount, linecount, validlinecount]}
f = open(“svn_stat.txt”)
while 1:
   line = f.readline()
   if not line: break
   line = line.strip(“\n”)
   x = line.split(“,”)
   #[‘9674’, ‘ mix1009’, ‘ 2007-03-30’, ‘ 1’, ‘ 15′, ’36’, ‘522’]

   if len(x) != 7: continue

   #print line
   rev = x[0].strip()
   user = x[1].strip()
   date = x[2].strip()
   comment = int(x[3].strip())
   linecount = int(x[4].strip())

   year = date[:4]
   #print year, user, comment, linecount
   if not m.has_key(year):
       m[year] = {}

   ym = m[year]
   if not ym.has_key(user):
       # [comment, commitcount, linecount, validlinecount]
       ym[user] = [0, 0, 0, 0]

   validlinecount = 0
   if linecount <= validcommitthreshold:
       validlinecount = linecount

   ym[user] = [ym[user][0]+comment, ym[user][1]+1, ym[user][2]+linecount, ym[user][3]+validlinecount]

k = m.keys()
k.sort()
for year in k:
  print(“[%s]”%year)
  for user in m[year].keys():
   print(”    %s : %s”%(user, m[year][user]))
[/HTML][/CODE]

연도별로 나눠서 각 사용자의 commit설명라인수, commit회수, commit diff 라인수, 유효 commit diff 라인수를 출력합니다. 유효 commit이라는걸 만든 이유는… 소스 import나 copy 같은걸 할 경우 상당히 많은 양의 commit 라인수가 발생해서 정확한 분석이 안되서.. commit 라인수의 분포를 액셀에서 그려보고, 어느 정도의 라인수까지가 소스를 손으로 작성했는지 대충 분석해서 diff가 5000라인 정도 이상이면 소스 import나 copy로 취급했습니다.

2007년과 2008년 결과값입니다.

[2007]
   mix1009 : [929, 687, 1183649, 117023]
   user1 : [152, 142, 432097, 46889]
   user2 : [199, 197, 475667, 70801]
   user3 : [197, 187, 24676, 24676]
[2008]
   mix1009 : [776, 574, 1135963, 119820]
   user1 : [316, 281, 1634243, 101233]
   user2 : [203, 163, 120608, 46729]
   user3 : [428, 292, 44474, 44474]
   user4 : [141, 132, 46616, 30751]

올해는 제가 회의도 많고 해서 개발에서 좀 빠져있을려고 했는데… 아직은 개발에서 손뗄수 있는 시기는 아닌거 같네요. 그리고 모든 팀원들의 퍼포먼스를 끌어올리기 위해서 좀더 노력해야겠다는 생각이 드네요.

Leave a Reply

Your email address will not be published.