• 《自拍教程40》Python adb一键导出Log


    Android设备,比如车载系统实车路试过程中,
    车上操作电脑比较麻烦,如果车载系统出现了Bug,
    如何很方便地一次性导出相关的log来(logcat, dbus, 高德地图log,gps定位log等)来呢?
    其实我们只需要一个python脚本就可以搞定!


    准备阶段
    1. adb pull 命令, 可以把Android系统里的文件,pull到电脑端
    2. 导出的Log,需要在当前路径新建一个文件夹用于存放,最好以时间戳命名
    3. os.system()可以调用adb命令

    Android车载系统默认的Log存储路径
    Android Log类型 默认路径
    logcat序列log /data/logs/logcat.txt
    /data/logs/logcat.txt.1

    /data/logs/logcat.txt.20
    dbus序列log /data/logs/dbus.txt
    /data/logs/dbus.txt.1

    /data/logs/dbus.txt.20
    kernel序列log /data/logs/kernel.txt
    /data/logs/kernel.txt.1
    ...
    /data/logs/kernel.txt.20
    tombstone log /data/tombstones/*
    anr卡死log /data/anr/*
    dropbox log /data/system/dropbox/*
    gps log /sdcard/map/gps/*
    高德地图log /sdcard/amapauto8/logs/*

    自动生成的序列Log

    何为自动生成的序列log,一般系统启动过程中,
    就默认开启了某种类型的log,且序列化存储,新的会自动冲刷掉旧的log。


    比如logcat序列log,
    一般是全部写到logcat.txt,写满5M后,
    将logcat.txt重命名为logcat.txt.1,以此类推。。。
    所以logcat.txt就始终是最新的log,
    然后就是logcat.txt.1,
    再然后是logcat.txt.2,
    .....
    最后是到序列logcat.txt.20


    当然以上取决于init.rc里的关于logcat自启动命令的设置,
    比如init.rc配置文件,如果设置如下:

    /system/bin/logcat -b system -b events -b main
    -b radio -n 20 -r5000 -v threadtime -f /data/logs/logcat.txt

    以上启动命令则表示:截取所有包括system,events,main,radio四种缓冲区的logcat 日志,
    并设置自动序列为20个序列片段,-r5000 代表是5M一个,
    -v threadtime是打印线程级别的时间戳,
    -f 是输出到什么路径,logcat.txt是初始和默认的句柄文件。


    其他的dbus.txt序列log, kernel序列log也是一致的。
    如以下截图所示:


    Python批处理脚本模式
    # coding=utf-8
    
    import os
    from datetime import datetime
    
    # 先新建一个带时间戳的文件夹用于存放导出来的Log
    now_time = datetime.now().strftime("%Y%m%d_%H%M%S")
    log_folder = "Logs_" + now_time
    os.mkdir(log_folder)  # 因为没指定具体路径,默认就是在当前路径下创建。
    
    # 先导出所有序列log
    os.system("adb pull /data/logs/logcat.txt %s" % log_folder)
    os.system("adb pull /data/logs/dbus.txt %s" % log_folder)
    os.system("adb pull /data/logs/kernel.txt %s" % log_folder)
    for i in range(1, 21):
        os.system("adb pull /data/logs/logcat.txt.%s %s" % (i, log_folder))
        os.system("adb pull /data/logs/dbus.txt.%s %s" % (i, log_folder))
        os.system("adb pull /data/logs/kernel.txt.%s %s" % (i, log_folder))
    
    # 再导出其他log
    os.system("adb pull /data/tombstones %s" % log_folder)
    os.system("adb pull /data/anr %s" % log_folder)
    os.system("adb pull /data/system/dropbox %s" % log_folder)
    os.system("adb pull /sdcard/map/gps %s" % log_folder)
    os.system("adb pull /sdcard/amapauto8/logs %s" % log_folder)
    
    # 打印存放地址的绝对路径。
    print("所有实车log均已经导出,存放地址:%s" % os.path.abspath(log_folder))
    
    os.system("pause")
    

    Python面向过程函数形式

    我们可以再细分为5个函数,
    其中1个函数是创建带时间戳的文件夹的,
    其中1个函数是导出logcat.txt序列log的,
    其中1个函数是导出dbus.txt序列log的,
    其中1个函数是导出kernel.txt序列log的,
    最后1个函数是导出所有包含其他log的函数。

    # coding=utf-8
    
    import os
    from datetime import datetime
    
    # 先新建一个带时间戳的文件夹用于存放导出来的Log
    def creat_floder():
        now_time = datetime.now().strftime("%Y%m%d_%H%M%S")
        log_folder = "Logs_" + now_time
        os.mkdir(log_folder)  # 因为没指定具体路径,默认就是在当前路径下创建。
        return os.path.abspath(log_folder)  # 返回绝对路径
    
    # 导出logcat序列log
    def pull_logcat_logs(save_path):
        os.system("adb pull /data/logs/logcat.txt %s" % save_path)
        for i in range(1, 21):
            os.system("adb pull /data/logs/logcat.txt.%s %s" % (i, save_path))
    
    # 导出dbus序列log
    def pull_dbus_logs(save_path):
        os.system("adb pull /data/logs/dbus.txt %s" % save_path)
        for i in range(1, 21):
            os.system("adb pull /data/logs/dbus.txt.%s %s" % (i, save_path))
    
    # 导出kernel序列log
    def pull_kernel_logs(save_path):
        os.system("adb pull /data/logs/kernel.txt %s" % save_path)
        for i in range(1, 21):
            os.system("adb pull /data/logs/kernel.txt.%s %s" % (i, save_path))
    
    def pull_all_logs(save_path):
        pull_logcat_logs(save_path)  # 函数调用
        pull_dbus_logs(save_path)    # 函数调用
        pull_kernel_logs(save_path)  # 函数调用
        os.system("adb pull /data/tombstones %s" % save_path)
        os.system("adb pull /data/anr %s" % save_path)
        os.system("adb pull /data/system/dropbox %s" % save_path)
        os.system("adb pull /sdcard/map/gps %s" % save_path)
        os.system("adb pull /sdcard/amapauto8/logs %s" % save_path)
        # 打印存放地址的绝对路径。
        print("所有实车log均已经导出,存放地址:%s" % save_path)
    
    log_path = creat_floder()
    pull_all_logs(log_path)
    os.system("pause")
    

    以上,实现了函数的返回值, 并传参,及函数内嵌调用。

    Python面向对象类的形式
    1. 以"万物皆可归类"的思想, 先抽象化出一个类来,
      类名一般建议用"名词", 所以我们命名为"LogPuller",
      代表Log导出器, 且一般要驼峰式(首字母大写)来规范类的命名。
    2. 养成良好的类的初始化(__init__)的习惯,
      初始化过程中, 可以传入导出的路径。
    3. 这个LogPuller类, 建议是再细化各类型Log的导出函数。
    4. 类是一个抽象的事物, 必须实例化成具体的对象后,
      才能进行调用, 所以我们实例化并命名成了l_obj, 表明是一个对象。
    5. 实例化成具体对象后, 对象就可以调用pull_all_logs这个函数了
    # coding=utf-8
    
    import os
    from datetime import datetime
    
    
    # 先新建一个带时间戳的文件夹用于存放导出来的Log
    # 这个作为一个公用函数,不放到类里,单独以函数的形式存在
    def creat_floder():
        now_time = datetime.now().strftime("%Y%m%d_%H%M%S")
        log_folder = "Logs_" + now_time
        os.mkdir(log_folder)  # 因为没指定具体路径,默认就是在当前路径下创建。
        return os.path.abspath(log_folder)
    
    
    # 导出所有实车日志
    class LogPuller():
        def __init__(self, save_path):
            self.save_path = save_path
    
        # 导出logcat序列log
        def pull_logcat_logs(self):
            os.system("adb pull /data/logs/logcat.txt %s" % self.save_path)
            for i in range(1, 21):
                os.system("adb pull /data/logs/logcat.txt.%s %s" % (i, self.save_path))
    
        # 导出dbus序列log
        def pull_dbus_logs(self):
            os.system("adb pull /data/logs/dbus.txt %s" % self.save_path)
            for i in range(1, 21):
                os.system("adb pull /data/logs/dbus.txt.%s %s" % (i, self.save_path))
    
        # 导出kernel序列log
        def pull_kernel_logs(self):
            os.system("adb pull /data/logs/kernel.txt %s" % self.save_path)
            for i in range(1, 21):
                os.system("adb pull /data/logs/kernel.txt.%s %s" % (i, self.save_path))
    
        def pull_tombstones_logs(self):
            os.system("adb pull /data/tombstones %s" % self.save_path)
    
        def pull_anr_logs(self):
            os.system("adb pull /data/anr %s" % self.save_path)
    
        def pull_dropbox_logs(self):
            os.system("adb pull /data/system/dropbox %s" % self.save_path)
    
        def pull_gps_logs(self):
            os.system("adb pull /sdcard/map/gps %s" % self.save_path)
    
        def pull_amapauto_logs(self):
            os.system("adb pull /sdcard/amapauto8/logs %s" % self.save_path)
    
        def pull_all_logs(self):
            self.pull_logcat_logs()
            self.pull_dbus_logs()
            self.pull_kernel_logs()
            self.pull_tombstones_logs()
            self.pull_anr_logs()
            self.pull_dropbox_logs()
            self.pull_gps_logs()
            self.pull_amapauto_logs()
            # 打印存放地址的绝对路径。
            print("所有实车log均已经导出,存放地址:%s" % self.save_path)
    
    # 更科学的文件内运行方式
    if __name__ == '__main__':
        log_path = creat_floder()
        l_obj = LogPuller(log_path)
        l_obj.pull_all_logs()
        os.system("pause")
    

    代码运行方式

    确保Android车机设备通过USB线与电脑连接了,adb设备有效连接,
    以上代码的3种实现形式都可以直接运行,比如保存为pull_logs.py并放在桌面,
    每次需要截图的时候,双击运行pull_logs.py,
    就会在当前文件夹下生成一个类似:Logs_20200308_101503的文件夹。

    更多更好的原创文章,请访问官方网站:www.zipython.com
    自拍教程(自动化测试Python教程,武散人编著)
    原文链接:https://www.zipython.com/#/detail?id=884c9f1c4f2e4a159457d7993d723aec
    也可关注“武散人”微信订阅号,随时接受文章推送。

  • 相关阅读:
    帧锁定同步算法
    为 Raft 引入 leader lease 机制解决集群脑裂时的 stale read 问题
    etcd:从应用场景到实现原理的全方位解读
    给定一个二叉搜索树(BST),找到树中第 K 小的节点
    UDP如何实现可靠传输
    理解TCP/IP三次握手与四次挥手的正确姿势
    Redis持久化
    Redis提供的持久化机制(RDB和AOF)
    redis渐进式 rehash
    redis rehash
  • 原文地址:https://www.cnblogs.com/zipython/p/12461479.html
Copyright © 2020-2023  润新知