init.c中打印Log

首先,该文件中使用的打印log的宏有 ERROR() INFO() NOTICE(),在系统里对这几个log宏做了限制,如下

#define ERROR(x...) log_write(3, "<3>init: " x)  
#define NOTICE(x...) log_write(5, "<5>init: " x)  
#define INFO(x...) log_write(6, "<6>init: " x)  
#define LOG_DEFAULT_LEVEL 3 /* messages <= this level are logged */  

LOG_DEFAULT_LEVEL 是3,比3小的才会被输出到Logcat里,所以在这里文件里跟踪log时,用ERROR肯定可以打印出来了...

接下来使用 adb shell dmesg > kernel_log.log即可打印到kernel的log里~该命令是高通平台的kernel log命令,其他平台请问厂商~

<think>我们正在讨论的是在Python GUI应用(特别是Tkinter)的Frame容器中显示日志信息。 通常,我们可以使用一个Text组件或者一个ScrolledText组件(带滚动条)来显示日志。 另外,我们也可以使用Listbox,但Text组件更灵活,可以显示多行文本且支持格式化。 步骤: 1. 在Frame中创建一个Text组件(或ScrolledText)作为日志显示区域。 2. 设置该组件的状态为禁用(DISABLED),以防止用户直接编辑。 3. 当需要添加日志时,临时将状态改为NORMAL,插入日志内容,再改回DISABLED。 4. 为了自动滚动到最底部,可以在插入后滚动到END位置。 另外,我们还可以重定向标准输出(stdout)和标准错误(stderr)到该Text组件,这样print语句输出的内容也会显示在GUI上。 下面是一个示例,展示如何在Tkinter的Frame中创建一个日志显示区域,并重定向stdout。 注意:由于Text组件支持直接打印,我们需要自定义一个类来接管stdout。 我们将创建一个名为RedirectText的类,它可以将写入字符串流的内容重定向到Text组件。 同时,我们也要考虑多线程安全,但在这个简单示例中,我们假设日志写入都在主线程(GUI线程)中。 完整代码示例:</think># Python GUI中Frame容器内显示日志信息的方法 在Python GUI应用中,特别是在Tkinter框架中,在Frame容器内显示日志信息是常见的需求。以下是完整的解决方案: ## 核心方法:使用Text组件显示日志 ```python import tkinter as tk from tkinter import scrolledtext import logging import sys class LogFrame(tk.Frame): def __init__(self, parent, *args, **kwargs): super().__init__(parent, *args, **kwargs) # 创建带滚动条的文本区域 self.text_area = scrolledtext.ScrolledText( self, wrap=tk.WORD, width=60, height=15, state=tk.DISABLED # 初始状态为禁用,防止用户编辑 ) self.text_area.pack(padx=10, pady=10, fill=tk.BOTH, expand=True) # 创建自定义日志处理器 self.log_handler = TextHandler(self.text_area) # 配置日志系统 self.setup_logging() def setup_logging(self): """配置日志系统""" logger = logging.getLogger() logger.setLevel(logging.DEBUG) # 设置日志级别 # 添加自定义处理器 self.log_handler.setFormatter(logging.Formatter( '%(asctime)s - %(levelname)s - %(message)s' )) logger.addHandler(self.log_handler) # 重定向标准输出和错误输出 sys.stdout = StdoutRedirector(self.text_area) sys.stderr = StderrRedirector(self.text_area) def write_log(self, message, level=logging.INFO): """手动写入日志""" logger = logging.getLogger() if level == logging.DEBUG: logger.debug(message) elif level == logging.WARNING: logger.warning(message) elif level == logging.ERROR: logger.error(message) elif level == logging.CRITICAL: logger.critical(message) else: logger.info(message) class TextHandler(logging.Handler): """自定义日志处理器,将日志输出到Text组件""" def __init__(self, text_widget): super().__init__() self.text_widget = text_widget def emit(self, record): """处理日志记录""" msg = self.format(record) # 启用文本区域以插入内容 self.text_widget.configure(state=tk.NORMAL) # 插入日志并添加换行 self.text_widget.insert(tk.END, msg + "\n") # 自动滚动到底部 self.text_widget.see(tk.END) # 禁用文本区域以防止用户编辑 self.text_widget.configure(state=tk.DISABLED) class StdoutRedirector: """重定向标准输出到Text组件""" def __init__(self, text_widget): self.text_widget = text_widget def write(self, message): self.text_widget.configure(state=tk.NORMAL) self.text_widget.insert(tk.END, message) self.text_widget.see(tk.END) self.text_widget.configure(state=tk.DISABLED) def flush(self): pass # 需要实现flush方法,但无需操作 class StderrRedirector(StdoutRedirector): """重定向标准错误输出到Text组件(可设置同颜色)""" def write(self, message): self.text_widget.configure(state=tk.NORMAL) # 添加错误标签以设置同颜色 self.text_widget.insert(tk.END, message, "error") self.text_widget.see(tk.END) self.text_widget.configure(state=tk.DISABLED) # 主应用示例 class App(tk.Tk): def __init__(self): super().__init__() self.title("日志显示示例") self.geometry("800x600") # 创建顶部按钮区域 button_frame = tk.Frame(self) button_frame.pack(pady=10) # 创建日志框架 self.log_frame = LogFrame(self) self.log_frame.pack(padx=10, pady=10, fill=tk.BOTH, expand=True) # 添加测试按钮 tk.Button(button_frame, text="测试信息", command=self.test_info).pack(side=tk.LEFT, padx=5) tk.Button(button_frame, text="测试警告", command=self.test_warning).pack(side=tk.LEFT, padx=5) tk.Button(button_frame, text="测试错误", command=self.test_error).pack(side=tk.LEFT, padx=5) tk.Button(button_frame, text="清除日志", command=self.clear_logs).pack(side=tk.LEFT, padx=5) def test_info(self): """测试信息级别日志""" self.log_frame.write_log("这是一条普通信息日志") print("这是通过print输出的信息") def test_warning(self): """测试警告级别日志""" self.log_frame.write_log("这是一条警告信息", logging.WARNING) print("警告: 这是通过print输出的警告信息") def test_error(self): """测试错误级别日志""" self.log_frame.write_log("这是一条错误信息", logging.ERROR) # 模拟错误输出 sys.stderr.write("错误: 这是通过stderr输出的错误信息\n") def clear_logs(self): """清除日志""" text_area = self.log_frame.text_area text_area.configure(state=tk.NORMAL) text_area.delete(1.0, tk.END) text_area.configure(state=tk.DISABLED) if __name__ == "__main__": app = App() app.mainloop() ``` ## 关键实现说明 ### 1. 日志显示框架 - **`LogFrame`类**:继承自`tk.Frame`,包含日志显示区域 - **`scrolledtext.ScrolledText`**:带滚动条的文本区域,适合显示大量日志 - **状态控制**:使用`state=tk.DISABLED`防止用户编辑,仅在写入时临时启用 ### 2. 日志处理机制 - **`TextHandler`类**:继承自`logging.Handler`,将日志定向到Text组件 - **日志格式化**:使用`logging.Formatter`定义日志格式(时间戳、级别、消息) - **自动滚动**:`see(tk.END)`确保新日志始终可见 ### 3. 标准输出重定向 - **`StdoutRedirector`**:重定向`sys.stdout`到Text组件 - **`StderrRedirector`**:重定向`sys.stderr`到Text组件(可设置同颜色) - **`flush()`方法**:实现空方法以满足接口要求 ### 4. 日志级别处理 - **多级别支持**:DEBUG, INFO, WARNING, ERROR, CRITICAL - **手动写入**:`write_log()`方法支持按级别写入日志 - **自动捕获**:通过logging模块自动捕获程序日志 ## 高级功能扩展 ### 1. 添加颜色区分日志级别 ```python class TextHandler(logging.Handler): def __init__(self, text_widget): super().__init__() self.text_widget = text_widget # 配置同级别的颜色 self.colors = { logging.DEBUG: "gray", logging.INFO: "black", logging.WARNING: "orange", logging.ERROR: "red", logging.CRITICAL: "darkred" } def emit(self, record): msg = self.format(record) self.text_widget.configure(state=tk.NORMAL) # 根据日志级别添加颜色标签 tag = f"level_{record.levelno}" self.text_widget.tag_config(tag, foreground=self.colors.get(record.levelno, "black")) self.text_widget.insert(tk.END, msg + "\n", tag) self.text_widget.see(tk.END) self.text_widget.configure(state=tk.DISABLED) ``` ### 2. 添加时间戳和日志搜索功能 ```python class LogFrame(tk.Frame): def __init__(self, parent, *args, **kwargs): # ...其他初始化代码... # 添加搜索框 search_frame = tk.Frame(self) search_frame.pack(fill=tk.X, padx=10, pady=(0, 5)) tk.Label(search_frame, text="搜索:").pack(side=tk.LEFT) self.search_var = tk.StringVar() search_entry = tk.Entry(search_frame, textvariable=self.search_var, width=30) search_entry.pack(side=tk.LEFT, padx=5) search_entry.bind("<Return>", self.search_log) tk.Button(search_frame, text="搜索", command=self.search_log).pack(side=tk.LEFT) def search_log(self, event=None): """搜索日志内容""" query = self.search_var.get().lower() if not query: return self.text_area.configure(state=tk.NORMAL) self.text_area.tag_remove("highlight", "1.0", tk.END) # 搜索所有匹配项 start_index = "1.0" while True: start_index = self.text_area.search(query, start_index, stopindex=tk.END) if not start_index: break end_index = f"{start_index}+{len(query)}c" self.text_area.tag_add("highlight", start_index, end_index) start_index = end_index # 设置高亮样式 self.text_area.tag_config("highlight", background="yellow") self.text_area.configure(state=tk.DISABLED) ``` ### 3. 日志导出功能 ```python class LogFrame(tk.Frame): # ...其他代码... def export_logs(self, filename="application.log"): """导出日志到文件""" self.text_area.configure(state=tk.NORMAL) content = self.text_area.get("1.0", tk.END) self.text_area.configure(state=tk.DISABLED) try: with open(filename, "w", encoding="utf-8") as f: f.write(content) return True except Exception as e: logging.error(f"导出日志失败: {str(e)}") return False ``` ## 最佳实践建议 1. **线程安全处理**: - 在多线程应用中,使用`queue`模块安全更新GUI - 通过`after()`方法定期检查队列并更新日志显示 2. **性能优化**: - 对于高频日志,使用缓冲机制批量更新 - 限制日志行数,避免内存占用过大 3. **日志级别管理**: - 提供界面选项让用户动态调整日志级别 - 同环境设置同默认级别(开发环境DEBUG,生产环境WARNING) 4. **错误处理**: - 捕获并记录日志处理过程中的异常 - 提供日志导出功能,便于问题排查 这种方法可以轻松集成到任何Tkinter应用程序中,为Frame容器提供专业的日志显示功能,同时支持标准Python日志模块的所有特性[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值