6.824/6.5840 的Debugging by Pretty Printing配置

news2024/9/21 2:48:29

TA的原文在:Debugging by Pretty Printing (josejg.com)

为了在WSL2中配置好打印运行日志,我可是忙活了一下午。可恶的log配置

首先是安装rich库Textualize/rich: Rich is a Python library for rich text and beautiful formatting in the terminal. (github.com)

python -m pip install rich

然后我发现我的pip命令报错了

$ python -m pip install rich
/usr/bin/python: No module named pip

尝试了多种方法依然失败,最后采用的方法是如下

先更新自己的系统安装包

sudo apt-get update
sudo apt-get upgrade

然后重新安装一遍pip

sudo apt install python3-pip

如果你没有遇到pip的问题,成功安装好了rich库,进行下一步

1. 准备好python3解释器

2.打开终端,输入which python3 复制解释器地址

3.在你需要执行的python文件最上方加上 #! python解释器地址

#!/usr/bin python3

 其实这么写可能会有问题,我就碰到了如下问题

-bash: /usr/bin/dtest: /usr/bin: bad interpreter: Permission denied

如果你也碰到了类似的问题,把上述语句改为

#!/usr/bin/env python3

4.修改当前需要执行的文件的权限 chmod +x xxx.py

例如

chmod +x dtest.py
chmod +x dslog.py

这句命令的意思是为xxx.py这个文件添加可执行权限

执行完上述命令后我们可以查看一下是否成功修改权限

5.复制当前文件到python解释器的bin/文件目录下

我的Python解释器目录在/usr/bin,目录的后缀/xxx是把xxx.py文件复制到这个文件夹中并且改名为xxx。我这里就是把dtest.py复制到了/usr/bin后改名为dtest

sudo cp dtest.py /usr/bin/dtest
sudo cp dslog.py /usr/bin/dslog

6.终端直接输入你的python文件名就可以看到运行结果了

如果你的WSL2没有安装过Python的库,一般还会报错

手动安装typer这个库就行

7.最后运行结果如下

dslog.py文件如下

#!/usr/bin/env python3
import sys
import shutil
from typing import Optional, List, Tuple, Dict

import typer
from rich import print
from rich.columns import Columns
from rich.console import Console
from rich.traceback import install

# fmt: off
# Mapping from topics to colors
TOPICS = {
    "TIMR": "#9a9a99",
    "VOTE": "#67a0b2",
    "LEAD": "#d0b343",
    "TERM": "#70c43f",
    "LOG1": "#4878bc",
    "LOG2": "#398280",
    "CMIT": "#98719f",
    "PERS": "#d08341",
    "SNAP": "#FD971F",
    "DROP": "#ff615c",
    "CLNT": "#00813c",
    "TEST": "#fe2c79",
    "INFO": "#ffffff",
    "WARN": "#d08341",
    "ERRO": "#fe2626",
    "TRCE": "#fe2626",
}
# fmt: on


def list_topics(value: Optional[str]):
    if value is None:
        return value
    topics = value.split(",")
    for topic in topics:
        if topic not in TOPICS:
            raise typer.BadParameter(f"topic {topic} not recognized")
    return topics


def main(
    file: typer.FileText = typer.Argument(None, help="File to read, stdin otherwise"),
    colorize: bool = typer.Option(True, "--no-color"),
    n_columns: Optional[int] = typer.Option(None, "--columns", "-c"),
    ignore: Optional[str] = typer.Option(None, "--ignore", "-i", callback=list_topics),
    just: Optional[str] = typer.Option(None, "--just", "-j", callback=list_topics),
):
    topics = list(TOPICS)

    # We can take input from a stdin (pipes) or from a file
    input_ = file if file else sys.stdin
    # Print just some topics or exclude some topics (good for avoiding verbose ones)
    if just:
        topics = just
    if ignore:
        topics = [lvl for lvl in topics if lvl not in set(ignore)]

    topics = set(topics)
    console = Console()
    width = console.size.width

    panic = False
    for line in input_:
        try:
            time, topic, *msg = line.strip().split(" ")
            # To ignore some topics
            if topic not in topics:
                continue

            msg = " ".join(msg)

            # Debug calls from the test suite aren't associated with
            # any particular peer. Otherwise we can treat second column
            # as peer id
            if topic != "TEST":
                i = int(msg[1])

            # Colorize output by using rich syntax when needed
            if colorize and topic in TOPICS:
                color = TOPICS[topic]
                msg = f"[{color}]{msg}[/{color}]"

            # Single column printing. Always the case for debug stmts in tests
            if n_columns is None or topic == "TEST":
                print(time, msg)
            # Multi column printing, timing is dropped to maximize horizontal
            # space. Heavylifting is done through rich.column.Columns object
            else:
                cols = ["" for _ in range(n_columns)]
                msg = "" + msg
                cols[i] = msg
                col_width = int(width / n_columns)
                cols = Columns(cols, width=col_width - 1, equal=True, expand=True)
                print(cols)
        except:
            # Code from tests or panics does not follow format
            # so we print it as is
            if line.startswith("panic"):
                panic = True
            # Output from tests is usually important so add a
            # horizontal line with hashes to make it more obvious
            if not panic:
                print("#" * console.width)
            print(line, end="")


if __name__ == "__main__":
    typer.run(main)

dtest.py内容如下

#!/usr/bin/env python3

import itertools
import math
import signal
import subprocess
import tempfile
import shutil
import time
import os
import sys
import datetime
from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor, wait, FIRST_COMPLETED
from dataclasses import dataclass
from pathlib import Path
from typing import List, Optional, Dict, DefaultDict, Tuple

import typer
import rich
from rich import print
from rich.table import Table
from rich.progress import (
    Progress,
    TimeElapsedColumn,
    TimeRemainingColumn,
    TextColumn,
    BarColumn,
    SpinnerColumn,
)
from rich.live import Live
from rich.panel import Panel
from rich.traceback import install

install(show_locals=True)


@dataclass
class StatsMeter:
    """
    Auxiliary classs to keep track of online stats including: count, mean, variance
    Uses Welford's algorithm to compute sample mean and sample variance incrementally.
    https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm
    """

    n: int = 0
    mean: float = 0.0
    S: float = 0.0

    def add(self, datum):
        self.n += 1
        delta = datum - self.mean
        # Mk = Mk-1+ (xk – Mk-1)/k
        self.mean += delta / self.n
        # Sk = Sk-1 + (xk – Mk-1)*(xk – Mk).
        self.S += delta * (datum - self.mean)

    @property
    def variance(self):
        return self.S / self.n

    @property
    def std(self):
        return math.sqrt(self.variance)


def print_results(results: Dict[str, Dict[str, StatsMeter]], timing=False):
    table = Table(show_header=True, header_style="bold")
    table.add_column("Test")
    table.add_column("Failed", justify="right")
    table.add_column("Total", justify="right")
    if not timing:
        table.add_column("Time", justify="right")
    else:
        table.add_column("Real Time", justify="right")
        table.add_column("User Time", justify="right")
        table.add_column("System Time", justify="right")

    for test, stats in results.items():
        if stats["completed"].n == 0:
            continue
        color = "green" if stats["failed"].n == 0 else "red"
        row = [
            f"[{color}]{test}[/{color}]",
            str(stats["failed"].n),
            str(stats["completed"].n),
        ]
        if not timing:
            row.append(f"{stats['time'].mean:.2f} ± {stats['time'].std:.2f}")
        else:
            row.extend(
                [
                    f"{stats['real_time'].mean:.2f} ± {stats['real_time'].std:.2f}",
                    f"{stats['user_time'].mean:.2f} ± {stats['user_time'].std:.2f}",
                    f"{stats['system_time'].mean:.2f} ± {stats['system_time'].std:.2f}",
                ]
            )
        table.add_row(*row)

    print(table)


def run_test(test: str, race: bool, timing: bool):
    test_cmd = ["go", "test", f"-run={test}"]
    if race:
        test_cmd.append("-race")
    if timing:
        test_cmd = ["time"] + cmd
    f, path = tempfile.mkstemp()
    start = time.time()
    proc = subprocess.run(test_cmd, stdout=f, stderr=f)
    runtime = time.time() - start
    os.close(f)
    return test, path, proc.returncode, runtime


def last_line(file: str) -> str:
    with open(file, "rb") as f:
        f.seek(-2, os.SEEK_END)
        while f.read(1) != b"\n":
            f.seek(-2, os.SEEK_CUR)
        line = f.readline().decode()
    return line


# fmt: off
def run_tests(
    tests: List[str],
    sequential: bool       = typer.Option(False,  '--sequential',      '-s',    help='Run all test of each group in order'),
    workers: int           = typer.Option(1,      '--workers',         '-p',    help='Number of parallel tasks'),
    iterations: int        = typer.Option(10,     '--iter',            '-n',    help='Number of iterations to run'),
    output: Optional[Path] = typer.Option(None,   '--output',          '-o',    help='Output path to use'),
    verbose: int           = typer.Option(0,      '--verbose',         '-v',    help='Verbosity level', count=True),
    archive: bool          = typer.Option(False,  '--archive',         '-a',    help='Save all logs intead of only failed ones'),
    race: bool             = typer.Option(False,  '--race/--no-race',  '-r/-R', help='Run with race checker'),
    loop: bool             = typer.Option(False,  '--loop',            '-l',    help='Run continuously'),
    growth: int            = typer.Option(10,     '--growth',          '-g',    help='Growth ratio of iterations when using --loop'),
    timing: bool           = typer.Option(False,   '--timing',          '-t',    help='Report timing, only works on macOS'),
    # fmt: on
):

    if output is None:
        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        output = Path(timestamp)

    if race:
        print("[yellow]Running with the race detector\n[/yellow]")

    if verbose > 0:
        print(f"[yellow] Verbosity level set to {verbose}[/yellow]")
        os.environ['VERBOSE'] = str(verbose)

    while True:

        total = iterations * len(tests)
        completed = 0

        results = {test: defaultdict(StatsMeter) for test in tests}

        if sequential:
            test_instances = itertools.chain.from_iterable(itertools.repeat(test, iterations) for test in tests)
        else:
            test_instances = itertools.chain.from_iterable(itertools.repeat(tests, iterations))
        test_instances = iter(test_instances)

        total_progress = Progress(
            "[progress.description]{task.description}",
            BarColumn(),
            TimeRemainingColumn(),
            "[progress.percentage]{task.percentage:>3.0f}%",
            TimeElapsedColumn(),
        )
        total_task = total_progress.add_task("[yellow]Tests[/yellow]", total=total)

        task_progress = Progress(
            "[progress.description]{task.description}",
            SpinnerColumn(),
            BarColumn(),
            "{task.completed}/{task.total}",
        )
        tasks = {test: task_progress.add_task(test, total=iterations) for test in tests}

        progress_table = Table.grid()
        progress_table.add_row(total_progress)
        progress_table.add_row(Panel.fit(task_progress))

        with Live(progress_table, transient=True) as live:

            def handler(_, frame):
                live.stop()
                print('\n')
                print_results(results)
                sys.exit(1)

            signal.signal(signal.SIGINT, handler)

            with ThreadPoolExecutor(max_workers=workers) as executor:

                futures = []
                while completed < total:
                    n = len(futures)
                    if n < workers:
                        for test in itertools.islice(test_instances, workers-n):
                            futures.append(executor.submit(run_test, test, race, timing))

                    done, not_done = wait(futures, return_when=FIRST_COMPLETED)

                    for future in done:
                        test, path, rc, runtime = future.result()

                        results[test]['completed'].add(1)
                        results[test]['time'].add(runtime)
                        task_progress.update(tasks[test], advance=1)
                        dest = (output / f"{test}_{completed}.log").as_posix()
                        if rc != 0:
                            print(f"Failed test {test} - {dest}")
                            task_progress.update(tasks[test], description=f"[red]{test}[/red]")
                            results[test]['failed'].add(1)
                        else:
                            if results[test]['completed'].n == iterations and results[test]['failed'].n == 0:
                                task_progress.update(tasks[test], description=f"[green]{test}[/green]")

                        if rc != 0 or archive:
                            output.mkdir(exist_ok=True, parents=True)
                            shutil.copy(path, dest)
 
                        if timing:
                            line = last_line(path)
                            real, _, user, _, system, _ = line.replace(' '*8, '').split(' ')
                            results[test]['real_time'].add(float(real))
                            results[test]['user_time'].add(float(user))
                            results[test]['system_time'].add(float(system))

                        os.remove(path)

                        completed += 1
                        total_progress.update(total_task, advance=1)

                        futures = list(not_done)

        print_results(results, timing)

        if loop:
            iterations *= growth
            print(f"[yellow]Increasing iterations to {iterations}[/yellow]")
        else:
            break


if __name__ == "__main__":
    typer.run(run_tests)

By the way,dtest的运行方式如下

dtest --help #查看运行参数

dtest -n 10(运行一百遍) -p 5(五个并发的运行测试加快运行速率) -s(顺序执行) 
-v(将Debug打印到log) 3A(测试点名称)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1911609.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android布局简介

布局是一种可用于放置很多控件的容器&#xff0c;根据既定的规则决定内部控件的位置。当然&#xff0c;布局的内部也可以放置布局&#xff0c;即布局嵌套&#xff0c;布局嵌套可以实现一些比较复杂的界面。 Android中有多种编写程序界面的方式可供选择。Android Studio提供了相…

Android应用程序调试Logcat的使用

Android的程序调试主要使用Logcat进行&#xff0c;本节主要介绍Logcat的使用。 开启调试模式 使用Android Studio进行程序调试&#xff0c;首先需要连接虚拟Android设备或真实Android设备&#xff0c;设备上需要启用调试功能。 虚拟Android设备默认情况下会启用调试功能。对…

超详细!Jmeter 压测-设计5W并发量场景

需求&#xff1a;设计一个5W并发量的性能场景&#xff1f; 1、确定性能测试工具&#xff0c;性能测试思路 测试工具&#xff1a;Jmeter 并发设计思路&#xff1a;如果被测服务足够快&#xff0c;比如10ms的响应时间&#xff0c;1个线程/秒就是100tps&#xff0c;5万的TPS&…

Redis代替Session实现共享

集群的session共享问题 session共享问题&#xff1a;多台tomcat并不共享session存储空间&#xff0c;当请求切换到不同的tomcat服务时导致数据丢失的问题。 session的替代方案&#xff1a; 数据共享内存存储key、value结构 将redis替换session可以解决session共享问题

AI发展的新方向:从卷模型到卷应用

在2024年7月4日于上海世博中心举办的世界人工智能大会暨人工智能全球治理高级别会议全体会议上&#xff0c;百度创始人、董事长兼首席执行官李彦宏发表了一段引人深思的演讲。他在产业发展主论坛上提出&#xff1a;“大家不要卷模型&#xff0c;要卷应用&#xff01;”这句话道…

打卡第7天-----哈希表

继续坚持✊,我现在看到leetcode上的题不再没有思路了,真的是思路决定出路,在做题之前一定要把思路梳理清楚。 一、四数相加 leetcode题目编号:第454题.四数相加II 题目描述: 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j…

设计模式使用简例(简单工厂+策略模式+模板方法)

直接上代码&#xff0c;方便记忆。主要的要点&#xff0c;已经写到注释中。 一&#xff0c;代码展示 启动类 package com.rojer;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootAppli…

【电路笔记】-C类放大器

C类放大器 文章目录 C类放大器1、概述2、C类放大介绍3、C类放大器的功能4、C 类放大器的效率5、C类放大器的应用:倍频器6、总结1、概述 尽管存在差异,但我们在之前有关 A 类、B 类和 AB 类放大器的文章中已经看到,这三类放大器是线性或部分线性的,因为它们在放大过程中再现…

离线运行Llama3:本地部署终极指南_liama2 本地部署

4月18日&#xff0c;Meta在官方博客官宣了Llama3&#xff0c;标志着人工智能领域迈向了一个重要的飞跃。经过笔者的个人体验&#xff0c;Llama3 8B效果已经超越GPT-3.5&#xff0c;最为重要的是&#xff0c;Llama3是开源的&#xff0c;我们可以自己部署&#xff01; 本文和大家…

大话光学原理:3.干涉与衍射

一、干涉 这是一束孤独的光&#xff0c;在真空的无垠中悄无声息地穿行。忽然&#xff0c;一堵高耸的墙壁挡住了它的去路&#xff0c;它别无选择&#xff0c;只能硬着头皮冲撞而去。在摸索中&#xff0c;它意外地发现墙壁上竟有两道孔隙&#xff0c;笔直而细长&#xff0c;宛如量…

tableau树形图制作 - 7

树形图制作 1. 树状图绘制-11.1 选择属性1.2 智能选择树状图1.3 颜色设置 2. 树状图绘制-22.1 标签属性选择2.2 树状图绘制2.3 颜色设置2.4 设置标签2.5 设置筛选器 3. 树状图绘制 - 33.1 选择行列3.2 树状图转换3.3 统计转换3.4 颜色设置3.5 标签设置3.6 筛选器设置 1. 树状图…

【系统架构设计】计算机组成与体系结构(二)

计算机组成与体系结构 计算机系统组成存储器系统前言主存储器存储器存储数量&#xff08;计算&#xff09; 辅助存储器&#xff08;以磁盘为例&#xff09;Cache存储器 流水线 计算机系统组成 存储器系统 前言 存储器用来存放程序和数据的部件&#xff0c;是一个记忆装置&am…

Michael.W基于Foundry精读Openzeppelin第63期——Initializable.sol

Michael.W基于Foundry精读Openzeppelin第63期——Initializable.sol 0. 版本0.1 Initializable.sol 1. 目标合约2. 代码精读2.1 _getInitializedVersion() internal && _isInitializing() internal2.2 modifier initializer()2.3 modifier reinitializer(uint8 version…

Qt 异步实现事件的定时执行 - QTimer和QThread的联合使用

异步实现事件的定时执行 - QTimer和QThread的联合使用 引言一、核心源码二、其信号和槽函数简述三、定时器及其moveToThread简述 引言 在 Qt 中&#xff0c;如果想要定时执行某些事件或函数&#xff0c;通常会使用 QTimer 类。QTimer 允许设置一个时间间隔&#xff0c;当这个时…

聚星文社一键生成工具绘唐3科技AI工具

聚星文社一键生成工具绘唐3科技AI工具 绘唐3.0——用户文档 - 飞书云文档 聚星文社一键生成工具绘唐3科技AI工具是一个基于人工智能技术的辅助创作工具&#xff0c;可以帮助用户快速生成有关唐朝科技的文本内容。该工具利用自然语言处理和机器学习等技术&#xff0c;通过输入一…

opencv读取视频文件夹内视频的名字_时长_帧率_分辨率写入excel-cnblog

看视频的时候有的视频文件名贼长。想要翻看&#xff0c;在文件夹里根本显示不出来&#xff0c;缩短又会丢失一些信息&#xff0c;所以我写了一份Python代码&#xff0c;直接获取视频的名字&#xff0c;时长&#xff0c;帧率&#xff0c;还有分辨率写到excel里。 实际效果如下图…

Cesium自定义着色器构件三角面片【闪烁】问题,但是一移动视角就闪烁

问题&#xff1a;已知各个顶点的坐标信息、颜色和索引信息&#xff0c;并自定义绘制三角面片。 但是绘制的三角面片随着视角稍微改动就会出现闪烁现象&#xff01;&#xff01;&#xff01;why? Cesium数据类型的精度问题&#xff0c;例如下面为了获取能接收到高精度坐标信息…

linux磁盘分区管理

首先关机状态下&#xff0c;先配置硬盘 硬盘分区管理 识别硬盘 》分区规划 》 格式化 》 挂载使用 [rootlocalhost ~]# lsblk 查看硬盘 分区划分&#xff08;m帮助, p 查看分区, n 创建分区, d 删除分区, q 退出, w 保存&#xff0c; g gpt分区&#xff09; [roo…

华为云发起,openGemini正式成为CNCF官方项目!

openGemini 正式成为 CNCF 官方项目 北京时间2024年7月9日&#xff0c;云原生计算基金会&#xff08;CNCF&#xff09;正式接纳云原生高性能时序数据库项目 openGemini。openGemini的加入&#xff0c;极大地丰富了云原生数据库技术的探索、创新和发展。 openGemini是华为云数据…

打开excel时弹出stdole32.tlb

问题描述 打开excel时弹出stdole32.tlb 如下图&#xff1a; 解决方法 打开 Microsoft Excel 并收到关于 stdole32.tlb 的错误提示时&#xff0c;通常意味着与 Excel 相关的某个组件或类型库可能已损坏或不兼容。 stdole32.tlb 是一个用于存储自动化对象定义的类型库&#x…