上一篇文章讲到了测试线排查的一些经验,上篇文章如:《「测试线排查的一些经验-上篇」&& 后端工程师》,本文主要是讲解一些实战中常用的命令或者一些故障排除方法。
全局搜索文件
其实这个命令有点鸡肋,但还是要介绍一下,比较常用。
find / -name tomcat
该命令是帮助我们直接查询tomcat这个文件在哪个路径下。
查看某端口占用的服务
其实这个信息在上一篇文章讲过,但是这里要做一些补充。
我们可以查看某个端口被哪个服务占用了,比如我们看8089这个端口的占用情况:
netstat -anp | grep 8099
在这一步我们只是查询出占用这个端口的服务进程号,接下来查询该进程号是哪个服务:
ps -ef | grep 11585
查看服务执行日志
我们的jar包放在服务器上启动以后,启动日志通常会放在一个单独的日志文件里,我们可以通过动态查看日志文件来看服务启动情况。
如果说jar包执行久了,这个日志文件的信息就会很多,比如像下面这样:
我们怎么看最新的执行信息呢,我们可以指定行数去查看执行情况。
tail -fn 10 log.txt
当日志 log.txt
在服务器上执行的时候,我们通过上面的命令可以动态查看指定的最下面的10行输出日志信息,尽管这个时候服务还在启动,控制台还在打印信息,但是这个信息是动态更新到我们面前了,前提是你用了上面这个命令。
其实上面这个方法特别适用于当我们通过日志进行线上故障的排查!
调试日志框架JUL
对于一个程序员来说,当你接触到日志框架,说明你有经常在线上测试调试程序的需要,而非像以前那样在线下测试程序时到处 System.out
。当你的程序上到线上的时候,所有的System.out
都会被去掉,这个时候使用日志会更方便一些,你就不用到处删System.out
,这也是日志存在的必要。
日志类型
我们谈到的日志主要分为:
- 调试日志
- 系统日志
日志框架
目前已知的日志框架如下:
- JUL 【自带原生、常用】
- logback
- log4j
- log4j2 【性能最好、常用】
JUL
JUL的全称是 java util Logging
,属于java原生的日志框架,使用时不需要引入第三方类库,属于学习成本最低的一种框架,能够在小型应用中灵活使用。
case one
Logger其实是一个静态方法,直接调用即可。
其中 Level.INFO
是日志级别,这里日志级别有七类,分别是:
public class JULTest { public static void main(String[] args) { /** 获取日志记录器 */ Logger logger= Logger.getLogger("JULTest"); /** 记录日志 */ logger.info("hi logger"); /** 记录日志 如上等价 枚举类型 */ logger.log((Level.INFO),"hi logger"); String name="linghu"; Integer age=25; /** 通过占位符输出变量值 */ logger.log(Level.INFO,"用户信息:{0},年龄:{1}",new Object[]{name,age}); logger.severe("严重错误"); logger.warning("警告信息"); logger.info("提示信息"); logger.fine("调试信息"); logger.finer("调试信息"); logger.finest("调试信息"); } }
八月 13, 2024 5:01:55 下午 com.linghu.api.JULTest main 信息: hi logger 八月 13, 2024 5:01:55 下午 com.linghu.api.JULTest main 信息: hi logger 八月 13, 2024 5:01:55 下午 com.linghu.api.JULTest main 信息: 用户信息:linghu,年龄:25 八月 13, 2024 5:01:55 下午 com.linghu.api.JULTest main 严重: 严重错误 八月 13, 2024 5:01:55 下午 com.linghu.api.JULTest main 警告: 警告信息 八月 13, 2024 5:01:55 下午 com.linghu.api.JULTest main 信息: 提示信息
可以关闭logger的对象记录器:
logger.setUseParentHandlers(false);
日志配置文件
日志配置文件使用的较多,比较灵活,这个配置文件其实就在JRE里的,不过我在这里拷贝出来做了精简:
handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler .level= ALL ## 文件处理器 # 输出日志级别 java.util.logging.FileHandler.level=ALL # 输出日志文件路径 java.util.logging.FileHandler.pattern = ./logs/java%u.log # 输出日志文件限制大小(50000字节) java.util.logging.FileHandler.limit = 50000 # 输出日志文件限制个数 java.util.logging.FileHandler.count = 1 # 输出日志格式 java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter ## 控制台处理器 # 输出日志级别 #java.util.logging.ConsoleHandler.level = OFF java.util.logging.ConsoleHandler.level = ALL # 输出日志格式 java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
有了这个配置文件,接下来我们就在代码中加入日志的实战:
public class JULTest { public static void main(String[] args) throws IOException { InputStream resourceAsStream = JULTest.class.getClassLoader().getResourceAsStream("logging.properties"); Logger logger = Logger.getLogger("JULTest"); LogManager manager = LogManager.getLogManager(); manager.readConfiguration(resourceAsStream); logger.severe("severe"); logger.warning("warning"); logger.info("info"); logger.config("config"); logger.fine("fine"); logger.finer("finer"); logger.finest("finest"); } }
我们在代码中动态加载了日志配置文件,这样做的好处是,在测试线调试的时候我们可以全局处理,比如全局关闭日志的记录,这样就有一首歌清清爽爽的控制台啦~
在上面配置中,需要注意:
# 输出日志级别 #java.util.logging.ConsoleHandler.level = OFF java.util.logging.ConsoleHandler.level = ALL
OFF
表示全局关闭日志处理记录; ALL
表示全局打开日志处理记录。
日志文件最好做一个备份处理,这样方便我们在测试线进行调试,排查:
# 输出日志文件路径 java.util.logging.FileHandler.pattern = ./logs/java%u.log
这个路径代表了一个相对路径,也就是我们当前项目的根目录的logs文件夹下:
我们可以将日志做几个保留,也就是相当于历史记录备份,这个备份的数量可以自己定义,定义如下:
# 输出日志文件限制个数 java.util.logging.FileHandler.count = 5
其实对于日志文件的使用我觉得差不多就是这样了。感谢大家提出好的意见。