一.简介
log4j2相对于log4j 1.x有了脱胎换骨的变化,其官网宣称的优势有多线程下10几倍于log4j 1.x和logback的高吞吐量、可配置的审计型日志、基于插件架构的各种灵活配置等。如果已经掌握log4j 1.x,使用log4j2还是非常简单的。
二.maven依赖
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.8.2</version> </dependency>
三.基本信息
1.关于配置文件的名称以及在项目中的存放位置
log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn".
系统选择配置文件的优先级(从先到后)如下:
(1).classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件.
(2).classpath下的名为log4j2-test.xml的文件.
(3).classpath下名为log4j2.json 或者log4j2.jsn的文件.
(4).classpath下名为log4j2.xml的文件.
我们一般默认使用log4j2.xml进行命名。如果本地要测试,可以把log4j2-test.xml放到classpath,而正式环境使用log4j2.xml,则在打包部署的时候不要打包log4j2-test.xml即可。
2.缺省默认配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="WARN"> 3 <Appenders> 4 <Console name="Console" target="SYSTEM_OUT"> 5 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> 6 </Console> 7 </Appenders> 8 <Loggers> 9 <Root level="error"> 10 <AppenderRef ref="Console"/> 11 </Root> 12 </Loggers> 13 </Configuration>
3.配置文件节点解析
(1).根节点Configuration有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(表明可以定义多个Appender和Logger).
status用来指定log4j本身的打印日志的级别.
monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s.
(2).Appenders节点,常见的有三种子节点:Console、RollingFile、File.
Console节点用来定义输出到控制台的Appender.
name:指定Appender的名字.
target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.
PatternLayout:输出格式,不设置默认为:%m%n.
File节点用来定义输出到指定位置的文件的Appender.
name:指定Appender的名字.
fileName:指定输出日志的目的文件带全路径的文件名.
PatternLayout:输出格式,不设置默认为:%m%n.
RollingFile节点用来定义超过指定大小自动删除旧的创建新的的Appender.
name:指定Appender的名字.
fileName:指定输出日志的目的文件带全路径的文件名.
PatternLayout:输出格式,不设置默认为:%m%n.
filePattern:指定新建日志文件的名称格式.
Policies:指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.
TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am.
SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小.
DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。
(3).Loggers节点,常见的有两种:Root和Logger.
Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出
level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender.
Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。
level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.
AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都 会输出,此时我们可以设置Logger的additivity="false"只在自定义的Appender中进行输出。
(4).关于日志level.
共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
All:最低等级的,用于打开所有日志记录.
Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.
Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.
Info:消息在粗粒度级别上突出强调应用程序的运行过程.
Warn:输出警告及warn以下级别的日志.
Error:输出错误信息日志.
Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.
OFF:最高等级的,用于关闭所有日志记录.
程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少。
四.比较完整的log4j2.xml配置模板
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> 3 <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--> 4 <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> 5 <configuration status="WARN" monitorInterval="30"> 6 <!--先定义所有的appender--> 7 <appenders> 8 <!--这个输出控制台的配置--> 9 <console name="Console" target="SYSTEM_OUT"> 10 <!--输出日志的格式--> 11 <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> 12 </console> 13 <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用--> 14 <File name="log" fileName="log/test.log" append="false"> 15 <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> 16 </File> 17 <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> 18 <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log" 19 filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"> 20 <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> 21 <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> 22 <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> 23 <Policies> 24 <TimeBasedTriggeringPolicy/> 25 <SizeBasedTriggeringPolicy size="100 MB"/> 26 </Policies> 27 </RollingFile> 28 <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log" 29 filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"> 30 <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> 31 <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> 32 <Policies> 33 <TimeBasedTriggeringPolicy/> 34 <SizeBasedTriggeringPolicy size="100 MB"/> 35 </Policies> 36 <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --> 37 <DefaultRolloverStrategy max="20"/> 38 </RollingFile> 39 <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log" 40 filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"> 41 <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> 42 <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> 43 <Policies> 44 <TimeBasedTriggeringPolicy/> 45 <SizeBasedTriggeringPolicy size="100 MB"/> 46 </Policies> 47 </RollingFile> 48 </appenders> 49 <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> 50 <loggers> 51 <!--过滤掉spring和mybatis的一些无用的DEBUG信息--> 52 <logger name="org.springframework" level="INFO"></logger> 53 <logger name="org.mybatis" level="INFO"></logger> 54 <root level="all"> 55 <appender-ref ref="Console"/> 56 <appender-ref ref="RollingFileInfo"/> 57 <appender-ref ref="RollingFileWarn"/> 58 <appender-ref ref="RollingFileError"/> 59 </root> 60 </loggers> 61 </configuration>
五.日志调用
package com.my.study; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class UseLog4j2 { private static Logger logger = LogManager.getLogger(UseLog4j2.class); public static void main(String[] args) { // TODO Auto-generated method stub logger.info("33333"); } }
六.配置详解
Log4j2的日志配置文件,log4j2.xml文件的配置(实现控制台输出,各级别分别文件输出,自动压缩等)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd"> <!-- status : 这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,会看到log4j2内部各种详细输出 monitorInterval : Log4j能够自动检测修改配置文件和重新配置本身, 设置间隔秒数。 注:本配置文件的目标是将不同级别的日志输出到不同文件,最大2MB一个文件, 文件数据达到最大值时,旧数据会被压缩并放进指定文件夹 --> <Configuration status="WARN" monitorInterval="600"> <Properties> <!-- 配置日志文件输出目录,此配置将日志输出到tomcat根目录下的指定文件夹 --> <Property name="LOG_HOME">${sys:catalina.home}/WebAppLogs/HHServices </Property> </Properties> <Appenders> <!-- 优先级从高到低分别是 OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL --> <!-- 单词解释: Match:匹配 DENY:拒绝 Mismatch:不匹配 ACCEPT:接受 --> <!-- DENY,日志将立即被抛弃不再经过其他过滤器; NEUTRAL,有序列表里的下个过滤器过接着处理日志; ACCEPT,日志会被立即处理,不再经过剩余过滤器。 --> <!--输出日志的格式 %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间 %p : 日志输出格式 %c : logger的名称 %m : 日志内容,即 logger.info("message") %n : 换行符 %C : Java类名 %L : 日志输出所在行数 %M : 日志输出所在方法名 hostName : 本地机器名 hostAddress : 本地ip地址 --> <!--这个输出控制台的配置,这里输出除了warn和error级别的信息到System.out --> <Console name="console_out_appender" target="SYSTEM_OUT"> <!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) . --> <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" /> <!-- 输出日志的格式 --> <PatternLayout pattern="%5p [%t] %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %m%n" /> </Console> <!-- 这个输出控制台的配置,这里输出error级别的信息到System.err,在eclipse控制台上看到的是红色文字 --> <Console name="console_err_appender" target="SYSTEM_ERR"> <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="%5p [%t] %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %m%n" /> </Console> <!-- TRACE级别日志 ; 设置日志格式并配置日志压缩格式,压缩文件独立放在一个文件夹内, 日期格式不能为冒号,否则无法生成,因为文件名不允许有冒号,此appender只输出trace级别的数据到trace.log --> <RollingFile name="trace_appender" immediateFlush="true" fileName="${LOG_HOME}/trace.log" filePattern="${LOG_HOME}/trace/trace - %d{yyyy-MM-dd HH_mm_ss}.log.gz"> <PatternLayout> <pattern>%5p [%t] %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %m%n</pattern> </PatternLayout> <Policies> <!-- 每个日志文件最大2MB --> <SizeBasedTriggeringPolicy size="2MB" /> </Policies> <Filters> <!-- 此Filter意思是,只输出TRACE级别的数据 DENY,日志将立即被抛弃不再经过其他过滤器; NEUTRAL,有序列表里的下个过滤器过接着处理日志; ACCEPT,日志会被立即处理,不再经过剩余过滤器。 --> <ThresholdFilter level="debug" onMatch="DENY" onMismatch="NEUTRAL" /> <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" /> </Filters> </RollingFile> <!-- DEBUG级别日志 设置日志格式并配置日志压缩格式,压缩文件独立放在一个文件夹内, 日期格式不能为冒号,否则无法生成,因为文件名不允许有冒号,此appender只输出debug级别的数据到debug.log; --> <RollingFile name="debug_appender" immediateFlush="true" fileName="${LOG_HOME}/debug.log" filePattern="${LOG_HOME}/debug/debug - %d{yyyy-MM-dd HH_mm_ss}.log.gz"> <PatternLayout> <pattern>%5p [%t] %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %m%n</pattern> </PatternLayout> <Policies><!-- 每个日志文件最大2MB ; --> <SizeBasedTriggeringPolicy size="2MB" /> <!-- 如果启用此配置,则日志会按文件名生成新压缩文件, 即如果filePattern配置的日期格式为 %d{yyyy-MM-dd HH} ,则每小时生成一个压缩文件, 如果filePattern配置的日期格式为 %d{yyyy-MM-dd} ,则天生成一个压缩文件 --> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> </Policies> <Filters><!-- 此Filter意思是,只输出debug级别的数据 --> <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL" /> <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" /> </Filters> </RollingFile> <!-- INFO级别日志 --> <RollingFile name="info_appender" immediateFlush="true" fileName="${LOG_HOME}/info.log" filePattern="${LOG_HOME}/info/info - %d{yyyy-MM-dd HH_mm_ss}.log.gz"> <PatternLayout> <pattern>%5p [%t] %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %m%n</pattern> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="2MB" /> </Policies> <Filters> <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL" /> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> </Filters> </RollingFile> <!-- WARN级别日志 --> <RollingFile name="warn_appender" immediateFlush="true" fileName="${LOG_HOME}/warn.log" filePattern="${LOG_HOME}/warn/warn - %d{yyyy-MM-dd HH_mm_ss}.log.gz"> <PatternLayout> <pattern>%5p [%t] %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %m%n</pattern> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="2MB" /> </Policies> <Filters> <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL" /> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY" /> </Filters> </RollingFile> <!-- ERROR级别日志 --> <RollingFile name="error_appender" immediateFlush="true" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error/error - %d{yyyy-MM-dd HH_mm_ss}.log.gz"> <PatternLayout> <pattern>%5p [%t] %d{yyyy-MM-dd HH:mm:ss} (%F:%L) %m%n</pattern> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="2MB" /> </Policies> <Filters> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" /> </Filters> </RollingFile> </Appenders> <Loggers> <!-- 配置日志的根节点 --> <!-- 定义logger,只有定义了logger并引入了appender,appender才会生效 --> <root level="trace"> <appender-ref ref="console_out_appender" /> <appender-ref ref="console_err_appender" /> <appender-ref ref="trace_appender" /> <appender-ref ref="debug_appender" /> <appender-ref ref="info_appender" /> <appender-ref ref="warn_appender" /> <appender-ref ref="error_appender" /> </root> <!-- 第三方日志系统 --> <logger name="org.springframework.core" level="info" /> <logger name="org.springframework.beans" level="info" /> <logger name="org.springframework.context" level="info" /> <logger name="org.springframework.web" level="info" /> <logger name="org.jboss.netty" level="warn" /> <logger name="org.apache.http" level="warn" /> </Loggers> </Configuration>
七.log4j2<PatternLayout>子节点浅析
PatternLayout是最重要也是最常用的控制输出内容的节点,包括类名、时间、行号、日志级别、序号等都可以控制,同时还可以指定日志格式,可以使用正则表达式处理输出结果。
PatternLayout中包含的特殊字符包括 , , ,f,用\输出单斜线,用%%输出%。
下面是PatternLayout的参数
Parameter Name |
Type |
Description |
charset |
String |
输出的字符集。如果没有指定,则使用系统默认的字符集输出。 |
pattern |
String |
详见后面的pattern的表格 |
replace |
RegexReplacement |
替换部分输出中的String。这将会调用一个与RegexReplacement转换器相同的函数,不同的是这是针对整个消息的。 |
alwaysWriteExceptions |
boolean |
默认为true。总是输出异常,即使没有定义异常对应的pattern,也会被附在所有pattern的最后。设为false则不会输出异常。 |
header |
String |
可选项。包含在每个日志文件的顶部。 |
footer |
String |
可选项。包含在每个日志文件的尾部。 |
noConsoleNoAnsi |
boolean |
默认为false。如果为true,且System.console()是null,则不会输出ANSI转义码。 |
下面RegexReplacement参数
Parameter Name |
Type |
Description |
regex |
String |
Java正则表达式 |
replacement |
String |
任何匹配正则规则,被正则替换的后值 |
下面是pattern属性具体描述(这个表格仅包括了我能看懂的部分,还有很多看不懂并且试验也不成功的部分我都没写。另外用于控制输出结果颜色的highlight和style我也没有写,实在是感觉平时意义不大):
:
参数名 |
参数意义 |
详细描述 |
||||||||||||||||||||||||
%c{参数}或%logger{参数} |
输出logger的名称,即语句private static final Logger logger = LogManager.getLogger(App.class.getName())中App.class.getName()的值。也可以使用其他字符串。 |
如果不带参数,则输出完整的logger名称;如果参数是整数n(只支持正整数),则先将logger名称依照小数点(.)分割成n段,然后取右侧的n段;如果参数不是整数,则除了最右侧的一段,其他整段字符都用这个字符代替,保留小数点;不管怎么写,最右侧的一段都保持不变。默认不带参数,并输出logger的完整名称。注意:上面的说明写得很烂,但是官方文档写得就这么烂,而且还不完整,看不懂是必然的,还请看官自己多试验,才能有所领会。如果看官自己懒得试验又看不懂,只能建议不要加参数,直接%c输出完整值。 示例:
|
||||||||||||||||||||||||
%C{参数}或%class{参数} |
输出类名。注意,这个是大写C,上面是小写c。 |
参数规则与%c完全一样,请参见上面的说明。 |
||||||||||||||||||||||||
%d{参数}{时区te{参数}{时区 |
输出时间。 |
第一个大括号数可以是保留关键字,也可以是text.SimpleDateFormat字符拼接而成。保留关键字有:DEFAULT,ABSOLUTE, COMPACT, DATE, ISO8601, ISO8601_BASIC。 第二个大括号中的参数是java.util.TimeZone.getTimeZone的值,可以设定时区。 示例:
|
||||||||||||||||||||||||
无 |
输出特殊字符 |
&, <, >, ”, ’全都要使用实体名称或实体编号替代,即
官方文档说pattern删除了 和 ,但是经我测试可以使用,明显是官方文档的错误。 |
||||||||||||||||||||||||
%F|%file |
输出文件名 |
仅仅是文件名称,如Test.java,不包含路径名称 |
||||||||||||||||||||||||
highlight{pattern}{style} |
高亮显示结果 |
|
||||||||||||||||||||||||
%l |
输出完整的错误位置,如com.future.ourfuture.test.test.App.tt(App.java:13) |
注意1:这个是小写的L。 注意2:使用该参数会影影响日志输出的性能。 |
||||||||||||||||||||||||
%L |
输出错误行号,如“13” |
注意:使用该参数会影响日志输出的性能。 |
||||||||||||||||||||||||
%m或%msg或%message |
输出错误信息,即logger.error(String msg)中的msg |
|
||||||||||||||||||||||||
%M或%method |
输出方法名,如“main”,“getMsg”等字符串 |
|
||||||||||||||||||||||||
%n |
换行符 |
根据系统自行决定,如Windows是” ”,Linux是” ” |
||||||||||||||||||||||||
%level{参数1}{参数2}{参数3} |
参数1用来替换日志信息的级别,格式为:{level=label, level=label, …},即使用label代替的字符串替换level。其中level为日志的级别,如WARN/DEBUG/ERROR/TRACE/INFO 参数2表示只保留前n个字符。格式为length=n,n为整型。但参数1中指定了label的字符串不受此参数限制 参数3表示结果是大写还是小写。参数1指定了label的字符串不受此参数限制。 |
示例:
|
||||||||||||||||||||||||
%r或%relative |
输出自JVM启动以来到log事件开始时的毫秒数 |
|
||||||||||||||||||||||||
replace{pattern}{regex}{substitution} |
将pattern的输出结果,按照正则表达式regex匹配后,使用substitution字符串替换 |
例如:"%replace{%logger }{.}{/}就是将所有%logger中的小数点(.)全部替换为斜杠,如果%logger是com.future.ourfuture.test.test.App则输出为com/future/ourfuture/test/test/App。pattern中可以写多个表达式,如%replace{%logger%msg%C}{.}{/}%n |
||||||||||||||||||||||||
%sn或%sequenceNumber |
自增序号,每执行一次log事件,序号+1,是一个static变量。 |
|
||||||||||||||||||||||||
%t或%thread |
创建logging事件的线程名 |
|
||||||||||||||||||||||||
%u{RANDOM|TIME}或%uuid{RANDOM|TIME} |
依照一个随机数或当前机器的MAC和时间戳来随机生成一个UUID |
|
下面是pattern的对齐修饰:
对齐修饰,可以指定信息的输出格式,如是否左对齐,是否留空格等。
编写格式为在任何pattern和%之间加入一个小数,可以是正数,也可以是负数。如%10.20c表示对logger的信息进行处理。%-10.20m表示对message进行处理。
整数表示右对齐,负数表示左对齐;整数位表示输出信息的最小10个字符,如果输出信息不够10个字符,将用空格补齐;小数位表示输出信息的最大字符数,如果超过20个字符,则只保留最后20个字符的信息(注意:保留的是后20个字符,而不是前20个字符)。
下面是一些示例。
格式 |
是否左对齐 |
最小宽度 |
最大宽度 |
说明 |
%20 |
右对齐 |
20 |
无 |
右对齐,不足20个字符则在信息前面用空格补足,超过20个字符则保留原信息 |
%-20 |
左对齐 |
20 |
无 |
左对齐,不足20个字符则在信息后面用空格补足,超过20个字符则保留原信息 |
%.30 |
不对齐 |
无 |
30 |
如果信息超过30个字符,则只保留最后30个字符 |
%20.30 |
右对齐 |
20 |
30 |
右对齐,不足20个字符则在信息前面用空格补足,超过30个字符则只保留最后30个字符 |
%-20.30 |
左对齐 |
20 |
30 |
左对齐,不足20个字符则在信息后面用空格补足,超过30个字符则只保留最后30个字符 |
参考资料:http://www.cnblogs.com/hafiz/p/6170702.html