👏 Hi! 我是 Yumuing,一个技术的敲钟人
👨💻 每天分享技术文章,永远做技术的朝拜者
📚 欢迎关注我的博客:Yumuing's blog
所有代码均有相关介绍。本文将阐述 springboot 下应该如何进行从日志打印、保存、管理等等的日志技巧,到常用编辑器 IDEA 断点生成、操作、管理等等的后端调试技巧,最后到谷歌浏览器的相关的前端调试技巧,基本能够满足项目基本的调试需要,里面的相关代码文件都可以作为模板使用,只需要修改部分参数即可适用。
日志错误信息:logback
注:使用的是 slf4j 进行日志管理,log.file 已被弃用,使用 yml 进行配置较为简单,但不能满足很多需求,所以采用 xml 的文件进行配置,所有代码均有相关介绍。
application.yml:level 跟的是包名,用来指定某个包下的日志显示级别
# Logger 配置:slf4j
logging:
level.top.yumuing.community: info
file:
name: logs/community.log
其中, logging.file 在 2.2 中已弃用,并在 2.3 中完全删除,因此不能再在 2.3+ 中使用,得使用logging.file.name,logs/community.log 表示项目根目录下的 logs/ 创建community.log 来保存日志文件
测试方法:
package top.yumuing.community;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class LoggerTest {
private static final Logger logger = LoggerFactory.getLogger(LoggerTest.class);
@Test
public void testLogger(){
System.out.println(logger.getName());
logger.info("info");
logger.warn("warn");
logger.error("error");
}
}
使用 xml 进行详细日志文件配置。
先在 application.yml 配置启动 xml 文件:
logging:
config: classpath:logback-spring.xml
logback-spring.xml:注意修改路径、包名、文件大小即可,按需修改,无需记忆。
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
:设置 logback 规则名称,以便后续启用该规则<property name="LOG_PATH" value="data"/>
:主日志文件目录位置为项目根目录下 date/logs/*.log<property name="APPDIR" value="logs"/>
:logs 可自行设置为程序名,统一管理所有程序日志文件,也可保持不变,保存在 LOG_PATH 下的 logs 目录<file>${LOG_PATH}/${APPDIR}/log_error.log</file>
:可自行选择注释还是保留,如果保留,则存入 log_error.log 直至文件限制,才会重新生成日志文件,否则为<fileNamePattern>
的格式<fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
:按文件名 log-error-生成日期.第几个.log 命名<maxFileSize>5MB</maxFileSize>
:文件一旦超过 5mb 即重新创建次序加一的文件,再次写入<maxHistory>30</maxHistory>
:日志文件保存时间<append>true</append>
:以追加的形式写入文件,而不是覆盖形式<pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
:日志内容文本写入格式,日期 级别 [线程 日志所处的类 哪个文件代码第几行] 详细日志信息<charset>utf-8</charset>
:写入格式<level>error</level>
:把以上规则应用到哪个日志的级别<onMatch>ACCEPT</onMatch>
:匹配则写入日志<onMismatch>DENY</onMismatch>
:不匹配则拒绝写入- console 部分是把日志打印到控制台
<logger name="top.yumuing.community" level="debug"/>
:限制日志显示打印级别,top.yumuing.community 包下级别为 debug<root level="info">
:项目根目录下的包默认日志显示级别为 info,有设置包级别以设置为主,否则默认<appender-ref ref="FILE_ERROR"/>
:启用 FILE_ERROR 规则
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<contextName>community</contextName>
<property name="LOG_PATH" value="data"/>
<property name="APPDIR" value="logs"/>
<!-- error file -->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${APPDIR}/log_error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- warn file -->
<appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${APPDIR}/log_warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- info file -->
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${APPDIR}/log_info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- console -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
</appender>
<logger name="top.yumuing.community" level="debug"/>
<root level="info">
<appender-ref ref="FILE_ERROR"/>
<appender-ref ref="FILE_WARN"/>
<appender-ref ref="FILE_INFO"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>
HTTP 常用状态码解释
状态码 | 使用场景 | 示例 |
---|---|---|
302:重定向 | 在访问完一个接口后,返回 302 及建议请求其他接口的地址,避免产生过多依赖耦合 | 访问完删除接口后,返回 302,查询接口地址,使得浏览器会在访问完 302 后去访问查询接口,以得到删除后的数据列表,而不是在删除方法中调用查询方法,导致过多依赖耦合,即修改完其中一个方法,就得考虑调用它的方法是否还适用 |
404:资源访问错误 | 浏览器未访问到所需资源,可能是由地址输入错误或者服务器路径相关代码错误导致的 | 默认错误页面的错误码,访问功能不存在,往往是路径书写错误 |
500:服务器接收到请求却处理错误 | 浏览器正确将请求发送到服务器。但服务器处理时间过长,或者处理错误 | 访问服务器性能不足(可能性较小),接口无法处理该请求(可能性较大)。修改服务端程序。 |
IDEA 项目断点调试
可以在你想要调试的地址左侧,单击鼠标打好断点,如下
再选择运行模式为 Debug 模式,快捷键 Shift + F9,正常运行模式是不会停止在断点代码处
从断点行开始执行代码的常见按钮及快捷键
按钮顺序 | 功能描述 | 快捷键 |
---|---|---|
01 | 执行当前行下一条代码 | F8 |
02 | 执行当前行所调用的方法内部的下一条代码 | F7 |
07 | 执行到下一个断点处:如果某个循环一步步执行太麻烦,可以选择设你想要跳转的断点处,打好断点,按绿色按钮跳转到断点处。如果后续代码没有断点,直接执行结束 | F9 |
调试时,会在需要参数处,以灰色字体显示对应值或该集合长度
在此处,显示参数完整信息
断点管理位置:第四个按钮:红色双圆点
打开界面如下:
客户端、浏览器调试
此处为前端代码,调试的常常为 js 文件。浏览器按 F12,调出调试界面
选择为 source 功能栏,再选择对应 js 文件,单击左侧,产生蓝色箭头即可。
开始运行调用代码,显示为这个,即为打断点成功。
快捷键:
F10:向下执行一行
F11:进入到某个方法内部执行代码
F8:执行到下一个断点处或执行到底
Breakpoints:管理断点处
此处查看参数值
如果没有想要查看的参数值,可选中想要查看的元素位置,右键选中此图最后一个:Add selected text to watchs
此处查看选中的对应值