现在的很多应用默认情况下就带了很多的日志输出, 比如下面的 java spring-boot 框架启动时的日志:
{spring.web.resources.chain.cache=false, spring.web.resources.cache.period=0}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.0)
2020-11-28 10:54:18.418 INFO 16144 --- [ restartedMain] n.x.sample.boot.basicweb.AppApplication : Starting AppApplication using Java 11.0.8 on DESKTOP-CGD1N1Q with PID 16144 (C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web\target\classes started by xiaog in C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web)
2020-11-28 10:54:18.423 INFO 16144 --- [ restartedMain] n.x.sample.boot.basicweb.AppApplication : No active profile set, falling back to default profiles: default
2020-11-28 10:54:18.453 INFO 16144 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2020-11-28 10:54:18.453 INFO 16144 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2020-11-28 10:54:19.024 INFO 16144 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-11-28 10:54:19.031 INFO 16144 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-11-28 10:54:19.032 INFO 16144 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.39]
2020-11-28 10:54:19.096 INFO 16144 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-11-28 10:54:19.098 INFO 16144 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 644 ms
2020-11-28 10:54:19.208 INFO 16144 --- [ restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-11-28 10:54:19.254 INFO 16144 --- [ restartedMain] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html]
2020-11-28 10:54:19.314 INFO 16144 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2020-11-28 10:54:19.337 INFO 16144 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-11-28 10:54:19.346 INFO 16144 --- [ restartedMain] n.x.sample.boot.basicweb.AppApplication : Started AppApplication in 1.216 seconds (JVM running for 1.887)
日志信息非常丰富当然是有助于我们理解应用运行的各个方面, 但经常地, 我们也不难发现一些不方便的地方, 比如就以上述的输出为例, 前面一大堆的 布局(layout) 相关的输出就极为冗长, 而真正关心的信息却被挤在了后面, 如果你的显示屏不够宽, 这些关键的信息常常反而看不到, 需要横向滚动, 非常繁琐.
下面将介绍一种极简的日志布局方案, 如下所示:
{spring.web.resources.chain.cache=false, spring.web.resources.cache.period=0}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.0)
49:20 Starting AppApplication using Java 11.0.8 on DESKTOP-CGD1N1Q with PID 11800 (C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web\target\classes started by xiaog in C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web)
49:20 No active profile set, falling back to default profiles: default
49:20 Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
49:20 For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
49:20 Tomcat initialized with port(s): 8080 (http)
49:21 Starting service [Tomcat]
49:21 Starting Servlet engine: [Apache Tomcat/9.0.39]
49:21 Initializing Spring embedded WebApplicationContext
49:21 Root WebApplicationContext: initialization completed in 636 ms
49:21 Initializing ExecutorService 'applicationTaskExecutor'
49:21 Adding welcome page: class path resource [static/index.html]
49:21 LiveReload server is running on port 35729
49:21 Tomcat started on port(s): 8080 (http) with context path ''
49:21 Started AppApplication in 1.219 seconds (JVM running for 1.945)
可以看到, 仅仅输出了一个时间(分别是分钟数和秒数, 小时, 毫秒什么的都省略了), 然后就是关键的日志信息, 非常简洁, 一目了然, 基本不需要各种拓宽或横向拖动来显示.
下面说说怎么配置以达到上述效果.
先分析下缺省布局的情况, 看看哪些是没有必要可以省略的信息.
当没有任何配置的情况下, 使用的是一个缺省的布局, 这个通常来说是面向生产级别的一个布局配置, 以下面的一条信息为例:
2020-11-28 10:54:18.418 INFO 16144 --- [ restartedMain] n.x.sample.boot.basicweb.AppApplication : Starting AppApplication using Java 11.0.8 on DESKTOP-CGD1N1Q with PID 16144 (C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web\target\classes started by xiaog in C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web)
日志非常长, 先是一个很长的 时间, 年月日时分秒以及毫秒, 可是对于开发阶段来说, 年月日基本没用, 绝大部分情况就是当天, 难不成还跨天调试不成? 这种情况肯定是很少的.
甚至来说, 小时都是不必要的, 毫秒如果不是需要特别精确的情况, 通常也是没啥用的, 所以光是时间方面就可以大幅地简化其输出, 而不会对我们开发阶段查看日志造成多大影响.
其次, INFO
这块属于 日志级别, 其它的还有诸如 ERROR
, WARN
之类的等等, 通常这个级别区不区分关系也不大, 因此也可以省略.
接下来的一个数字 16144, 这是个 进程 ID(PID), 这个作用也不大, 反正至少对于我来说, 我几乎从未怎么关注过这个信息.
接下来的 [ restartedMain] 这个是 线程名称, 这个几乎在多数情况下也用处不大, 通常也可以省略.
如果你调试多线程情况就另说, 或许可以起到一些帮助.
接下来的 n.x.sample.boot.basicweb.AppApplication
是 类名 及 简化的包名, 虽然包名已经是简化的, 但无奈现在很多框架包括我们自己的工程, 包的层次都是蛮多的, 所以即便是简化的, 也通常也还蛮长的, 加上类名, 整个长度通常也还是非常可观.
这些信息怎么说呢, 看你自己的需要, 你也许不需要这些类和包名, 也许需要, 有时候, 必须承认它们还是有点用的, 至少可以让我们知道, 日志是在哪里打印出来的. 所以是否保留这个信息就看你自己的决定了.
后面除了极简的配置外, 还将给出一个适中的配置, 可以作为参考.
在以上的信息输出完之后, 才是我们最关心的日志信息了, 而这个最关键的信息常常被挤到看不到, 则是由于前面的布局相关的信息实在是太长了.
为输出前上述极简的布局, 可以在你的项目的开发环境的配置文件比如 application-dev.properties
中这样去配置:
logging.pattern.console=%date{mm:ss} %message%n
注意: 请配置在开发环境中, 在测试及生产环境就不建议这样去配置了. 关于 spring-boot 的 分环境配置 的
profile
机制, 如不熟悉请自行查阅网络了解.
在以上配置中, %date
表示时间, {mm:ss}
表示仅输出 分钟 和 秒; %message
这个是关键的日志信息; 最后的 %n
是换行.
在上述配置下, 就能输出开头那种极简的风格了:
49:20 Starting AppApplication using Java 11.0.8 on DESKTOP-CGD1N1Q with PID 11800 (C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web\target\classes started by xiaog in C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web)
一个简单的时间, 然后就是日志信息, 没有其它太多的不实用的信息.
当然有些人可能觉得上述配置也太简陋了, 那么下面是一个较为适中一点的配置:
logging.pattern.console=%date{HH:mm:ss} %logger{0}.%method - %message%n
上述配置中, 加上了小时数, 这样看上去更加符合我们的习惯; 另外, 类名(%logger{0}) 也同样输出了, 但忽略了包名; 还有一个改进是增加输出了 方法名(%method), 这样能更清楚知道日志是哪里打印出来的, 缺省的情况是没有输出这个的.
最终的输出效果如下:
{spring.web.resources.chain.cache=false, spring.web.resources.cache.period=0}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.0)
12:13:12 AppApplication.logStarting - Starting AppApplication using Java 11.0.8 on DESKTOP-CGD1N1Q with PID 20788 (C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web\target\classes started by xiaog in C:\dev\proj\my\code-sample\be\java\fw\spring-boot\basic-web)
12:13:12 AppApplication.logStartupProfileInfo - No active profile set, falling back to default profiles: default
12:13:12 DevToolsPropertyDefaultsPostProcessor.logTo - Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
12:13:12 DevToolsPropertyDefaultsPostProcessor.logTo - For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
12:13:13 TomcatWebServer.initialize - Tomcat initialized with port(s): 8080 (http)
12:13:13 StandardService.log - Starting service [Tomcat]
12:13:13 StandardEngine.log - Starting Servlet engine: [Apache Tomcat/9.0.39]
12:13:13 [/].log - Initializing Spring embedded WebApplicationContext
12:13:13 ServletWebServerApplicationContext.prepareWebApplicationContext - Root WebApplicationContext: initialization completed in 653 ms
12:13:13 ThreadPoolTaskExecutor.initialize - Initializing ExecutorService 'applicationTaskExecutor'
12:13:13 WelcomePageHandlerMapping. - Adding welcome page: class path resource [static/index.html]
12:13:13 OptionalLiveReloadServer.startServer - LiveReload server is running on port 35729
12:13:13 TomcatWebServer.start - Tomcat started on port(s): 8080 (http) with context path ''
12:13:13 AppApplication.logStarted - Started AppApplication in 1.248 seconds (JVM running for 1.921)
以上输出比缺省要简洁, 但比起极简风格又多了一些输出, 具体的取舍就看你自己的需要了.
最后, 如果你需要更加详细更多的配置, 请参考: https://logback.qos.ch/manual/layouts.html, 里面有完整的配置项介绍.
注: spring-boot 默认使用的日志框架是 logback, 所以上面给的是 logback 的参考, 如果你使用的是其它日志框架, 请参考相应的框架说明.
当然, 很多日志框架的配置是大同小异的.
你可以多配置几种风格, 一次启用一种, 然后试试自己适合喜欢哪种风格; 同时, 保留的其它几种风格可以在你有需要时进行切换.
关于配置简化开发阶段日志输出布局的介绍就到这里.