`
schy_hqh
  • 浏览: 543341 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Chapter 4: Appenders

阅读更多

OutputStreamAppender

ConsoleAppender

三个可配置属性:

encoderOutputStreamAppender的一个属性,用来设置日志格式

target:  System.out or System.err,default is System.out

withJansi: ANSI color(在win7 64bit上无法正常工作)

 

 

<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

 

===============================================================================

 

FileAppender

The FileAppender, a subclass of OutputStreamAppender, appends log  events into a file.

可配置属性

append: 是否追加,默认为true

encoder:OutputStreamAppender的一个属性,用于设置日志格式

file: 指定存放日志的文件,如果不存在,将自动创建(mkdirs)。

   文件路径:c:/test.log 或 c:\\test.log。文件属性没有默认值

prudent: true/false, default false. 确保在多JVM环境下的日志安全处理的机制(文件锁)。

   该机制如果被设置为true,则append属性将自动设置为true

   该机制会影响到日志写入效率!

 

<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>testFile.log</file>
    <append>true</append>
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>
        
  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

 

 

Uniquely named files (by timestamp)

利用timestamp设置唯一的日志文件名

取配置文件被解析时的时间作为当前时间

<configuration>

  <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
       the key "bySecond" into the logger context. This value will be
       available to all subsequent configuration elements. -->
  <timestamp key="bySecond" datePattern="yyyy年MM月dd日HH时mm分ss秒"/>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <!-- use the previously created timestamp to create a uniquely
         named log file -->
    <file>log-${bySecond}.txt</file>
    <encoder>
      <pattern>%logger{35} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

 

使用系统的contextBirth 设置时间

<configuration>
  <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" 
             timeReference="contextBirth"/>
  ...
</configuration>

  

 

RollingFileAppender

滚动日志

两个重要的组件:

   RollingPolicy     负责日志滚动-how

   TriggeringPolicy  负责触发日志回滚动作的执行-when

RollingFileAppender 必须配置RollingPolicy 和   TriggeringPolicy

不过,RollingPolicy 已经对TriggeringPolicy 进行了实现,因此,只需要配置RollingPolicy 即可!

 

RollingFileAppender可配置属性:

file:记录日志的文件,该属性可选。如果没有设置,logback将自动进行文件命名。

如logFile.2014-03-07.log。

但是,通过file属性指定文件,可以实现已记录日志与正在记录日志文件的解耦。

append:是否追加,默认true

encoder:OutputStreamAppender的一个属性,用于设置日志格式

rollingPolicy:负责日志滚动时的具体行为

triggeringPolicy:告诉fileAppender何时激活日志的滚动行为

prudent:FixedWindowRollingPolicy 不支持

TimeBasedRollingPolicy 进行联合使用,不支持也不允许文件压缩,file属性不能设置,必须为blank

 

 

TimeBasedRollingPolicy

TimeBasedTriggeringPolicy 实现了RollingPolicy和TriggeringPolicy

TimeBasedRollingPolicy具有1个强制属性和几个可选属性:

fileNamePattern 强制属性,指定日志文件的名称样式(actived,已记录完日志的文件)

%d{pattern} SimpleDateFormat格式,默认为yyyy-MM-dd

注意:"/" 或者 "\",logback将其解析为路径分隔符

maxHistory int类型 指定最大保留多少个文件,将自动删除超出保留个数的日志文件

cleanHistoryOnStart boolean类型 在appender启动的时候移除已有日志文件?

 

fileNamePattern详细配置  

/wombat/foo.%d   每天自动滚动[daily rollover at midnight]

没有设置file属性

第1天的日志名为/wombat/foo.2006-11-23

第2天的日志名为/wombat/foo.2006-11-24

设置了file属性,即指定了file名称

                设置了日志文件名称为/wombat/foo.txt

到午夜,foo.txt将被重命名为/wombat/foo.2006-11-23

然后,logback将创建1个新的foo.txt日志文件(保证当天记录日志的文件名始终都是foo.txt)

 

/wombat/%d{yyyy/MM}/foo.txt  每个月初进行滚动

file property not set:

当月:    /wombat/2006/10/foo.txt

 下个月:/wombat/2006/11/foo.txt.         

file property set to /wombat/foo.txt:

  在2006年10月份,日志名称始终是 /wombat/foo.txt

  在2006年11月份,日志名称将被重命名为 /wombat/2006/10/foo.txt

  而且,1个新的日志文件被创建,名称仍未指定的文件名/wombat/foo.txt

 到在2006年12月份,又被重命名为/wombat/2006/11/foo.txt

然后再创建1个新的/wombat/foo.txt

 

/wombat/foo.%d{yyyy-ww}.log  每周滚动1次

 

/wombat/foo%d{yyyy-MM-dd_HH-mm}.log  每分钟滚动1次

 

/foo/%d{yyyy-MM,aux}/%d.log  带文件夹的每天滚动1次 【aux 辅助标记】

日志将被放在1个以年和月命名的文件夹下,而且日志名称采用年月日的方式命名

由于%d没有aux修饰,将被作为日志的命名规则

这样,日志名称按%d进行命名,同时,文件夹将以年和月进行命名

如,folder :   /foo/2006-11/

日志路径则为: /foo/2006-11/2006-11-14.log

 好处:非常方便的将日志文件放在不同文件夹下进行管理!

 

/wombat/foo.%d.gz  在日志滚动的时候,将对历史日志文件进行压缩

如果,fileNamePattern以".gz"或者".zip"结尾,日志压缩功能将被开启

 

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

      <!-- keep 30 days' worth of history -->
      <maxHistory>30</maxHistory>
    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender> 

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

 

开启prudent模式,支持多JVM环境往同一个日志文件写入日志

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- Support multiple-JVM writing to the same log file -->
    <prudent>true</prudent>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory> 
    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender> 

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

 

SizeAndTimeBasedFNATP

基于时间和文件大小的配置

当文件达到指定大小时,将通过额外的index参数(自增,从0开始)附加在日志文件上

已归档的日志:

mylog-2014-03-08.0.txt

mylog-2014-03-08.1.txt

mylog-2014-03-08.2.txt

当前日志:

mylog.txt

<configuration>
  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.txt</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
      <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <!-- or whenever the file size reaches 100MB -->
        <maxFileSize>10MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>


  <root level="DEBUG">
    <appender-ref ref="ROLLING" />
  </root>

</configuration>

 

  

SizeBasedTriggeringPolicy

当日志文件达到指定大小时,logback对日志进行滚动

SizeBasedTriggeringPolicy 只支持1个属性

maxFileSize:default value of 10MB

maxFileSize可以指定的值:KB,MB ,  GB (5000KB, 5MB and 2GB)

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>test.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
      <fileNamePattern>test.%i.log.zip</fileNamePattern>
      <minIndex>1</minIndex>
      <maxIndex>3</maxIndex>
    </rollingPolicy>

    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>5MB</maxFileSize>
    </triggeringPolicy>
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>
        
  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

 

===============================================================================  

 

 

SocketAppender and SSLSocketAppender

SocketAppender被设计成可在网络上传输序列化的ILoggingEvent实例对象,在远程日志服务器上进行日志记录

SocketAppender  以明文方式进行传输

SSLSocketAppender 以密文方式进行传输

LoggingEventVO 实现了ILoggingEvent   接口

当反序列话完成之后,在远程日志服务器上将对日志进行记录,就像在本地记录日志一样

在接收端反序列化日志对象后,该事件可以像本地一样的进行日志记录

在不同的机器上运行多个SocketAppender实例,他们的日志输出定向到一个中央日志服务器,其格式是固定的,因为网路上传输日志是没有Layout可言的

SocketAppender利用传输控制协议(TCP)层进行数据传输,TCP提供了一个可靠的,有序的,流控制的端到端的字节流

如果远程日志服务器连接正常,则日志将被正确传输过去

如果远程日志服务器关机或不可达,则日志将被丢弃

当远程服务器恢复可连接状态时,日志传输任务将透明的被恢复,这个透明的重连接是通过一个"connector thread"周期性尝试与远程服务器进行连接实现的【底层源码如何实现的?】

 

需要注意:即使SocketAppender 没有注册到任何logger上,它也不会被JVM垃圾回收

当且仅当远程服务器关机,导致连接失败时,"connector thread"才会自动结束

为了避免垃圾收集文件,当不需要远程日志记录时,应该明确关闭  SocketAppender

如果1个应用处于长时间运行,又进行远程日志记录,就需要注意这个问题了

在应用退出之前,为了防止管道流中仍有未传输完成的日志数据,应该调用   SocketAppender 的close()或者LoggerContext's stop(),将数据都传输完成再关闭应用。

 

可配置属性如下

includeCallerData

default:false
true ,调用者的相关信息将提供给远程主机
false,  调用方的相关信息不提供给远程主机

reconnectionDelay

指定连接服务器失败后,再次尝试连接的等待时间,如10 seconds
Default value of this option is 30 seconds.
默认值30秒
Setting this option to zero turns off reconnection capability
设置为0则关闭重连接
如果连接成功,则没有"connector thread"存在(该线程仅当连接失败时才有存在的必要)

queueSize

通过1个非负的整数描述该队列需要保留多少logging event
当队列长度为0时,将以同步方式进行数据传输
当队列长度大于0时,logging event 将被加入到队列中(队列未满)

eventDelayLimit

对queueSize的附加配置
当远程日志服务器处理效率慢,而导致本地日志队列已满时,指定等待进入队列的logging Event被丢弃的时间
该属性的默认值为100 milliseconds,可以指定为10 seconds或其它
当100milliseconds后,队列中有空余空间,则加入,否则,丢弃等待进入队列的event

remoteHost

远程主机地址

 

port

远程主机端口

ssl

是否使用安全套接字进行传输

 

[远程记录日志以后再弄....]

 

 

 

=============================================================================== 

 

SMTPAppender

发送邮件的日志记录器

SMTPAppender 的属性配置:

 

smtpHost:   SMTP server,如smtp.126.com

 

smtpPort:    default 25

 

to:                 接收方邮件地址,多人接收则使用commas分割

 

from:            发送方的邮件地址

 

subject:        邮件主题

 

username:    连接SMTP SERVER的用户名

 

password:    连接SMTP SERVER的密码

 

discriminator: 使用默认提供的discriminator,它始终返回同一个值,这样,所有的event都使用同一个日志缓冲区;通过配置Discriminator,SMTPAppender 可以根据返回值的不同,将发生的event缓存到不同的buffer中。这样,可以实现不同event发送到不同的地方。【不同event进入不同buffer】

 

evaluator: 默认提供OnErrorEvaluator ,当发生error级别的日志时将触发邮件的发送。

logback提供了其它类型的触发机制:

通过标记来触发:OnMarkerEvaluatorJaninoEventEvaluator,GEventEvaluator.          

 

cyclicBufferTracker: 如果没有指定该属性,logback将提供1个默认的实现CyclicBufferTrackerImpl ,它将保持缓冲区大小为256条日志.缓冲区大小可以进行配置,通过设置CyclicBufferTrackerImplbufferSize属性即可。

256条日志:缓冲区最多保留256条日志。

 

STARTTLS: 默认false. 如果设置为true,appender将发出一个STARTTLS 命令给服务器,将连接切换为SSL传输

 

SSL: 默认false. 如果设置为true,则使用SSL 方式与服务器进行连接

 

charsetEncoding: 默认使用UTF-8编码

 

localhost: 客户端主机名称

 

asynchronousSending: 邮件传输是否采用异步方式。

 

includeCallerData: 默认为false.如果配置了asynchronousSending=true,希望包含调用者信息,可设置为true.

 

sessionViaJNDI: SMTPAppender 是依靠javax.mail.Session进行邮件发送的。

默认情况下,sessionViaJNDI 是设置为false的,因此javax.mail.Session是由SMTPAppender自己

创建的(通过读取用户配置的邮件服务器配置)。如果sessionViaJNDI 设置为true,则javax.mail.Session

将通过JNDI进行获取(JNDI服务在应用服务器/容器中进行配置)。

注意:如果使用JNDI获取javax.mail.Session,确保删除WEB-INF/lib中mail.jar、activation.jar 

 

jndiLocation: 配置javax.mail.Session的JNDI位置,默认"java:comp/env/mail/Session"

 

 

The SMTPAppender keeps only the last 256 logging events in its cyclic buffer, throwing away older events when its buffer becomes full. Thus, the number of logging events delivered in any e-mail sent by SMTPAppender is upper-bounded by 256. 

 SMTPAppender 的缓冲区仅仅保留最近的256条日志记录,当缓冲区满了,将从缓冲区中清除最旧的日志。这样,任何被传输的email最多包含256条日志。默认在发生error时触发邮件进行发送。

 

SMTPAppender 依赖 JavaMail API。因此,需要提供mail.jar 和 activation.jar到classpath中

 

<configuration debug="true">   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <smtpHost>smtp.126.com</smtpHost>
    <smtpPort>25</smtpPort>
    <username>sailhuang@126.com</username>
    <password>******</password>
    <to>sailhuang@126.com</to>
    <from>sailhuang@126.com</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <includeCallerData>false</includeCallerData>
    <!-- 自定义样式 -->
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%date %-5level %logger{35} - %message%n</pattern>
    </layout>       
  </appender>

  <root level="DEBUG">
    <appender-ref ref="EMAIL" />
  </root>  
</configuration>

 

网页样式

<configuration debug="true">   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <smtpHost>smtp.126.com</smtpHost>
    <smtpPort>25</smtpPort>
    <username>sailhuang@126.com</username>
    <password>******</password>
    <to>sailhuang@126.com</to>
    <from>sailhuang@126.com</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <includeCallerData>false</includeCallerData>
    <!-- HTML样式 -->
    <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="EMAIL" />
  </root>  
</configuration>

 

 

 

Custom buffer size

指定缓冲区大小,比如,设置为10,则只保留error发生前的9条log

<configuration debug="true">   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <smtpHost>smtp.126.com</smtpHost>
    <smtpPort>25</smtpPort>
    <username>sailhuang@126.com</username>
    <password>*****</password>
    <to>sailhuang@126.com</to>
    <from>sailhuang@126.com</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <includeCallerData>false</includeCallerData>
    
	<!-- 缓冲区大小 -->
    <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
      <bufferSize>10</bufferSize>
    </cyclicBufferTracker>

    <!-- HTML样式 -->
    <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="EMAIL" />
  </root>  
</configuration>

  

Triggering event

【自定义触发机制】

当日志累积到多少条时发送有邮件,覆盖默认的OnErrorEvaluator,不再由Error所触发了!

 

package chapters.configuration;

import ch.qos.logback.core.boolex.EvaluationException;
import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.spi.ContextAwareBase;

public class CounterBasedEvaluator extends ContextAwareBase implements
		EventEvaluator {
	
	/**每10条日志就触发邮件发送*/
	static int LIMIT = 10;
	int counter = 0;
	String name;

	public boolean evaluate(Object event) throws NullPointerException,
			EvaluationException {
		//计数器
		counter++;

		if (counter == LIMIT) {
			counter = 0;

			return true;
		} else {
			return false;
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	//====================================
	public void start() {}

	public void stop() {}

	public boolean isStarted() {
		return false;
	}
}

 

此时,定义的BufferSize最好与LIMIT一致

<configuration debug="true">   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
	
	<evaluator class="chapters.configuration.CounterBasedEvaluator" />
	
    <smtpHost>smtp.126.com</smtpHost>
    <smtpPort>25</smtpPort>
    <username>sailhuang@126.com</username>
    <password>*****</password>
    <to>sailhuang@126.com</to>
    <from>sailhuang@126.com</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <includeCallerData>false</includeCallerData>
    
	<!-- 缓冲区大小与LIMIT保持一致 -->
    <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
      <bufferSize>10</bufferSize>
    </cyclicBufferTracker>

    <!-- HTML样式 -->
    <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="EMAIL" />
  </root>  
</configuration>

 

Marker based triggering

基于标记进行触发

当具有特定标记的日志被记录时,触发邮件发送

不一定非得发送ERROR时才发送邮件,可以在某个感兴趣的事件发生时发送邮件

比如,用户付款成功后,即发送邮件进行通知

 

logback.xml

<configuration debug="true">   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
	<!-- 通过标记进行触发 -->
	<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
      <marker>NOTIFY_ADMIN</marker>
      <!-- you specify add as many markers as you want -->
      <marker>TRANSACTION_FAILURE</marker>
    </evaluator>

    <smtpHost>smtp.126.com</smtpHost>
    <smtpPort>25</smtpPort>
    <username>sailhuang@126.com</username>
    <password>*****</password>
    <to>sailhuang@126.com</to>
    <from>sailhuang@126.com</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <includeCallerData>false</includeCallerData>

    <!-- HTML样式 -->
    <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="EMAIL" />
  </root>  
</configuration>

 

记录日志的时候,使用Marker

package chapters.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

public class MyApp1 {
	  final static Logger logger = LoggerFactory.getLogger(MyApp1.class);

	  public static void main(String[] args) {
		  logger.info("some one coming to shopping");
		  String name = "张三";
		  int howmuch = 1000000;
		  Marker notifyAdmin = MarkerFactory.getMarker("NOTIFY_ADMIN");
		  logger.info(notifyAdmin,"name = {}, paid money: {}", name, howmuch);
	  }

}

  



 

 

Marker-based triggering with JaninoEventEvaluator

另一种Marker的使用方式: JaninoEventEvaluator

<configuration>
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
      <expression>
        (marker != null) &&
        (marker.contains("NOTIFY_ADMIN") || marker.contains("TRANSACTION_FAILURE"))
      </expression>
    </evaluator>    
    ... same as above
  </appender>
</configuration>

  

 

Marker-based triggering with GEventEvaluator

 另一种Marker的使用方式:GEventEvaluator

 

<configuration>
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
      <expression>
        e.marker?.contains("NOTIFY_ADMIN") || e.marker?.contains("TRANSACTION_FAILURE")
      </expression>
    </evaluator>    
    ... same as above
  </appender>
</configuration>

 

Authentication/STARTTLS/SSL

 In SSL mode, the connection is encrypted right from the start.    

 SSL模式,连接一开始就是进行加密传输的

 

 In STARTTLS, the connection is initially non-encrypted and only after the STARTTLS command is issued by the client does the connection switch to SSL.

STARTTLS模式在初始化连接时不是加密连接的,仅当客户端使用STARTTLS 命令后,连接才被切换到SSL连接(前提是服务器支持模式切换)

 

<configuration>
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <smtpHost>smtp.126.com</smtpHost>
    <smtpPort>25</smtpPort>
    <SSL>true</SSL>
    <username>sailhuang@126.com</username>
    <password>****</password>

    <to>sailhuang@126.com</to>
    <to>sailhuang@163.com</to> <!-- additional destinations are possible -->
    <from>sailhuang@126.com</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%date %-5level %logger{35} - %message%n</pattern>
    </layout>       
  </appender>

  <root level="DEBUG">
    <appender-ref ref="EMAIL" />
  </root>  
</configuration>

 

 STARTTLS protocol

<configuration>   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <smtpHost>smtp.gmail.com</smtpHost>
    <smtpPort>587</smtpPort>
    <STARTTLS>true</STARTTLS>
    <username>YOUR_USERNAME@gmail.com</username>
    <password>YOUR_GMAIL_xPASSWORD</password>
    
    <to>EMAIL-DESTINATION</to>
    <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
    <from>YOUR_USERNAME@gmail.com</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%date %-5level %logger - %message%n</pattern>
    </layout>       
  </appender>

  <root level="DEBUG">
    <appender-ref ref="EMAIL" />
  </root>  
</configuration>

 

 

===============================================================================

DBAppender

把日志往数据库中记录

three tables:

logging_event

logging_event_property

logging_event_exception.

 

The logging_event table contains the following fields:  

timestamp 记录日志时的时间戳

formatted_message  格式化之后的日志内容
logger_name 记录该日志的logger名称
level_string  logger的Level
reference_flag 标识日志事件所关联的属性( MDC or Context properties )
caller_filename logger所在的java类
caller_class   全路径类名
caller_method 日志记录时所在的方法名称

caller_line 日志记录时所在的行号

event_id  数据库id

 

The logging_event_property is used to store the keys and values contained in the MDC or the Context. It contains these fields:  

event_id  日志的数据库id

mapped_key  MDC的key

mapped_value MDC的key

 

The logging_event_exception table contains the following fields:  

event_id 日志的数据库id

堆栈跟踪的索引

trace_line  堆栈跟踪对应的行

 

Logback提供了创建3张表的脚本,MySql为例

 

# Logback: the reliable, generic, fast and flexible logging framework.
# Copyright (C) 1999-2010, QOS.ch. All rights reserved.
#
# See http://logback.qos.ch/license.html for the applicable licensing 
# conditions.

# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender.
#
# It is intended for MySQL databases. It has been tested on MySQL 5.1.37 
# on Linux


BEGIN;
DROP TABLE IF EXISTS logging_event_property;
DROP TABLE IF EXISTS logging_event_exception;
DROP TABLE IF EXISTS logging_event;
COMMIT;


BEGIN;
CREATE TABLE logging_event 
  (
    timestmp         BIGINT NOT NULL,
    formatted_message  TEXT NOT NULL,
    logger_name       VARCHAR(254) NOT NULL,
    level_string      VARCHAR(254) NOT NULL,
    thread_name       VARCHAR(254),
    reference_flag    SMALLINT,
    arg0              VARCHAR(254),
    arg1              VARCHAR(254),
    arg2              VARCHAR(254),
    arg3              VARCHAR(254),
    caller_filename   VARCHAR(254) NOT NULL,
    caller_class      VARCHAR(254) NOT NULL,
    caller_method     VARCHAR(254) NOT NULL,
    caller_line       CHAR(4) NOT NULL,
    event_id          BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
  );
COMMIT;

BEGIN;
CREATE TABLE logging_event_property
  (
    event_id	      BIGINT NOT NULL,
    mapped_key        VARCHAR(254) NOT NULL,
    mapped_value      TEXT,
    PRIMARY KEY(event_id, mapped_key),
    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
  );
COMMIT;

BEGIN;
CREATE TABLE logging_event_exception
  (
    event_id         BIGINT NOT NULL,
    i                SMALLINT NOT NULL,
    trace_line       VARCHAR(254) NOT NULL,
    PRIMARY KEY(event_id, i),
    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
  );
COMMIT;

 

 

 

 

ConnectionSource

 

据专家介绍,在"标准PC"上,往数据库插入1条记录大约需要10 milliseconds

如果使用了连接池技术,时间消耗将仅有1 millisecond

因此,与数据库打交道,数据库连接池显得非常重要

 

通过使用DBAppender 与数据库打交道可以有几种不同的方式:

关于DBAppender 最重要的配置- ConnectionSource 对象

 

logback通过ConnectionSource 接口提供可插拔的方式获取java.sql.Connection.

 

There are currently three implementations of ConnectionSource, namely DataSourceConnectionSource,

DriverManagerConnectionSource,

JNDIConnectionSource.    

 

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.10</version>
</dependency>

 

 

 DriverManagerConnectionSource

Note that this class will establish a new Connection for each call to getConnection()

注意:DriverManagerConnectionSource每次都会创建1个新的连接,没有使用连接池技术

因此,需要自己实现一个连接池,通过implementation of ConnectionSource

 

没有使用连接池的配置,直接使用DriverManagerConnectionSource

每次都创建新的连接

logback.xml

<configuration>

  <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
      <driverClass>com.mysql.jdbc.Driver</driverClass>
      <url>jdbc:mysql://localhost:3306/logback</url>
      <user>root</user>
      <password>root</password>
    </connectionSource>
  </appender>
  
  <root level="DEBUG" >
    <appender-ref ref="DB" />
  </root>
</configuration>

 

测试类

package chapters.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyApp1 {
	  final static Logger logger = LoggerFactory.getLogger(MyApp1.class);

	  public static void main(String[] args) {
		  long start = System.currentTimeMillis();
		  for(int i=0;i<500;i++)
		  logger.info("some one coming to shopping");
		  long total = System.currentTimeMillis()-start;
		  logger.info("500 records takes: {} mills ", total);
	  }

}

 

 

 

 

DataSourceConnectionSource

实现了ConnectionSource 接口,并且基于javax.sql.DataSource获取数据库连接

使用C3P0连接池

<dependency>
	<groupId>c3p0</groupId>
	<artifactId>c3p0</artifactId>
	<version>0.9.1.2</version>
</dependency>

 
Logback.xml

<configuration>

  <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource
      class="ch.qos.logback.core.db.DataSourceConnectionSource">
      <dataSource
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <driverClass>com.mysql.jdbc.Driver</driverClass>
        <jdbcUrl>jdbc:mysql://localhost:3306/logback</jdbcUrl>
        <user>root</user>
        <password>root</password>
      </dataSource>
    </connectionSource>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="DB" />
  </root>
</configuration>

 测试类

package chapters.configuration;

import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyApp1 {
	  final static Logger logger = LoggerFactory.getLogger(MyApp1.class);

	  public static void main(String[] args)throws Exception {
		  logger.info("some one coming to shopping");
		  Thread.sleep(new Random().nextInt(10000));
		  System.out.println("waking...");
		  long start = System.currentTimeMillis();
		  for(int i=0;i<500;i++)
		  logger.info("some one coming to shopping");
		  long total = System.currentTimeMillis()-start;
		  logger.info("500 records takes: {} mills ", total);
	  }

}

 



 

采用C3P0默认的设置,发现没快好多呢。。。

 

 

 

JNDIConnectionSource

在J2EE Sever中定义DataSource,以Tomcat为例

Context.xml 

<Context docBase="/path/to/app.war" path="/myapp">
  ...
  <Resource name="jdbc/logging"
               auth="Container"
               type="javax.sql.DataSource"
               username="..."
               password="..."
               driverClassName="org.postgresql.Driver"
               url="jdbc:postgresql://localhost/..."
               maxActive="8"
               maxIdle="4"/>
  ...
</Context>

 

logback.xml  通过JNDI从Tomcat容器中获取DataSource

<configuration debug="true">
  <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource class="ch.qos.logback.core.db.JNDIConnectionSource">
      <!-- please note the "java:comp/env/" prefix -->
      <jndiLocation>java:comp/env/jdbc/logging</jndiLocation>
    </connectionSource>
  </appender>
  <root level="INFO">
    <appender-ref ref="DB" />
  </root>  
</configuration>

 

 

 POM.XML

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>logger</groupId>
	<artifactId>sl4j</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>sl4j</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.10</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.0.13</version>
		</dependency>
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4.7</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.10</version>
		</dependency>
		<dependency>
			<groupId>c3p0</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.1.2</version>
		</dependency>

	</dependencies>
</project>

 

 

 

 

  • 大小: 98.1 KB
  • 大小: 61 KB
  • 大小: 258.3 KB
  • 大小: 266.4 KB
分享到:
评论

相关推荐

    log4j:WARN No appenders could be found for logger (org.springframework.context.s

    NULL 博文链接:https://wait7758521.iteye.com/blog/1933964

    log4js钉钉机器人的Appenders

    log4js 钉钉机器人的 Appenders

    log4j日志报错解决办法

    提示:log4j:WARN Please initialize the log4j system properly,log4j:WARN No appenders could be found for logger错误的处理办法

    JAVACCC.DLL

    log4j:WARN No appenders could be found for logger org apache commons beanutils ConvertUtils 出现这个错误 在web inf classes路径下加了log4j properties文件还是这个错误log4j:WARN Please initialize the ...

    log4j.properties

    如果eclipse打印不出日志,在控制台上只...2.log4j:WARNPleaseinitializethelog4jsystemproperly. 3.log4j:WARNSeehttp://logging.apache.org/log4j/1.2/faq.html#noconfigformoreinfo. 就本文件拷贝到src目录下即可。

    log4j的Appenders配置方法

    下面小编就为大家带来一篇log4j的Appenders配置方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    log4j-appenders

    dotcms 中使用的 log4j ASYNC Appender

    logback-more-appenders:额外的Logback附加器

    重新登录更多的appender 是用于其他附加程序,提供更好的性能和数据一致性,而无需担心。 追加者 ... implementation 'com.sndyuk:logback-more-appenders:1.8.6-JAVA9MODULE_SLF4J17' 玛文 &lt;grou

    GFlyway2:适用于Grails的Flyway 2插件

    您需要通过在log4j部分中添加以下代码来修改Config.groovy配置文件: appenders { console name: 'stdout', layout: pattern(conversionPattern: '%m%n') } info 'org.flywaydb' 配置 默认情况下,您应该将sql文件...

    log4j-aws-appenders:写入AWS目标的Log4J 1.2.x,Log4J 2.x和Logback的Appender

    log4j-aws-appenders , 和Appender写入了各种AWS目标: :AWS本地集中式日志管理,提供关键字和时间范围搜索。 :这是向和其他分析目标提供数据的第一步。 :用于实时错误通知。 除了基本的日志输出外,该库还...

    log4js-dingbot

    钉钉log4js附加程序用法log4js.configure({ appenders: { out: { type: 'stdout' }, dingbot: { type: '@ruangnazi/log4js-dingbot', access_token: 'access_token', secret: 'secret', sendInterval: 5 } }, ...

    log4cplus 源码(C++编写的开源的日志系统)

    /* step 4: Instantiate a logger object */ Logger _logger = Logger::getInstance("test"); /* step 5: Attach the appender object to the logger */ _logger.addAppender(_append); /* step 6: Set a ...

    promise-appenders:使用可配置的附加程序扩展Promise的功能

    使用可配置的附加程序扩展Promise的功能。 包含的附加程序: 承诺-基本承诺 log4js-tagline-记录到文件,控制台,... pro_appenders = require ( 'promise-appenders' ) , log , lne , cfu , tcf atst = new pro_ap

    Domino Log4j Appenders-开源

    该项目提供了几个Log4j附加程序,可以从各种上下文(例如servlet,Java客户端,当然还有Domino Java代理)登录Domino数据库。

    quartz log4j

    log4j:WARN No appenders could be found for logger (com.mchange.v2.log.MLog). log4j:WARN Please initialize the log4j system properly.

    Log4j教程.docx

    log4j是一个用Java编写的可靠,快速和灵活的日志框架(API),它在Apache软件许可下发布。...• appenders : 负责发布日志信息,以不同的首选目的地。 • layouts: 负责格式化不同风格的日志信息。

    Log4j日志管理系统简单使用说明

    Log4j有三个主要的组件:Loggers,Appenders和Layouts,这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。综合使用这三个组件可以轻松的记录信息的类型和级别,并可以在运行时控制日志输出的样式和...

    dropwizard-honeybadger:Dropwizard 的插件包以支持登录到 Honeybadger

    您的 YAML 配置可以包含以下代码段来配置HoneybadgerAppender : appenders: - type: console threshold: DEBUG target: stderr - type: honeybadger threshold: INFO apiKey: xxxxx # async: true # maxThread

Global site tag (gtag.js) - Google Analytics