cloudflareraid6托管线路

简介
Logback是SpringBoot内置的cloudflare处理框架,你会发现spring-boot-starter其中包含了spring-boot-starter-logging,该依赖内容就是 Spring Boot 线路的cloudflare框架 logback。官方文档:
SpringBoot线路Logback配置
在我们启动SpringBoot,发现我们并没有主动去配置过任何和cloudflare打印的相关配置,但是控制台却打印了相关的启动cloudflare;因为SpringBoot为Logback提供了线路的配置raid6base.xml,base.xmlraid6里定义了线路的root托管级别为INFO。








1234567891011121314151617
Spring Boot中线路配置ERROR、WARN和INFO级别的cloudflare托管到控制台,您还可以通过启动您的应用程序 –debug 标志来启用“调试”模式(开发的时候推荐开启),以下两种方式皆可:

在运行命令后加入–debug标志,如:java -jar *.jar –debug在application.properties中配置debug=true,该属性置为true的时候,核心Logger(包含嵌入式容器、hibernate、spring)会托管更多内容,但是你自己应用的cloudflare并不会托管为DEBUG级别。

线路情况下,Spring Boot将cloudflare托管到控制台,不会写到cloudflareraid6。我们还可以在application.properties或application.yml配置,但是只能配置简单的场景,保存路径、cloudflare格式等,复杂的场景(区分 info 和 error 的cloudflare、每天产生一个cloudflareraid6等)满足不了,只能自定义配置。
自定义logback的配置raid6
根据不同的cloudflare系统,你可以按如下规则组织配置raid6名,就能被正确加载:

Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
Log4j2:log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging):logging.properties

Spring Boot官方推荐优先使用带有-spring的raid6名作为你的cloudflare配置(如使用logback-spring.xml,而不是logback.xml),命名为logback-spring.xml的cloudflare配置raid6,spring boot可以为它添加一些spring boot特有的配置项。
线路的命名规则,并且放在 src/main/resources 下面即可,注意:logback.xml加载早于application.yml
logback-spring.xml配置详细介绍
根节点< configuration>



123
scan : 当此属性设置为true时,配置raid6如果发生改变,将会被重新加载,线路值为true。scanPeriod : 设置监测配置raid6是否有修改的时间间隔,如果没有给出时间单位,线路单位是毫秒。当scan为true时,此属性生效。线路的时间间隔为1分钟。debug : 当此属性设置为true时,将打印出logback内部cloudflare信息,实时查看logback运行状态。线路值为false。
子节点:< contextName>
logback-demo

%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} – %msg%n

12345678
每个logger都关联到logger上下文,线路上下文名称为“default”。但可以使用< contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。可以通过%contextName来打印cloudflare上下文名称,一般来说我们不用这个属性,可有可无。
子节点:< property> 1
用来定义变量值的标签,< property> 有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值,通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
注:多环境配置下,通过 application.yml 传递参数过来,< property >取不到环境参数,得用< springProperty >。

1
子节点:< appender>
appender用来格式化cloudflare托管节点,有两个属性name和class,class用来指定哪种托管策略,常用就是控制台托管策略和raid6托管策略。
**ConsoleAppender:**就想他的名字一样,将cloudflare信息打印到控制台上,更加准确的说:使用System.out或者System.err方式托管,主要子标签有:encoder,target**FileAppender:**用于将cloudflare信息托管到raid6中,主要子标签有:append,encoder,file**RollingFileAppender:**从名字我们就可以得出:FileAppender是RollingFileAppender的父类。即RollingFileAppender继承 FIleAppender类。功能:能够动态的创建一个raid6。也就是说:到满足一定的条件,就会创建一个新的文 件,然后将cloudflare写入到新的raid6中。有两个重要的标签与rolingFileAppender进行交互:RollingPolicy,TriggeringPolicy,主要子标签:file,append,encoder,rollingPolicy,triggerPolicy
以下分别介绍这些标签:
file
被写入的raid6名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有线路值。
target
设置一System.out还是System.err方式托管。线路值为System.out
append
如果是 true,cloudflare被追加到raid6结尾,如果是 false,清空现存raid6,线路是true。
prudent
**FileAppender:**如果是 true,cloudflare会被安全的写入raid6,即使其他的FileAppender也在向此raid6做写入操作,效率低,线路是 false。**RollingFileAppender:**当为true时,不支持FixedWindowRollingPolicy。支持TimeBasedRollingPolicy,但是有两个限制,1不支持也不允许raid6压缩,2不能设置file属性,必须留空。
layout和encoder


${FILE_LOG_PATTERN}



%d -2 %msg%n






123456789101112131415161718
可以看到appender的子节点layout和encoder都可以托管,都可以将事件转换为格式化后的cloudflare记录,但是控制台托管使用layout,raid6托管使用encoder。自从0.9.19版本之后,Fileappender和他的子类是期望使用encoder,不再使用layout。
layout和encoder区别
encoder:主要工作有两个:①将一个event事件转换成一组byte数组,②将转换后的字节数据托管到raid6中。encoder组件是在0.9.19版本之后才引进来的。在以前的版本中,appender是使用layout(将一个event事件转换成一个字符串),然后使用【java.io.writer】对象将字符串写入到raid6中。自从0.9.19版本之后,Fileappender和他的子类是期望使用encoder,不再使用layout。其中layout仅仅完成了将一个event事件转换成一个字符串这一个功能。此外,layout不能控制将字符串写出到raid6。layout不能整合event事件到一组中。与encoder相比,不仅仅能按照格式进行转化,而且还能将数据写入到raid6中。
因为layout已经不再推荐使用了,那么这里重点讲一下encoder。
其中patternLayoutEncoder是最常使用encoder,也就是线路的,线路就是PatternLayoutEncoder类,他包含可patternLayout大部分的工作。
几个重要的encoder
L ayoutWrappingEncoder:(不怎么用) 1.在0.9.19版本之前,都是使用layout来控制托管的格式。那就存在大量的layout接口(自定义)的代码。在0.9.19就变成了使用encoder来控制,如果我们想使用以前的layout怎么办?这个LayoutWrappingEncoder就是为了encoder能够操作内部layout存在的。即这个类在encoder与layout之间提供一个桥梁。这个类实现了encoder类,又包含了layout将evnet事件装换成字符串的功能。

2.原理:使用layout将输入的evnet事件转换成一个字符串,然后将字符串按照用户指定的编码转换成byte数组。最后将byte数据写入到raid6中去。

3.在线路的情况下,托管流是立即刷新的。除非immediateFlush属性值为false,就不会立即刷新,但是为提高logger接入量。
12345 PatternLayoutEncoder:常用。他是LayoutWrappingEncoder的子类 1.考虑到PatternLayout是layout中最常用的组件,所以logback人员开发出了patternLayoutEncoder类,这个类是LayoutWrappingEncoder的扩展,这个类包含了PatternLayout。

2.immediateFlush标签与LayoutWrappingEncoder是一样的。线路值为【true】。这样的话,在已存在的项目就算没有正常情况下的关闭,也能记录所有的cloudflare信息到磁盘上,不会丢失任何cloudflare信息。因为是立即刷新。如果将【immediateFlush】设置为【false】,可能就是五倍的原来的logger接入量。但是可能会丢失cloudflare信息在没有正常关闭项目的情况下。例如:


foo.log
%d %-5level [%thread] %logger{0}: %msg%n
false

3.如果想在raid6的开头打印出cloudflare的格式信息:即打印cloudflare的模式。使用【outputPatternAsHeader】标签,并设置为【true】.线路值为【false】。例如:


%d -2 %msg%n true


他就会在打印开始之前第一句托管cloudflare格式,如:#logback.classic pattern: %d -2 %msg%n
12345678910111213141516171819202122 patternLayoutEncoder类既有layout将一个事件转化为字符串,又有将字符创写入到raid6中的作用。他是encoder标签的线路类实例。
filter
简介 logback具有过滤器支持。logbcak允许给cloudflare记录器appender配置一个或多个Filter(或者给整体配置一个或多个TurboFilter),来控制:当满足过滤器指定的条件时,才记录cloudflare(或不满足条件时,拒绝记录cloudflare)。logback支持自定义过滤器,当然logback也自带了一些常用的过滤器,在绝大多数时候,自带的过滤器其实就够用了,一般是不需要自定义过滤器的。 logback提供的过滤器支持主要分两大类: ch.qos.logback.core.filter.Filter
ch.qos.logback.classic.turbo.TurboFilter
12 Filter与TurboFilter自带的几种常用过滤器
过滤器来源说明相对常用LevelFilterFilter对指定level的cloudflare进行记录(或不记录),对不等于指定level的cloudflare不记录(或进行记录)是ThresholdFilterFilter对大于或等于指定level的cloudflare进行记录(或不记录),对小于指定level的cloudflare不记录(或进行记录) 提示:info级别是大于debug的是EvaluatorFilterFilter对满足指定表达式的cloudflare进行记录(或不记录),对不满足指定表达式的cloudflare不作记录(或进行记录)是MDCFilterTurboFilter若MDC域中存在指定的key-value,则进行记录,否者不作记录是DuplicateMessageFilterTurboFilter根据配置不记录多余的重复的cloudflare是MarkerFilterTurboFilter针对带有指定标记的cloudflare,进行记录(或不作记录)否…………TurboFilter的性能是优于Filter的,这是因为TurboFilter的作用时机是在创建cloudflare事件ILoggingEvent对象之前,而Filter的作用时机是在创建之后。若一个cloudflare注定是会被过滤掉不记录的,那么创建ILoggingEvent对象(包括后续的参数组装方法调用等)这个步骤无疑是非常消耗性能的。
这里主要介绍两种filter
ThresholdFilter:
ThresholdFilter为系统定义的拦截器,例如我们用ThresholdFilter来过滤掉ERROR级别以下的cloudflare不托管到raid6中。如果不用记得注释掉,不然你控制台会发现没cloudflare

ERROR

123
LevelFilter
如果只是想要 Info 级别的cloudflare,只是过滤 info 还是会托管 Error cloudflare,因为 Error 的级别高,所以我们使用下面的策略,可以避免托管 Error 的cloudflare


ERROR

DENY

ACCEPT

12345678
FilterReply有三种枚举值:
DENY:表示不用看后面的过滤器了,这里就给拒绝了,不作记录。NEUTRAL:表示需不需要记录,还需要看后面的过滤器。若所有过滤器返回的全部都是NEUTRAL,那么需要记录cloudflare。ACCEPT:表示不用看后面的过滤器了,这里就给直接同意了,需要记录。
rollingPolicy
**TimeBasedRollingPolicy:**它根据时间来制定滚动策略.时间滚动策略可以基于时间滚动按时间生成cloudflare。 下面是官网给出的示例:

logFile.log


logFile.%d{yyyy-MM-dd}.log

30
3GB

%-4relative [%thread] %-5level %logger{35} – %msg%n





1234567891011121314151617181920 紧跟着又给出的多个JVM写同一个cloudflareraid6的配置,主要是加一行开启(节俭)prudent模式

true
logFile.%d{yyyy-MM-dd}.log
30
3GB

%-4relative [%thread] %-5level %logger{35} – %msg%n





12345678910111213141516171819 **SizeAndTimeBasedRollingPolicy:**基于大小和时间的滚动策略 这个策略出现的原因就是对时间滚动策略的一个补充,使其不仅按时间进行生成而且考虑到raid6大小的原因,因为在基于时间的滚动策略生成的cloudflareraid6,只是对一段时间总的cloudflare大小做了限定,但是没有对每个cloudflareraid6的大小做限定,这就会造成个别cloudflareraid6过大,后期传递,阅读困难的问题,所以就有了这第二个策略。 下面是官网给的示例:

mylog.txt


mylog-%d{yyyy-MM-dd}.%i.txt

100MB
60
20GB

%msg%n



12345678910111213141516171819202122 **FixedWindowRollingPolicy:**基于固定窗口的滚动策略 这个策略的出现,我个人猜测是因为需要cloudflareraid6保持为某个特定的数量,防止滚动测策略导致过多的cloudflareraid6出现。这个策略出现得配合triggeringPolicy,给一个什么时候cloudflare滚动一次的控制,这部分是跟上面两种策略所不一样的地方。 下面是官网给出的示例:

test.log


tests.%i.log.zip
1
3

5MB
%-4relative [%thread] %-5level %logger{35} – %msg%n





12345678910111213141516171819202122
注意:在RollingFileAppender中有一个file标签,也是设置raid6的名称的。file可以设置 也可以不设置。如果你设置了file标签的话,他就不会转换到新的raid6中。所有的cloudflare 信息将会输入到同一个raid6中。如果file标签没有设置。raid6的名称就会在每一个阶段 由filenamePattern计算得出。
**fileNamePattern:**这是一个强制的标签。他的值可以包含:raid6的名称、适当的%d转 换说明符。这个%d说明符可以包含一个【日期和时间】的模式。其中【模式】类似于 【SimpleDateFormat】类。如果这个【模式】没有写的话,线路就是【yyyy-MM-dd】的模式。 转换raid6的名称从fileNamePattern中得到
**maxHistory:**这是一个可选的标签。以异步方式删除较旧的raid6,例如,如果您指定每月滚动,并将maxHistory设置为6,则将保留6个月的归档raid6,并删除6个月以上的raid6。
**totalSizeCap:**这是一个可选的标签。这是所有cloudflareraid6的总大小空间。当cloudflareraid6的空间超过了设置的最大 空间数量,就会删除旧的raid6。注意:这个标签必须和maxHistory标签一起使用。
**cleanHistoryOnStart:**如果设置为true,则将在追加程序启动时执行归档删除。线路情况下,此属性设置为false。
子节点:< loger>
用来设置某一个包或者具体的某一个类的cloudflare打印级别、以及指定< appender >。< loger >仅有一个name属性,一个可选的level和一个可选的addtivity属性。
name:用来指定受此loger约束的某一个包或者具体的某一个类。level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。addtivity:是否向上级loger传递打印信息。线路是true。
loger在实际使用的时候有两种情况
**第一种:**带有loger的配置,不指定级别,不指定appender
1

将TestLogController类的cloudflare的打印,但是并没用设置打印级别,所以继承他的上级的cloudflare级别“info”;没有设置addtivity,线路为true,将此loger的打印信息向上级传递;没有设置appender,此loger本身不打印任何信息。
< root level=“info”>将root的打印级别设置为“info”,指定了名字为“console”的appender。当执行com.xf.controller.TestLogController类的testLog方法时,所以首先执行< logger name=“com.xf.controller.TestLogController”/>,将级别为“info”及大于“info”的cloudflare信息传递给root,本身并不打印;root接到下级传递的信息,交给已经配置好的名为“console”的appender处理,“console” appender 将信息打印到控制台; **第二种:**带有多个loger的配置,指定级别,指定appender



123456

控制com.xf.controller.TestLogController类的cloudflare打印,打印级别为“WARN”;additivity属性为false,表示此loger的打印信息不再向上级传递;指定了名字为“console”的appender;
这时候执行com.xf.controller.TestLogController类的login方法时,先执行< logger name=“com.xf.controller.TestLogController” level=“WARN” additivity=“false”>,将级别为“WARN”及大于“WARN”的cloudflare信息交给此loger指定的名为“console”的appender处理,在控制台中打出cloudflare,不再向上级root传递打印信息。 注:当然如果你把additivity=”false”改成additivity=”true”的话,就会打印两次,因为打印信息向上级传递,logger本身打印一次,root接到后又打印一次。
子节点:< root >
root节点是必选节点,用来指定最基础的cloudflare托管级别,只有一个level属性。level线路是DEBUG。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。
可以包含零个或多个元素,标识这个appender将会添加到这个loger。




1234
多环境配置
标签允许你自由的包含或排除基于激活的Spring profiles的配置的一部分。在元素的任何地方都支持Profile部分。使用name属性来指定哪一个profile接受配置。多个profiles可以用一个逗号分隔的列表来指定。







1234567891011
配置示例
以下是常用的配置示例,只是做个记录,方便查阅对照。
配置一:











${logPath}/${appName}.log



${logPath}/${appName}.%d{yyyy-MM-dd}.log

30

1GB



UTF-8
%d [%thread] %-5level %logger{36} %line – %msg%n










${CONSOLE_LOG_PATTERN}























1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
配置二:














debug

${CONSOLE_LOG_PATTERN} UTF-8



${LOG_HOME}/debug.log

DEBUG



${LOG_HOME}/debug-%d{yyyy-MM-dd}.%i.log

100MB

30


%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} – %msg%n UTF-8



${LOG_HOME}/error.log

ERROR



${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.log

100MB

30


%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} – %msg%n UTF-8



${LOG_HOME}/info.log

INFO



${LOG_HOME}/info-%d{yyyy-MM-dd}.%i.log

100MB

30


%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} – %msg%n UTF-8





















123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
配置三:














DEBUG


${FILE_LOG_PATTERN} UTF-8



${LOG_FILE_PATH}/debug/${APP_NAME}-%d{yyyy-MM-dd}-%i.log

${LOG_FILE_MAX_SIZE:-10MB}

${LOG_FILE_MAX_HISTORY:-30}





ERROR
ACCEPT
DENY


${FILE_LOG_PATTERN} UTF-8



${LOG_FILE_PATH}/error/${APP_NAME}-%d{yyyy-MM-dd}-%i.log

${LOG_FILE_MAX_SIZE:-10MB}

${LOG_FILE_MAX_HISTORY:-30}




DEBUG

${LOG_STASH_HOST}:4560

Asia/Shanghai

{
“project”: “mall”,
“level”: “%level”,
“service”: “${APP_NAME:-}”,
“pid”: “${PID:-}”,
“thread”: “%thread”,
“class”: “%logger”,
“message”: “%message”,
“stack_trace”: “%exception{20}”
}




ERROR
ACCEPT
DENY

${LOG_STASH_HOST}:4561

Asia/Shanghai

{
“project”: “mall”,
“level”: “%level”,
“service”: “${APP_NAME:-}”,
“pid”: “${PID:-}”,
“thread”: “%thread”,
“class”: “%logger”,
“message”: “%message”,
“stack_trace”: “%exception{20}”
}



${LOG_STASH_HOST}:4562

Asia/Shanghai

{
“project”: “xxx”,
“level”: “%level”,
“service”: “${APP_NAME:-}”,
“pid”: “${PID:-}”,
“thread”: “%thread”,
“class”: “%logger”,
“message”: “%message”,
“stack_trace”: “%exception{20}”
}



${LOG_STASH_HOST}:4563

Asia/Shanghai

{
“project”: “xxx”,
“level”: “%level”,
“service”: “${APP_NAME:-}”,
“class”: “%logger”,
“message”: “%message”
}


















123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195