一、主分析脚本(StatisticsNum.sh)如下:
#!/bin/bash
echo "get cuurnt path"
basePath=$(cd $(dirname $0);pwd)
echo $basePath
cd $basePath
# define variables
# 统计起始时间
BEGIN_TIME=$1
# 统计截止时间
END_TIME=$2
#GitLab服务器分支存储默认路径,如有变更请同步修改
GITDATA_PATH="/var/opt/gitlab/git-data/repositories"
# 初始化相关路径
mkdir -p $basePath/report
mkdir -p $basePath/log
# 定义统计总天数函数(参数:起始日期、截止日期)
function CountEffectiveDays(){
BEGIN_SECONDS=$(date -d "$1" "+%s")
END_SECONDS=$(date -d "$2" "+%s")
DIFF_SECONDS=$[$END_SECONDS-$BEGIN_SECONDS]
expr $DIFF_SECONDS / 86400
}
# 定义计算时保留小数函数(参数:分子、分母、小数位数)
function KeepDecimal(){
# 分子
MEMBER=$1
# 分母
DENMOINATOR=$2
# 小数位数
DECIMAL_PLACES=$3
cat $basePath/KeepDecimal.sh > $basePath/countfile.sh
if [ ! -n "$DECIMAL_PLACES" ] ;then
DNUMBER="2"
echo "$AUTHOR DELETE IS NULL!"
fi
if [ ! -n "$DECIMAL_PLACES" ] ;then
DECIMAL_PLACES="2"
fi
sed -i "s#2#$DECIMAL_PLACES#g;" $basePath/countfile.sh
# 更新表达式
COUNTMET=$MEMBER/$DENMOINATOR
sed -i "s#countmet#$COUNTMET#g;" $basePath/countfile.sh
# 返回结果
echo $( sh $basePath/countfile.sh)
rm -rf $basePath/countfile.sh
}
# 计算统计总天数
TOTAL_DAYS=$( CountEffectiveDays $BEGIN_TIME $END_TIME )
# 定义记录日志函数
function logger(){
printf "%s\n" "$*" >> $basePath/log/StatisticsNum.log
}
# define add message function
function ShowMessage(){
echo "规则说明:"
echo "提交次数:统计周期内用户提交commit的总次数"
echo "日均提交:统计期内用户日均提交commit的次数"
echo "文件:统计周期内文件累计修改总数"
echo "变更:统计周期累计新增和修改总行数之和"
echo "删除:统计周期内删除的总行数"
echo "有效变更:统计周期内新增和变更的总行数"
echo "日均变更:统计周期内日均有效变更行数"
echo "变更度:变更/提交"
echo "修改一行记作增加一行且删去一行"
echo "merge操作内容不计入统计范围"
echo "Statistics time [$BEGIN_TIME $END_TIME)"
echo "Statistics total days $TOTAL_DAYS"
echo "Statistics total persons $TOTAL_PERSION"
}
# 文本转化格式化HTML函数(参数:名称 账号 提交次数 文件 变更 删除 有效变更 变更度 )
function HTMLFormat(){
HTML_PATH="$basePath/report/RESULT.html"
echo "<tr>" >> $HTML_PATH
echo "<th align="center">$1</th>" >> $HTML_PATH
echo "<th align="center">$2</th>" >> $HTML_PATH
echo "<th align="center">$3</th>" >> $HTML_PATH
echo "<th align="center" style="color:green">$4</th>" >> $HTML_PATH
echo "<th align="center">$5</th>" >> $HTML_PATH
echo "<th align="center">$6</th>" >> $HTML_PATH
echo "<th align="center">$7</th>" >> $HTML_PATH
echo "<th align="center">$8</th>" >> $HTML_PATH
echo "<th align="center" style="color:green">$9</th>" >> $HTML_PATH
echo "<th align="center">${10}</th>" >> $HTML_PATH
echo "</tr>" >> $HTML_PATH
}
echo "get contents and subdirectory path"
cd $GITDATA_PATH
# 1.遍历GitLab服务器全部可用群组
for file in $GITDATA_PATH/*
do
if test -f $file
then
echo "$file is a file"
else
echo $file
cd $file
# 2.遍历群组下的全部库
for sonfile in $file/*
do
if test -f $sonfile
then
echo "$sonfile is a file"
else
cd $sonfile
# 3.遍历不同库下的全部分支
git branch -a | sed 's/.//' | sed -e 's/^/pre /' | awk -F" " '{print $2}' | while read BRANCHNAME
do
# 获取单分支的相关使用信息源数据
echo $BRANCHNAME
# 获取有效用户列表
git log $BRANCHNAME --no-merges --pretty=format:"%ai,%cn:%s" --since="$BEGIN_TIME" --until="$END_TIME" | \
awk -F"," '{print $2}' | \
awk -F":" '{print $1}' > $basePath/USERLIST
# 4.遍历该分支下每个用户的提交信息
sort $basePath/USERLIST | uniq | while read USER
do
# 5.获取并格式化汇总元数据
git log $BRANCHNAME --no-merges --author="$USER" --stat --since="$BEGIN_TIME" --until="$END_TIME" | \
grep changed | \
awk '/insertion|deletion/' | \
while read LINE
do
echo "$USER $LINE" >> $basePath/CollectMetadata
echo "时间:$(date "+%Y.%m.%d-%H.%M.%S");库:$sonfile;分支:$BRANCHNAME;用户:$USER;单次源日志:$LINE;" >> $basePath/log/StatisticsNum.log
done
done
done
fi
done
fi
logger "Run by user " $(id -un) "at " $(/bin/date)
done
echo "information Statistics And Generate RESULT"
# 添加表头信息
echo "名称 账号 提交次数 日均提交 文件 变更 删除 有效变更 日均变更 变更度" > $basePath/report/RESULT
# HTML格式化头
echo "<table border="1">" > $basePath/report/RESULT.html
HTMLFormat 名称 账号 提交次数 日均提交 文件 变更 删除 有效变更 日均变更 变更度
# 遍历获取有效用户列表
cat $basePath/CollectMetadata | awk '{print $1}' | sort | uniq | while read USER
do
# 获取用户修改文件数
FILESSUM=$( cat $basePath/CollectMetadata | grep -w $USER | awk '{print $2}' | awk '{sum+=$1}END{print sum}' )
# 获取用户名称
USER_NAME=$( cat $basePath/userlist | grep -w $USER | awk '{print $2}' | head -1 )
if [ ! -n "$USER_NAME" ] ;then
USER_NAME="已清除账号"
fi
# 获取用户变更代码总行数
INSERTIONSSUM=$( cat $basePath/CollectMetadata | grep -w $USER | awk -F"insertion" '{print $1}'| awk -F"," '{print $2}' | awk '{sub(/^[ \t]+/,"");print $0}' | awk '{sum+=$1}END{print sum}' )
# 获取用户删除代码总行数
DELETIONSSUM=$( cat $basePath/CollectMetadata | grep -w $USER | awk -F"," '{print $NF}' | awk -F"deletion" '{print $1}' | grep -v insertion | awk '{sub(/^[ \t]+/,"");print $0}' | awk '{sum+=$1}END{print sum}' )
# 获取用户提交总次数
COMMITNUM=$( cat $basePath/CollectMetadata | grep -w $USER | awk '{a[$1]++}END{for(i in a){print i,a[i] | "sort -r -k 2"}}' | sort -n -b -t" " -r -k2 | awk '{print $2}' )
# 美化数据,将空值填充为o
if [ ! -n "$FILESSUM" ] ;then
FILESSUM="0"
echo "$USER FILESSUM IS NULL!"
fi
if [ ! -n "$INSERTIONSSUM" ] ;then
INSERTIONSSUM="0"
echo "$USER INSERTIONSSUM IS NULL!"
fi
if [ ! -n "$DELETIONSSUM" ] ;then
DELETIONSSUM="0"
echo "$USER DELETIONSSUM IS NULL!"
fi
# 计算日均提交次数
PREDAY_CNUMBER=$( KeepDecimal $COMMITNUM $TOTAL_DAYS 2 )
# 计算日均变更(日均变更=变更总数/统计总天数)
PREDAY_Eff=$( KeepDecimal $INSERTIONSSUM $TOTAL_DAYS 3 )
# 计算变更度(变更度=变更/提交次数)
MET=$( KeepDecimal $INSERTIONSSUM $COMMITNUM 2 )
# 归集生成最终结果文件
echo "$USER_NAME $USER $COMMITNUM $PREDAY_CNUMBER $FILESSUM $INSERTIONSSUM $DELETIONSSUM $INSERTIONSSUM $PREDAY_Eff $MET" >> $basePath/report/RESULT
HTMLFormat $USER_NAME $USER $COMMITNUM $PREDAY_CNUMBER $FILESSUM $INSERTIONSSUM $DELETIONSSUM $INSERTIONSSUM $PREDAY_Eff $MET
logger "Run by user " $(id -un) "at " $(/bin/date)
done
# 获取总人数
TOTAL_ROWS=$( cat $basePath/report/RESULT | awk '{print $1}' | uniq | wc -l )
TOTAL_PERSION=$( expr $TOTAL_ROWS - 1 )
# HTML格式化尾
echo "</table>" >> $basePath/report/RESULT.html
echo "<p>(Statistics TOTAL $TOTAL_PERSION PERSIONS )<br /></p>" >> $basePath/report/RESULT.html
echo "<p>Statistics time [$BEGIN_TIME $END_TIME)<br /></p>" >> $basePath/report/RESULT.html
echo "<p>Statistics total days $TOTAL_DAYS<br /></p>" >> $basePath/report/RESULT.html
echo "clean up temp files"
cd $basePath
rm -rf CollectMetadata USERLIST
# 格式化展示最终统计分析数据
echo "--------------------------------- EXPLAIN MESSAGES --------------------------------"
ShowMessage
echo "-------------------------------- FORMAT SHOW DATA --------------------------------"
column -t $basePath/report/RESULT
echo "-------------------------------- FORMAT SHOW END ---------------------------------"
if [ $? -eq 0 ]; then
echo "successed."
else
echo "failed , please check this script ."
exit 1
fi
二、计算保留变更度脚本(KeepDecimal.sh)内容如下:
#!/bin/bash
basePath=$(cd $(dirname $0);pwd)
cd $basePath
awk 'BEGIN{printf "%0.2f",countmet}'
三、将两个脚本拷贝到GitLab服务器的任意同一目录下
#userlist用户对应一览表
zhangsan 张三
lisi 李四
wangwu 王五
四、传参(开始时间、截止时间)运行脚本:
sh StatisticsNum.sh begintime endtime
-rw-rw-r-- 1 peizhi peizhi 95 12月 27 15:05 KeepDecimal.sh
drwxr-xr-x 2 root root 31 12月 27 15:06 log
-rw-rw-r-- 1 peizhi peizhi 121 12月 27 15:05 README
drwxr-xr-x 2 root root 39 12月 27 15:08 report
-rw-rw-r-- 1 peizhi peizhi 8443 12月 27 15:21 StatisticsNum.sh
-rw-rw-r-- 1 peizhi peizhi 13386 12月 27 15:05 userlist
[root@vm-ghxw-gitlab-h13-8 StatisticsNum]# sh StatisticsNum.sh 2021-12-1 2021-12-28
五、等待完成并展示结果即可