移动性能测试 Android 性能统计--网络流量统计 using ADB

dabao · 2015年02月27日 · 最后由 dabao 回复于 2019年05月18日 · 7931 次阅读
本帖已被设为精华帖!

因之前性能脚本针对流量统计在某些机型如(红米 note)上不支持,故对流量部分做了调研和改进
1、 之前统计是 cat proc/uid_stat/(uid#)/tcp_rcv 路径下

adb shell cat proc/uid_stat/(uid#)/tcp_rcv
adb shell cat proc/uid_stat/(uid#)/tcp_snd

对二者求和,劣势是只针对 tcp 协议网络的消耗统计,且在某些机型上不存在该路径。
故进行了优化。

2、 经调查/proc/net/xt_qtaguid/stats 基本覆盖目前所有机型且统计流量全面

adb shell cat /proc/net/xt_qtaguid/stats | grep (uid#)

如: adb shell cat /proc/net/xt_qtaguid/stats | grep 10127

48 wlan0 0x0 10127 0 316574 2279 472562 3651 316574 2279 0 0 0 0 472562 3651 0 0 0 0
49 wlan0 0x0 10127 1 6172960 4936 415951 5215 6172960 4936 0 0 0 0 415951 5215 0 0 0 0
50 wlan0 0x3792d5b400000000 10127 0 29678 208 32168 296 29678 208 0 0 0 0 32168 296 0 0 0 0
51 wlan0 0x3792d5b400000000 10127 1 226170 222 25745 265 226170 222 0 0 0 0 25745 265 0 0 0 0
56 wlan0 0xfa1dcc4b00000000 10127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
57 wlan0 0xfa1dcc4b00000000 10127 1 3014885 2127 139857 2117 3014885 2127 0 0 0 0 139857 2117 0 0 0 0

其中第 6 和 8 列为 rx_bytes(接收数据)和 tx_bytes(传输数据)包含 tcp,udp 等所有网络流量传输的统计。
[具体参考 url:​http://stackoverflow.com/questions/12904809/tracking-an-applications-network-statistics-netstats-using-adb]


添加了代码,论坛的兄弟姐妹们可以帮忙参考一下可行性如何

def get_networkTraffic(self):
    """基于UID获取App的网络流量的方法
       从/proc/net/xt_qtaguid/stats获取网络流量统计,进行判断,不存在使用之前的方法。
    """

    flag_net = self.adb.shell('{0} cat /proc/net/xt_qtaguid/stats'.format(BUSYBOX_PATH),timeout=TIMEOUT)
    # print flag_net
    if "No such file or directory" not in flag_net:
        list_rx = [] # 接收网络数据流量列表
        list_tx = [] # 发送网络数据流量列表
        str_uid_net_stats = self.adb.shell('{0} cat /proc/net/xt_qtaguid/stats|{0} grep {1}'.format(BUSYBOX_PATH,self.strUID),timeout=ADB_TIMEOUT)
        # print str_uid_net_stats
        try:
            for item in str_uid_net_stats.splitlines():
                rx_bytes = item.split()[5] # 接收网络数据流量
                tx_bytes = item.split()[7] # 发送网络数据流量
                list_rx.append(int(rx_bytes))
                list_tx.append(int(tx_bytes))
            # print list_rx, sum(list_rx)
            floatTotalNetTraffic = (sum(list_rx) + sum(list_tx))/1024.0/1024.0
            floatTotalNetTraffic = round(floatTotalNetTraffic,4)
            return floatTotalNetTraffic
        except:
            print "[ERROR]: cannot get the /proc/net/xt_qtaguid/stats, return 0.0"
            return 0.0

    else:
        strTotalTxBytes = self.adb.shell('{0} cat /proc/uid_stat/{1}/tcp_snd'.format(BUSYBOX_PATH,self.strUID),timeout=TIMEOUT)
        strTotalRxBytes = self.adb.shell('{0} cat /proc/uid_stat/{1}/tcp_rcv'.format(BUSYBOX_PATH,self.strUID),timeout=TIMEOUT)
        try:
            floatTotalTraffic = (int(strTotalTxBytes) + int(strTotalRxBytes))/1024.0/1024.0
            floatTotalTraffic = round(floatTotalTraffic,4)
            return floatTotalTraffic
        except:
            return 0.0  
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 43 条回复 时间 点赞

要 root 么?= =

#1 楼 @monkey 不要的,用 busybox 里统一提供的命令,只要能 push 到可用路径下/data/local/tmp/busybox
现在就是有点怀疑,这样做准确不,不知道有没有兄弟这样搞过,我看以前都是从/proc/uid_stat/{1}/tcp_rcv 路径下

#2 楼 @oscar 我以前开放过我调用 android 原生 api 来拿 rx 和 tx 的,不知道数据是不是一样。。。。

其实不用吧 没 root 可以统计到那 2 个路径的

dabao #10 · 2015年02月27日 Author

#4 楼 @kasi 嗯 不用 root,统一用的 busybox,怕有的系统裁剪的太厉害。

其实不然 我个人觉得 这个地方一般系统是不会改的 这个地方大家都是统一用 google 的 除了某些厂商会大调整才修改

另外最好的统计是用 tcpdump 的模式 加 wireshark

基本误差没有了 对于精益求精的人来说

dabao #13 · 2015年02月27日 Author

#7 楼 @kasi 嗯。有空研究一下

#7 楼 @kasi 但这个的话,不是很好做自动化,而且数据量比较大,看数据的精细度了

#2 楼 @oscar 类似于这种

for (String premission : premissions) {
    if ("android.permission.INTERNET".equals(premission)) {
        int uId = info.applicationInfo.uid;
        long rx = TrafficStats.getUidRxBytes(uId);
        long tx = TrafficStats.getUidTxBytes(uId);
        if (rx < 0 || tx < 0) {
            continue;
        } else {
            if (info.packageName.equals("com.alipay.m.portal")) {
                Log.e(info.packageName.toString()
                        + "trafficeTest", (rx + tx) / 1000
                        + "kb");
            }
        }

    }
}

说实话 就是转换的时候有点麻烦 需要算法进行优化一下,我在 hatt 中实现了

我实现的是短时间的计算 长时间的由于算法太菜搞不定

dabao #14 · 2015年02月27日 Author

#10 楼 @monkey 没必要这么精细,目前能做到基本的统计,和历史版本对比一下性能指标就可以。

厉害, 大赞. 进步神速啊. 从今以后我要对你另眼相看了.

rx tx 的流量性能统计,app 上也要做么?貌似只有我们做硬件测试才做啊。而且也是用 ixChariot 或者 iperf 做的。

需要验证的 尤其是网络交互严重的应用

dabao #18 · 2015年03月01日 Author

#16 楼 @lihuazhang 需要的,比如有有些 app 如锁屏软件,休眠后回进行联网请求,长时间的休眠待机如何耗费太多流量肯定不行,所以需要做一些监控测试。

学习了

撸主,iface 和 cnt_set 列都是啥知道么

如: adb shell cat /proc/net/xt_qtaguid/stats | grep 10127

48 wlan0 0x0 10127 0 316574 2279 472562 3651 316574 2279 0 0 0 0 472562 3651 0 0 0 0
49 wlan0 0x0 10127 1 6172960 4936 415951 5215 6172960 4936 0 0 0 0 415951 5215 0 0 0 0

lz,请教下,我根据 UID 筛选出来都是两行,如上,这两行有什么区别?
另,这个统计时累计流量还是实时当前流量?

dabao #23 · 2015年03月11日 Author

#22 楼 @xxx 一个 uid 可能对应多个 进程,所以有几行,就求和几行。流量是累加的,你设置时间点进行减法计算。

dabao #24 · 2015年03月11日 Author

#22 楼 @xxx 就是你的产品运行的过程中产生一个 uid,但是进程可能有多个,都在耗流量和 cpu、内存等,你性能测试都要求和的。

dabao #25 · 2015年03月11日 Author

#21 楼 @aite 各列的意义 你自己看吧 O(∩_∩) O~

-----各列的意义----

idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets

谢谢 oscar
刚看到回复
昨天查了下和您说的一致,非常感谢!

self.adb.shell 这个是啥语法啊啊? python 调用 cmd 中的 adb shell 命令就是这么写的吗?
求教

#27 楼 @wangfuwen000 这是语法么。。。作者自己封装的 adb 工具类或者方法。

dabao #29 · 2015年03月22日 Author

#27 楼 @wangfuwen000 整个统计功能写了一个 Python 类,用了 adbpy 的功能,所以写类你知道的,内部调用就是用了 self 的,具体命令 你可以忽略 self

adb shell cat /proc/net/xt_qtaguid/stats | grep (uid#)
这里的 uid 是什么?

刚看到、不错、进步神速、学习了。

API TrafficStats 类统计流量也是通过读取这个文件的

dabao #33 · 2015年08月21日 Author

#31 楼 @sgq1117 哈哈 好久的帖子了,以为你不在论坛呢

请问下这个文件是不是没有清零状态的,当前的流量是要跟上次的流量相减的吧?

匿名 #38 · 2016年06月03日

#23 楼 @oscar 你意思说,一个应用里面就算有多个进程启动,他们是同一个 uid 吗?

dabao #36 · 2016年06月27日 Author

#34 楼 @luweicheng2009 对,记录一个场景的当前状态,之后测试一段时间后,两个时间段求差值

dabao #37 · 2016年06月27日 Author

#35 楼 @lrw3716740 是的,

匿名 #38 · 2016年07月07日

如: adb shell cat /proc/net/xt_qtaguid/stats | grep 10127

48 wlan0 0x0 10127 0 316574 2279 472562 3651 316574 2279 0 0 0 0 472562 3651 0 0 0 0
49 wlan0 0x0 10127 1 6172960 4936 415951 5215 6172960 4936 0 0 0 0 415951 5215 0 0 0 0
50 wlan0 0x3792d5b400000000 10127 0 29678 208 32168 296 29678 208 0 0 0 0 32168 296 0 0 0 0
51 wlan0 0x3792d5b400000000 10127 1 226170 222 25745 265 226170 222 0 0 0 0 25745 265 0 0 0 0
56 wlan0 0xfa1dcc4b00000000 10127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
57 wlan0 0xfa1dcc4b00000000 10127 1 3014885 2127 139857 2117 3014885 2127 0 0 0 0 139857 2117 0 0 0 0

这个是得当前时刻应用消耗网络数据总和吗?还有会实时变化吗?就是比如当前时(比如是时刻 A)刻是这个数据,又操作下被测应用,再运行(时刻 B)这个命令,我看了下数据会变化,根据这个数据能算出应用在时刻 A 到 B 所消耗的流量吗?如果能的话,具体是哪些项怎么加减呢?非常感谢大神。

假设手机上已有 busybox,则可以通过如下命令直接获取(将 #uid# 替换成 uid 值):
adb shell cat /proc/net/xt_qtaguid/stats|grep #uid#|busybox awk '{rx_bytes+=$6}END{print rx_bytes}'
adb shell cat /proc/net/xt_qtaguid/stats|grep #uid#|busybox awk '{tx_bytes+=$8}END{print tx_bytes}'

dabao #40 · 2016年11月18日 Author

#38 楼 @lrw3716740 数据肯定会变化,但是是持续累加的

dabao 关闭了讨论 11月28日 17:16
dabao 重新开启了讨论 11月30日 11:18
Monkey 回复

busybox 需要 root 才行

终于可以发言了:提几个建议点;1.首先根据 UID 筛选出的内容 有本地流量、网络流量、移动流量;本地流量不能算在整体的流量统计中的;所以数据筛选时需要判断一下流量类型,数据能更准确;第二 就是有时一个应用可能会启多个进程;比如 push 也有可能会产生流量 所以需要再根据 UID 筛选出的具体数据 判断是否需要相加

dabao #46 · 2019年05月18日 Author

说得很对,第二个建议,具体实现的时候发现了这个问题了, 已经相加处理了;第一个你说包含本地流量,统计进去也可以吧,主要是一个消耗指标。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册