logger.debug的用处

简单的说,就是配合log的等级过滤输出

根据你log4j的配置等级,logger记录日志分别对相应等级的内容进行输出,当然很有可能你的不同等级的日志记录地点或方式是不是一样的。
比如,你在开发的时候,要验证一个方法有没有被调用到,为了方便调试,通常会在这个方法开始的时候加一些system.out。
但是项目真正发布的时候这些代码通常是要移除掉的,所以通常更建议用logger来记录

所以你可能会加logger.debug。

为什么是debug而不是info error或者其他呢?
因为通常项目发布的时候都会把日志等级设置为error 或者info之类的等级,
在这两个等级下debug的内容是输出不了的,所以就可以做到不需要修改代码就不会输出你只有在调试的时候才需要输出的内容

各个等级都是有它的含义的,虽然在代码写的时候你用debug info error都是可以,
但是为了方便管理,只有调试的时候才用到日志会用debug,一些信息类的日志记录通常会用info(比如你想看一天有几个用户登录),
一些错误的,或者异常信息会用error,比如某个时刻数据库连接出了问题,如果分析日志,直接搜索error开头的就能直接定位到了

转载于:https://www.cnblogs.com/xiangkejin/p/6426761.html

import time import psutil import random import os import logging from logging.handlers import TimedRotatingFileHandler from pywinauto import Application from pywinauto.findwindows import ElementNotFoundError, find_elements from pywinauto.timings import TimeoutError, wait_until from pywinauto.base_wrapper import ElementNotEnabled def setup_logger(): log_dir = "output" if not os.path.exists(log_dir): os.makedirs(log_dir) logger = logging.getLogger("BarcodeAutomation") logger.setLevel(logging.INFO) log_file = os.path.join(log_dir, "barcode_auto_fill.log") file_handler = TimedRotatingFileHandler( filename=log_file, when="midnight", interval=1, backupCount=7, encoding="utf-8" ) file_handler.setFormatter(logging.Formatter( "%(asctime)s - %(levelname)s - %(message)s" )) console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter( "[%(asctime)s] %(message)s", datefmt="%H:%M:%S" )) logger.addHandler(file_handler) logger.addHandler(console_handler) return logger def generate_simulated_barcode(): prefix = "AUTO_" timestamp = int(time.time()) % 100000 random_part = random.randint(1000, 9999) return f"{prefix}{timestamp}{random_part}" def is_window_valid(handle): try: app = Application(backend="uia").connect(handle=handle) window = app.window(handle=handle) window.exists() return True except: return False def find_edit_boxes_by_labels(dialog, logger): """ 根据 '子板1' 和 '子板2' 的 Static 标签查找对应的 Edit 控件 """ try: # 查找两个 Static 标签 label1 = dialog.child_window(title="子板1", control_type="Text") label2 = dialog.child_window(title="子板2", control_type="Text") if not label1 or not label2: logger.warning("找不到标签控件,跳过填充") return None, None # 获取下一个兄弟控件(即 Edit 输入框) edit1 = label1.parent().children(control_type="Edit")[0] edit2 = label2.parent().children(control_type="Edit")[1] return edit1, edit2 except Exception as e: logger.debug(f"通过标签查找输入框失败: {str(e)}") return None, None def automate_barcode_window(): logger = setup_logger() TARGET_WINDOW_TITLE = "请扫描或输入条码" logger.info("条码自动填充服务已启动(结构定位模式)") logger.info(f"目标窗口标题: '{TARGET_WINDOW_TITLE}'") while True: try: # 性能检查 cpu_percent = psutil.cpu_percent(interval=0.1) mem_percent = psutil.virtual_memory().percent if cpu_percent > 80 or mem_percent > 70: time.sleep(1) continue # 查找窗口 windows = find_elements(visible_only=True) found_window = None for win in windows: if win.name == TARGET_WINDOW_TITLE: found_window = win break if not found_window: time.sleep(3) continue handle = found_window.handle # 连接窗口 app = Application(backend="uia").connect(handle=handle) dialog = app.window(handle=handle) # 使用标签定位两个输入框 edit1, edit2 = find_edit_boxes_by_labels(dialog, logger) if not edit1 or not edit2: logger.warning("无法定位输入框,跳过本次循环") time.sleep(3) continue # 查找确定按钮 confirm_btn = dialog.child_window(title="确定", control_type="Button") # 第一次检查输入框是否为空 val1 = edit1.get_value().strip() val2 = edit2.get_value().strip() if val1 or val2: logger.debug("检测到条码已录入,跳过填充") time.sleep(3) continue logger.info("检测到条码框为空,等待2秒后再次确认") time.sleep(2) # 再次检查窗口是否存在 if not is_window_valid(handle): logger.info("窗口已关闭,跳过填充") continue # 再次检查输入框是否为空 val1 = edit1.get_value().strip() val2 = edit2.get_value().strip() if val1 or val2: logger.debug("检测到条码已录入,跳过填充") continue # 开始填充 barcode1 = generate_simulated_barcode() barcode2 = generate_simulated_barcode() edit1.set_text(barcode1) edit2.set_text(barcode2) # 等待按钮可用 for _ in range(5): if confirm_btn.is_enabled(): break time.sleep(0.5) confirm_btn.click() logger.info(f"已自动填充条码: {barcode1}, {barcode2}") time.sleep(0.5) # 给窗口关闭一点时间 except (ElementNotFoundError, TimeoutError) as e: logger.debug(f"查找控件失败: {str(e)}") time.sleep(3) except ElementNotEnabled as e: logger.warning(f"控件不可操作: {str(e)}") time.sleep(1) except Exception as e: logger.error(f"发生异常: {str(e)}", exc_info=True) time.sleep(3) if __name__ == "__main__": automate_barcode_window()将本程序中的等待时间抽离成变量,便于在赋值
最新发布
07-31
package com.teacher.service.Impl; import com.teacher.model.dto.AnalysisResult; import com.teacher.model.entity.StudentAnswer; import com.teacher.repository.AnswerRepo; import com.teacher.service.AnalysisService; import com.teacher.util.QwenClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; @Service public class AnalysisServiceImpl implements AnalysisService { private static final Logger logger = LoggerFactory.getLogger(AnalysisServiceImpl.class); private final AnswerRepo answerRepo; private final QwenClient qwenClient; @Autowired public AnalysisServiceImpl(AnswerRepo answerRepo, QwenClient qwenClient) { this.answerRepo = answerRepo; this.qwenClient = qwenClient; } @Override public AnalysisResult analyzeTeachingEffectiveness(String courseId) { logger.debug("分析教学效果: courseId={}", courseId); // 构建提示词 String prompt = "分析课程ID为 " + courseId + " 的教学效果,包括学生掌握情况、常见问题等"; String analysis = qwenClient.generateText(prompt); logger.info("教学效果分析完成: courseId={}", courseId); return new AnalysisResult(courseId, analysis); } @Override public List<String> identifyCommonMistakes(String exerciseId) { logger.debug("识别常见错误: exerciseId={}", exerciseId); try { // 获取相关答题数据(添加类型转换) List<StudentAnswer> answers = answerRepo.findByExerciseId(Long.parseLong(exerciseId)); logger.debug("获取到答题记录: 数量={}", answers.size()); // 构建提示词 String prompt = "分析习题ID " + exerciseId + " 的常见错误类型,基于以下答题数据: " + answers; String response = qwenClient.generateText(prompt); // 解析响应 return List.of(response.split("\\n")); } catch (NumberFormatException e) { logger.error("习题ID格式错误: {}", exerciseId, e); return Collections.emptyList(); } } @Override public AnalysisResult predictStudentPerformance(Long studentId) { logger.debug("预测学生表现: studentId={}", studentId); // 获取学生历史数据(处理可能的null值) Double avgScore = answerRepo.calculateAverageScore(studentId); if (avgScore == null) avgScore = 0.0; // 处理没有答题记录的情况 List<StudentAnswer> recentAnswers = answerRepo.findTop5ByStudentIdOrderByCreatedAtDesc(studentId); // 构建提示词 String prompt = "预测学生ID " + studentId + " 的未来表现。当前平均分: " + avgScore + ",最近答题情况: " + recentAnswers; String prediction = qwenClient.generateText(prompt); logger.info("学生表现预测完成: studentId={}", studentId); return new AnalysisResult("student_" + studentId, prediction); } } 出现 return new AnalysisResult(courseId, analysis); 应为无实参,但实际为 2 return new AnalysisResult("student_" + studentId, prediction);应为无实参,但实际为 2 AnalysisResult的代码如下package com.teacher.model.dto; import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import java.util.Map; import java.util.Objects; /** * 学生答题分析结果DTO */ @Getter public class AnalysisResult { private static final Logger logger = LoggerFactory.getLogger(AnalysisResult.class); private String studentId; private String exerciseId; private double overallScore; private double accuracyRate; private Map<String, Double> knowledgePointMastery; private List<String> weakAreas; private String improvementSuggestions; public AnalysisResult() { logger.debug("创建分析结果DTO实例"); } public void setStudentId(String studentId) { logger.trace("设置学生ID: {}", studentId); this.studentId = studentId; } public void setExerciseId(String exerciseId) { logger.trace("设置习题ID: {}", exerciseId); this.exerciseId = exerciseId; } public void setOverallScore(double overallScore) { logger.trace("设置总分: {}", overallScore); this.overallScore = overallScore; } public void setAccuracyRate(double accuracyRate) { logger.trace("设置正确率: {}%", accuracyRate * 100); this.accuracyRate = accuracyRate; } public void setKnowledgePointMastery(Map<String, Double> knowledgePointMastery) { logger.trace("设置知识点掌握情况: 知识点数量={}", knowledgePointMastery.size()); this.knowledgePointMastery = knowledgePointMastery; } public void setWeakAreas(List<String> weakAreas) { logger.trace("设置薄弱环节: 数量={}", weakAreas.size()); this.weakAreas = weakAreas; } public void setImprovementSuggestions(String improvementSuggestions) { logger.trace("设置改进建议: 长度={}", improvementSuggestions.length()); this.improvementSuggestions = improvementSuggestions; } @Override public String toString() { return "AnalysisResult{" + "studentId='" + studentId + '\'' + ", exerciseId='" + exerciseId + '\'' + ", overallScore=" + overallScore + ", accuracyRate=" + accuracyRate + ", knowledgePointMastery=" + knowledgePointMastery + ", weakAreas=" + weakAreas + ", improvementSuggestions='" + improvementSuggestions + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AnalysisResult that = (AnalysisResult) o; return Double.compare(that.overallScore, overallScore) == 0 && Double.compare(that.accuracyRate, accuracyRate) == 0 && Objects.equals(studentId, that.studentId) && Objects.equals(exerciseId, that.exerciseId) && Objects.equals(knowledgePointMastery, that.knowledgePointMastery) && Objects.equals(weakAreas, that.weakAreas) && Objects.equals(improvementSuggestions, that.improvementSuggestions); } @Override public int hashCode() { return Objects.hash(studentId, exerciseId, overallScore, accuracyRate, knowledgePointMastery, weakAreas, improvementSuggestions); } /** * 添加知识点掌握情况 * @param point 知识点名称 * @param mastery 掌握程度(0-1) */ public void addKnowledgeMastery(String point, double mastery) { logger.trace("添加知识点掌握情况: {}={}", point, mastery); knowledgePointMastery.put(point, mastery); } }
07-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值