Automic
是一个原子类型包,其中包含了AtomicBoolean,AtomicInteger,AtomicLong等, 原子操作说是这样说的,然而并不是所有的物理机器都支持原子指令,所以不能保证不被阻塞,一般而言,采用的CAS+volatile+native的方法,避免synchronized的使用,如果不支持CAS那就上自旋锁了
接口
log4j
Maven依赖
1 2 3 4 5
| <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
|
log4j.properties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| log4j.rootLogger=all, stdout, logfile
<!--more-->
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %l %F %p %m%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=log/log.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.Append = true log4j.appender.logfile.MaxFileSize=1MB log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %l %F %p %m%n
|
用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.wsx;
import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator;
public class Test { public static void main(String[] args) { Logger logger = Logger.getLogger(Test.class); logger.info("info"); logger.debug(" debug "); logger.debug(" debug "); logger.debug(" debug "); logger.debug(" debug "); logger.debug(" debug "); logger.debug(" debug "); logger.error(" error "); logger.error(" error "); logger.error(" error "); } }
|
SLF4J
log的实现太多了,log4j,logBack,jdklog,以后想换怎么办呢?
Simple Logging Facade for Java
就像和JDBC一样,SLF4J把所有的日志框架连接起来
五个级别
trace,debug,info,warn,error
啥事不干,写下面的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.wsx;
import org.slf4j.LoggerFactory; import org.slf4j.Logger;
public class Test { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(Test.class); logger.trace("trace"); logger.debug("debug"); logger.info("info"); logger.warn("warn"); logger.error("error"); } }
|
得到了
1 2 3 4
| 22:23:01.931 [main] DEBUG com.wsx.Slf4jStudy - debug 22:23:01.940 [main] INFO com.wsx.Slf4jStudy - info 22:23:01.941 [main] WARN com.wsx.Slf4jStudy - warn 22:23:01.941 [main] ERROR com.wsx.Slf4jStudy - error
|
logback
写一个logback.xml
appender 后面是log的名字,再往后是输出位置:文件或者控制台
level后面跟级别,表示输出哪些东西
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <configuration>
<contextName>play_dice</contextName> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender>
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender"> <append>false</append> <encoder> <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <root level="tarce"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> </root> </configuration>
|
简化
注释太烦了,我们给他全删掉,使用下面的vim指令
\v代表字符模式,把所有的特殊字符看着特殊意义
(.|\n)可以匹配所有的字符
{-}是*的非贪婪匹配
1
| %s/\v\<!--(.|\n){-}--\>//g
|
会到logback中
%date是时间,%thread是线程,level是级别,-是左对齐,%logger指名字,%msg是日志输出 %n是换行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <append>false</append> <encoder> <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <root level="tarce"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> </root> </configuration>
|
细节
1
| logger.info("hello {} {} {}","I","am","wsx");
|