diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..081b737 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 数据源本地存储已忽略文件 +/dataSources/ +/dataSources.local.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..7eec3cb --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..a02a35e --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..980588c --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/journal.iml b/.idea/journal.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/journal.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml b/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml new file mode 100644 index 0000000..71b60c6 --- /dev/null +++ b/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml b/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml new file mode 100644 index 0000000..14c00d3 --- /dev/null +++ b/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_11_4.xml b/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_11_4.xml new file mode 100644 index 0000000..0b33870 --- /dev/null +++ b/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_11_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_lmax_disruptor_3_3_7.xml b/.idea/libraries/Maven__com_lmax_disruptor_3_3_7.xml new file mode 100644 index 0000000..c595cd1 --- /dev/null +++ b/.idea/libraries/Maven__com_lmax_disruptor_3_3_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_11.xml b/.idea/libraries/Maven__junit_junit_4_11.xml new file mode 100644 index 0000000..ab6d071 --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_11.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__log4j_log4j_1_2_17.xml b/.idea/libraries/Maven__log4j_log4j_1_2_17.xml new file mode 100644 index 0000000..087f7e4 --- /dev/null +++ b/.idea/libraries/Maven__log4j_log4j_1_2_17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml b/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml new file mode 100644 index 0000000..75cb4f7 --- /dev/null +++ b/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml new file mode 100644 index 0000000..b9d199b --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_12_1.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_12_1.xml new file mode 100644 index 0000000..66c0865 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_12_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_12_1.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_12_1.xml new file mode 100644 index 0000000..8bdb21a --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_12_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_1.xml b/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_1.xml new file mode 100644 index 0000000..2943e31 --- /dev/null +++ b/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 0000000..7aa739f --- /dev/null +++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml b/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml new file mode 100644 index 0000000..f259444 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_20.xml b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_20.xml new file mode 100644 index 0000000..9228a2a --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_20.xml b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_20.xml new file mode 100644 index 0000000..e03d15c --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_4_20.xml b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_4_20.xml new file mode 100644 index 0000000..3c18150 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_4_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_4_20.xml b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_4_20.xml new file mode 100644 index 0000000..4b34807 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_4_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_8_0_M1.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_8_0_M1.xml new file mode 100644 index 0000000..2555696 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_0_M1.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_0_M1.xml new file mode 100644 index 0000000..9bbd56f --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_8_0_M1.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_8_0_M1.xml new file mode 100644 index 0000000..df3b03c --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_8_0_M1.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_8_0_M1.xml new file mode 100644 index 0000000..621f053 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_0_M1.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_0_M1.xml new file mode 100644 index 0000000..b5fd290 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_8_0_M1.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_8_0_M1.xml new file mode 100644 index 0000000..0fcf62a --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml b/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml new file mode 100644 index 0000000..3f0eeb5 --- /dev/null +++ b/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml b/.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml new file mode 100644 index 0000000..2519ac9 --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml new file mode 100644 index 0000000..6c1740b --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml new file mode 100644 index 0000000..eba2faa --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..cfa6f2f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..555b913 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..bd241e7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/JCL/.idea/.gitignore b/JCL/.idea/.gitignore new file mode 100644 index 0000000..081b737 --- /dev/null +++ b/JCL/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 数据源本地存储已忽略文件 +/dataSources/ +/dataSources.local.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/JCL/.idea/compiler.xml b/JCL/.idea/compiler.xml new file mode 100644 index 0000000..aa0a26a --- /dev/null +++ b/JCL/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JCL/.idea/encodings.xml b/JCL/.idea/encodings.xml new file mode 100644 index 0000000..63e9001 --- /dev/null +++ b/JCL/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/JCL/.idea/jarRepositories.xml b/JCL/.idea/jarRepositories.xml new file mode 100644 index 0000000..980588c --- /dev/null +++ b/JCL/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/JCL/.idea/misc.xml b/JCL/.idea/misc.xml new file mode 100644 index 0000000..132404b --- /dev/null +++ b/JCL/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/JCL/JCl.iml b/JCL/JCl.iml new file mode 100644 index 0000000..68f5234 --- /dev/null +++ b/JCL/JCl.iml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/JCL/pom.xml b/JCL/pom.xml new file mode 100644 index 0000000..a526e47 --- /dev/null +++ b/JCL/pom.xml @@ -0,0 +1,75 @@ + + + + 4.0.0 + + com.yunbocheng + JCl + 1.0-SNAPSHOT + + JCl + + http://www.example.com + + + UTF-8 + 1.7 + 1.7 + + + + + junit + junit + 4.11 + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + diff --git a/JCL/src/main/java/com/yunbocheng/App.java b/JCL/src/main/java/com/yunbocheng/App.java new file mode 100644 index 0000000..f065baa --- /dev/null +++ b/JCL/src/main/java/com/yunbocheng/App.java @@ -0,0 +1,13 @@ +package com.yunbocheng; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/JCL/src/main/java/com/yunbocheng/Test.java b/JCL/src/main/java/com/yunbocheng/Test.java new file mode 100644 index 0000000..e368d3f --- /dev/null +++ b/JCL/src/main/java/com/yunbocheng/Test.java @@ -0,0 +1,36 @@ +package com.yunbocheng; + +public class Test extends father { + + private String name = print(); + private int age = create(); + + private static boolean sex = false; + + static { + System.out.println(sex); + System.out.println("p12"); + } + public Test() { + System.out.println("p15"); + } + + public Test(String name, int age) { + this.name = name; + this.age = age; + } + + public String print(){ + System.out.println("p13"); + return null; + } + public int create(){ + System.out.println("p12"); + return 0; + } + + public static void main(String[] args) { + Test test = new Test(); + test = new Test(); + } +} diff --git a/JCL/src/main/java/com/yunbocheng/Test01.java b/JCL/src/main/java/com/yunbocheng/Test01.java new file mode 100644 index 0000000..9a32874 --- /dev/null +++ b/JCL/src/main/java/com/yunbocheng/Test01.java @@ -0,0 +1,9 @@ +package com.yunbocheng; + +import javax.naming.PartialResultException; + +public class Test01 { + public static void main(String[] args) { + father father = new Test(); + } +} diff --git a/JCL/src/main/java/com/yunbocheng/father.java b/JCL/src/main/java/com/yunbocheng/father.java new file mode 100644 index 0000000..eacbcb4 --- /dev/null +++ b/JCL/src/main/java/com/yunbocheng/father.java @@ -0,0 +1,34 @@ +package com.yunbocheng; + +import com.sun.scenario.effect.impl.sw.java.JSWBlend_SRC_OUTPeer; + +public class father { + private String name = print(); + + private String print() { + System.out.println(2); + return null; + } + + private int age = create(); + + private int create() { + return 0; + } + + private static boolean sex = true; + + static { + System.out.println(sex); + System.out.println("1"); + } + + public father() { + System.out.println(5); + } + + public father(String name, int age) { + this.name = name; + this.age = age; + } +} diff --git "a/JCL/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" "b/JCL/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" new file mode 100644 index 0000000..f729d30 --- /dev/null +++ "b/JCL/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" @@ -0,0 +1,72 @@ +package com.yunbocheng; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.jupiter.api.Test; + + +public class 入门案例 { + + @Test + public void test01(){ + /* + * 我们暂时还没有导入第三方的日志框架,例如:log4j + * + * 默认情况下,会使用JUL日志框架做日志的记录操作。 + * + * JUL使用原则: + * 如果有log4j,优先使用log4j + * 如果没有任何第三方日志框架的时候,我们使用的就是这个JUL + * */ + // 注意:这里需要导入的是apache下的这个Log + Log log = LogFactory.getLog(入门案例.class); + log.info("info信息"); + } + + @Test + public void test02(){ + /* + * 导入log4j依赖,继续测试原有程序 + * + * 总结: + * 我们上一个案例,使用的是JUL,但是在集成了log4j环境之后,使用的又是log4j + * 通过测试观察,虽然日志框架发生了变化,但是代码完全没有改变 + * + * 日志门面技术: + * 门面技术是面向接口的开发,不再依赖具体的实现类,减少代码的耦合性。 + * 可以根据实际需求,灵活的切换日志框架 + * 统一的API,方便开发者学习和使用,统一的配置管理便于项目日志的维护工作。 + * + * JCL门面技术使用日志框架源码分析: + * Log接口的4个实现类 + * JDK13 : + * JDK14 : 正常java.util.logging + * Log4j : 我们继承的log4j + * Simple : JCL自带实现类 + * + * (1) 查看jdk14Logger源码证明里面使用的是JUL日志框架 + * (2) 查看Log4JLogger源码证明里面使用的Log4j日志框架 + * + * (3) 观察LogFactory,看看如何加载Logger对象 + * 这是一个抽象类,无法实例化 + * 需要观察其实现类LogFactoryImpl + * (4) 观察LogFactoryImpl + * 真正加载日志实现类的是这个实现类 LogFactoryImpl + * + * LogFactoryImpl在底层遍历我们拥有的日志框架 + * 遍历的是一个数组,这个数组是按照 + * log4j + * jdk14 + * jdk13 + * SimpleLogger + * 的顺序依此遍历的 + * 表示的是,第一个遍历的是log4j,如果有log4j则使用log4j来执行该日志框架 + * 如果没有,则遍历出来第二个日志框架,使用jdk14的JUL日志框架 + * 依此类推。 + * */ + + Log log = LogFactory.getLog(入门案例.class); + log.info("info信息"); + } +} diff --git a/JCL/src/main/resources/log4j.properties b/JCL/src/main/resources/log4j.properties new file mode 100644 index 0000000..0df2a57 --- /dev/null +++ b/JCL/src/main/resources/log4j.properties @@ -0,0 +1,8 @@ +# ???????????????? +log4j.rootLogger = trace,console + +# ??????????? +log4j.appender.console = org.apache.log4j.ConsoleAppender +log4j.appender.console.layout = org.apache.log4j.PatternLayout +log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n + diff --git a/JCL/src/test/java/com/yunbocheng/AppTest.java b/JCL/src/test/java/com/yunbocheng/AppTest.java new file mode 100644 index 0000000..fa0c7ad --- /dev/null +++ b/JCL/src/test/java/com/yunbocheng/AppTest.java @@ -0,0 +1,20 @@ +package com.yunbocheng; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest +{ + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() + { + assertTrue( true ); + } +} diff --git a/JCL/target/classes/log4j.properties b/JCL/target/classes/log4j.properties new file mode 100644 index 0000000..0df2a57 --- /dev/null +++ b/JCL/target/classes/log4j.properties @@ -0,0 +1,8 @@ +# ???????????????? +log4j.rootLogger = trace,console + +# ??????????? +log4j.appender.console = org.apache.log4j.ConsoleAppender +log4j.appender.console.layout = org.apache.log4j.PatternLayout +log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n + diff --git a/JUL/.idea/.gitignore b/JUL/.idea/.gitignore new file mode 100644 index 0000000..081b737 --- /dev/null +++ b/JUL/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 数据源本地存储已忽略文件 +/dataSources/ +/dataSources.local.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/JUL/.idea/compiler.xml b/JUL/.idea/compiler.xml new file mode 100644 index 0000000..2e918d9 --- /dev/null +++ b/JUL/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/dataSources.xml b/JUL/.idea/dataSources.xml new file mode 100644 index 0000000..1672484 --- /dev/null +++ b/JUL/.idea/dataSources.xml @@ -0,0 +1,13 @@ + + + + + mysql.8 + true + 日志 + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3306/log + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/JUL/.idea/encodings.xml b/JUL/.idea/encodings.xml new file mode 100644 index 0000000..259d068 --- /dev/null +++ b/JUL/.idea/encodings.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/jarRepositories.xml b/JUL/.idea/jarRepositories.xml new file mode 100644 index 0000000..980588c --- /dev/null +++ b/JUL/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml b/JUL/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml new file mode 100644 index 0000000..71b60c6 --- /dev/null +++ b/JUL/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml b/JUL/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml new file mode 100644 index 0000000..14c00d3 --- /dev/null +++ b/JUL/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_11_4.xml b/JUL/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_11_4.xml new file mode 100644 index 0000000..0b33870 --- /dev/null +++ b/JUL/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_11_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__com_lmax_disruptor_3_3_7.xml b/JUL/.idea/libraries/Maven__com_lmax_disruptor_3_3_7.xml new file mode 100644 index 0000000..c595cd1 --- /dev/null +++ b/JUL/.idea/libraries/Maven__com_lmax_disruptor_3_3_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__junit_junit_4_11.xml b/JUL/.idea/libraries/Maven__junit_junit_4_11.xml new file mode 100644 index 0000000..ab6d071 --- /dev/null +++ b/JUL/.idea/libraries/Maven__junit_junit_4_11.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__log4j_log4j_1_2_17.xml b/JUL/.idea/libraries/Maven__log4j_log4j_1_2_17.xml new file mode 100644 index 0000000..087f7e4 --- /dev/null +++ b/JUL/.idea/libraries/Maven__log4j_log4j_1_2_17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml b/JUL/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml new file mode 100644 index 0000000..75cb4f7 --- /dev/null +++ b/JUL/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_26.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml b/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml new file mode 100644 index 0000000..b9d199b --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_12_1.xml b/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_12_1.xml new file mode 100644 index 0000000..66c0865 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_12_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_12_1.xml b/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_12_1.xml new file mode 100644 index 0000000..8bdb21a --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_12_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_1.xml b/JUL/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_1.xml new file mode 100644 index 0000000..2943e31 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/JUL/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 0000000..7aa739f --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml b/JUL/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml new file mode 100644 index 0000000..f259444 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_20.xml b/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_20.xml new file mode 100644 index 0000000..9228a2a --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_20.xml b/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_20.xml new file mode 100644 index 0000000..e03d15c --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_4_20.xml b/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_4_20.xml new file mode 100644 index 0000000..3c18150 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_4_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_4_20.xml b/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_4_20.xml new file mode 100644 index 0000000..4b34807 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_4_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_8_0_M1.xml b/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_8_0_M1.xml new file mode 100644 index 0000000..2555696 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_0_M1.xml b/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_0_M1.xml new file mode 100644 index 0000000..9bbd56f --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_8_0_M1.xml b/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_8_0_M1.xml new file mode 100644 index 0000000..df3b03c --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_8_0_M1.xml b/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_8_0_M1.xml new file mode 100644 index 0000000..621f053 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_0_M1.xml b/JUL/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_0_M1.xml new file mode 100644 index 0000000..b5fd290 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_8_0_M1.xml b/JUL/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_8_0_M1.xml new file mode 100644 index 0000000..0fcf62a --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_8_0_M1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml b/JUL/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml new file mode 100644 index 0000000..3f0eeb5 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml b/JUL/.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml new file mode 100644 index 0000000..2519ac9 --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_slf4j_log4j_over_slf4j_1_7_25.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml b/JUL/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml new file mode 100644 index 0000000..6c1740b --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml b/JUL/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml new file mode 100644 index 0000000..eba2faa --- /dev/null +++ b/JUL/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/misc.xml b/JUL/.idea/misc.xml new file mode 100644 index 0000000..88d592a --- /dev/null +++ b/JUL/.idea/misc.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/modules.xml b/JUL/.idea/modules.xml new file mode 100644 index 0000000..a1a77fe --- /dev/null +++ b/JUL/.idea/modules.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/JUL/.idea/uiDesigner.xml b/JUL/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/JUL/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git "a/JUL/src/com/yunbocheng/JUL/JULLogger\344\270\255\347\232\204\347\210\266\345\255\220\345\205\263\347\263\273.java" "b/JUL/src/com/yunbocheng/JUL/JULLogger\344\270\255\347\232\204\347\210\266\345\255\220\345\205\263\347\263\273.java" new file mode 100644 index 0000000..689738c --- /dev/null +++ "b/JUL/src/com/yunbocheng/JUL/JULLogger\344\270\255\347\232\204\347\210\266\345\255\220\345\205\263\347\263\273.java" @@ -0,0 +1,87 @@ +package com.yunbocheng.JUL; + + +import com.sun.scenario.effect.impl.sw.java.JSWBlend_SRC_OUTPeer; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +public class JULLogger中的父子关系 { + + @Test + public void test01(){ + + /* + * Logger之间的父子关系 + * JUL中Logger之间是存在“父子”关系的 + * 但是需要注意的是 :这种父子关系不是我们普遍认为的类之间的继承关系。 + * 这里的父子关系是通过树状机构存储的。 + * */ + + /* + * JUL中的父子之间的关系是通过这种包结构来进行实现的。 + * 从下面的两个logger对象来看 + * 我们可以认为logger1是logger2的父类。(越具体的越是子类) + * */ + + /* + * JUL在初始化的时候会常创建一个顶层的RootLogger作为所有的Logger的父Logger + * 查看源码: + * owner.rootLogger = owner.RootLogger(); + * RootLogger是LogManager的内部类 + * 这个RootLogger对象给定的输出级别是 info + * 所以在没有继承自定的父类的时候,默认继承的就是这个RootLogger父类, + * 并且这个父类的输出级别是info,所以子类继承这个父类的输出级别, + * 子类的输出默认就是info。 + * */ + + // 创建一个父类 + Logger logger1 = Logger.getLogger("com.yunbocheng.JUL"); + // 日志对象的子类 + Logger logger2 = Logger.getLogger("com.yunbocheng.JUL.JULLogger中的父子关系"); + + // 这里使用 getParent()方法来判断 + System.out.println(logger2.getParent() == logger1); // true + /* + * 只要是整体结构比他短的都是它的 父结构 + * */ + + // 这个logger1没有在代码中声明具体的父类,所以此时他的父类是顶级父类 RootLogger。 + // 名称默认是一个空字符串 null + // RootLogger可以被称之为所有的logger对象的顶层logger + System.out.println("logger1的父logger引用为:" + logger1.getParent() + ",名称为:" +logger2.getName() + + "; 父亲的名称为:" + logger1.getParent().getName()); + + // 这个logger2在代码中有声明具体的父类logger对象。所以此时输出的父类是logger1,名称是 com.yunbocheng.JUL + System.out.println("logger2的父logger引用为:" + logger2.getParent() + ",名称为:" +logger2.getName() + + "; 父亲的名称为:" + logger2.getParent().getName()); + + /* + * 父亲所作的设置,也能够同时作用于儿子 + * 对logger1做日志的打印,然后我们使用logger2进行日志的打印。 + * */ + + // 父类做打印的设置 + logger1.setUseParentHandlers(false); + ConsoleHandler handler = new ConsoleHandler(); + SimpleFormatter formatter = new SimpleFormatter(); + handler.setFormatter(formatter); + logger1.addHandler(handler); + logger1.setLevel(Level.ALL); + handler.setLevel(Level.ALL); + + // 儿子做打印的内容 + logger2.severe("server信息"); + logger2.warning("warning信息"); + logger2.info("info信息"); + logger2.config("config信息"); + logger2.fine("fine信息"); + logger2.finer("finer信息"); + logger2.finest("finest信息"); + } +} diff --git "a/JUL/src/com/yunbocheng/JUL/JUL\351\205\215\347\275\256\346\226\207\344\273\266.java" "b/JUL/src/com/yunbocheng/JUL/JUL\351\205\215\347\275\256\346\226\207\344\273\266.java" new file mode 100644 index 0000000..a10ac20 --- /dev/null +++ "b/JUL/src/com/yunbocheng/JUL/JUL\351\205\215\347\275\256\346\226\207\344\273\266.java" @@ -0,0 +1,53 @@ +package com.yunbocheng.JUL; + +import org.junit.Test; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +public class JUL配置文件 { + + @Test + public void text01() throws Exception { + /* + * 以上所有的配置相关的操作,都是一Java硬编码的形式进行的。 + * 我们可以使用更加清晰,更加专业的一种做法,就是配置文件。 + * 如果我们没有自己添加这个配置文件,则会使用系统默认的配置文件。 + * + * 这个配置文件: + * java.home --> 找到jre文件夹 --> lib --> logging.properties + * + * 配置文件中的#代表的注释,可以删除掉。 + * + * */ + /* + * 我们从外部来读取这个配置文件之后就不需要我们在写 释放默认级别、设置输出级别、定义格式等代码。 + * 我们只需要创建一个处理器对象,使用这个处理器对象来读取我们的配置文件信息。 + * 之后我们直接打印想要输出的信息即可。 + * + * */ + // 获取日志管理器对象 + LogManager logManager = LogManager.getLogManager(); + // 获取一个输入流对象,这个对象用来读取我们自定义的配置文件的信息 + // 这个参数就是 自定义的配置文件的路径信息。 + // 如果我们不是自定义的配置文件,那么此时就会使用默认的配置文件,自动进行寻找, + // 不用我们在创建输入流对象。 + InputStream inputStream = new FileInputStream("D:\\test\\logging.properties"); + // 使用这个日志管理器对象来读取自定义的配置文件 + logManager.readConfiguration(inputStream); + + // 获取一个日志记录器对象,这个是日志程序的入口 + Logger logger = Logger.getLogger("com.yunbocheng.JUL.JUL配置文件"); + + logger.severe("server信息"); + logger.warning("warning信息"); + logger.info("info信息"); + logger.config("config信息"); + logger.fine("fine信息"); + logger.finer("finer信息"); + logger.finest("finest信息"); + } +} diff --git "a/JUL/src/com/yunbocheng/JUL/\345\205\245\351\227\250\344\273\245\345\217\212\351\273\230\350\256\244\347\272\247\345\210\253\345\261\225\347\244\272.java" "b/JUL/src/com/yunbocheng/JUL/\345\205\245\351\227\250\344\273\245\345\217\212\351\273\230\350\256\244\347\272\247\345\210\253\345\261\225\347\244\272.java" new file mode 100644 index 0000000..d01cf0e --- /dev/null +++ "b/JUL/src/com/yunbocheng/JUL/\345\205\245\351\227\250\344\273\245\345\217\212\351\273\230\350\256\244\347\272\247\345\210\253\345\261\225\347\244\272.java" @@ -0,0 +1,83 @@ +package com.yunbocheng.JUL; + +import org.junit.Test; +import org.omg.CORBA.INITIALIZE; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * JUL入门案列 + */ +public class 入门以及默认级别展示 { + + @Test + public void Test01(){ + + // 入门案例 + /* + * 日志入口程序 + * java.util.logging.Logger + * */ + // Logger对象的创建方式,不能直接new对象 + // 取得Logger对象的方法参数,需要引入当前类的全路径字符串(我们在这里先这么使用,以后可以根据包结构有Logger父子关系,以后详细介绍) + Logger logger = Logger.getLogger("com.yunbocheng.JUL.入门以及默认级别展示"); + + /* + * 对于日志的输出,有两种方式 + * + * 第一种方法: + * 直接调用日志级别相关的方法,方法中传递日志输出信息 + * 假设现在我们要输出info级别的日志信息。 + * */ + // logger.info("输出info信息1"); + + /* + * 第二种方式: + * 通过调用的log方法,然后在里面通过Level类型来定义日志的级别参数, + * 以及搭配日志输出信息的参数。 + * */ + // logger.log(Level.INFO,"输出info信息2"); + + /* + * 输出学生信息 + * 姓名 + * 年龄 + * */ + + // String name = "zhangsan"; + // int age = 23; + // logger.log(Level.INFO,"学生的姓名为:" + name + ",年龄为:" + age); + + /* + * 对于输出信息中,字符串的拼接弊端很多 + * 1.麻烦 + * 2.程序效率低 + * 3.可读性不强 + * 4.维护成本高 + * + * 我们应该使用动态生成数据的方法,生产日志 + * 使用占位符的方式进行操作。 + * */ + String name = "zhangsan"; + int age = 23; + logger.log(Level.INFO,"学生的姓名:{0},年龄:{1}",new Object[]{name,age}); + + /** + * 通过打印结果,我们可以看到的仅仅是输出了info级别的以及比info级别高的日志信息。 + * 这个高低的判断就取决于Level()方法中的第二个参数的大小。比info级别低的日志信息 + * 没有输出出来,证明了info级别的日志信息,它是系统默认的日志级别,在默认日志级别info的 + * 基础上,打印比他级别高的信息。 + * 此时没有设置打印输出的级别,使用的是默认级别(即info)此时打印的是比info级别高的日志信息 + * 其中包含info级别的日志信息,所以此时只会打印 severe、warning、info + */ + logger.severe("severe信息"); + logger.warning("warining信息"); + logger.info("info信息"); + logger.config("config信息"); + logger.fine("fine信息"); + logger.finer("finer信息"); + logger.finest("finest信息"); + + } +} diff --git "a/JUL/src/com/yunbocheng/JUL/\350\207\252\345\256\232\344\271\211\346\227\245\345\277\227\347\272\247\345\210\253.java" "b/JUL/src/com/yunbocheng/JUL/\350\207\252\345\256\232\344\271\211\346\227\245\345\277\227\347\272\247\345\210\253.java" new file mode 100644 index 0000000..9fa888c --- /dev/null +++ "b/JUL/src/com/yunbocheng/JUL/\350\207\252\345\256\232\344\271\211\346\227\245\345\277\227\347\272\247\345\210\253.java" @@ -0,0 +1,130 @@ +package com.yunbocheng.JUL; + +import org.junit.Test; +import sun.rmi.runtime.Log; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.logging.*; + +public class 自定义日志级别 { + + @Test + public void test02(){ + /* + * 自定义日志级别,也就是改变默认级别info + * */ + + // 日志记录器(日志的入口) + Logger logger = Logger.getLogger("com.yunbocheng.JUL.自定义日志级别"); + + // 将默认的日志打印方式关闭 + // 参数设置为false,我们打印日志的方式就不会按照父logger默认的方式进行操作。 + logger.setUseParentHandlers(false); + + // 处理器Handler + // 在此使用控制台日志处理器,取得处理器对象 + // 这个是将日志信息输出到控制台 + ConsoleHandler handler = new ConsoleHandler(); + // 创建日志格式化组件对象,这个格式是可以任意修改的,这里先使用默认的格式。 + SimpleFormatter formatt = new SimpleFormatter(); + // 在处理器中设置输出格式 + handler.setFormatter(formatt); + // 在记录器中添加处理器 + logger.addHandler(handler); + + // 设置日志的打印级别 + // 此处必须将日志记录器和处理器的级别进行统一设置,才会达到日志显示相应级别的效果 + logger.setLevel(Level.CONFIG); + handler.setLevel(Level.CONFIG); + + logger.severe("severe信息"); + logger.warning("warining信息"); + logger.info("info信息"); + logger.config("config信息"); + logger.fine("fine信息"); + logger.finer("finer信息"); + logger.finest("finest信息"); + + /* + * 此时已经将默认的日志级别改变为config级别,此时打印的是config以及config以上的信息。 + * */ + } + @Test + public void test03() throws IOException { + /* + * 将日志输出到具体的磁盘文件中 + * 这样就相当于是做了日志的持久化操作。 + * */ + + // 获取日志记录器对象,这个是日志的入口 + Logger logger = Logger.getLogger("com.yunbocheng.JUL.自定义日志级别"); + // 关闭默认的日志级别 + logger.setUseParentHandlers(false); + + // 文件日志处理器,配置打印日志的地方 注意这个日志文件的后缀名必须是 .log + FileHandler handler = new FileHandler("E:\\JavaProject\\journal\\Log_information\\myLogTest.log"); + // 使用日志格式化组件 + SimpleFormatter formatter = new SimpleFormatter(); + // 在处理器中设置输出信息格式 + handler.setFormatter(formatter); + // 在记录器中添加处理器 + logger.addHandler(handler); + + // 更改输出的级别 + logger.setLevel(Level.ALL); + handler.setLevel(Level.ALL); + + // 输出信息 + logger.severe("severe信息"); + logger.warning("warining信息"); + logger.info("info信息"); + logger.config("config信息"); + logger.fine("fine信息"); + logger.finer("finer信息"); + logger.finest("finest信息"); + + } + + @Test + public void test04() throws IOException { + + /* + * 同时添加多个处理器 + * 也就是同时控制台和自定义的位置输出日志信息 + * + * */ + + // 创建一个日志记录器(日志的入口) + Logger logger = Logger.getLogger("com.yunbocheng.JUL.自定义日志级别"); + // 释放默认的打印日志信息级别 + logger.setUseParentHandlers(false); + // 创建一个从控制台输出的处理器 + ConsoleHandler handler = new ConsoleHandler(); + // 创建一个从指定位置输出日志信息的文件 + FileHandler handler1 = new FileHandler("E:\\JavaProject\\journal\\Log_information\\myLog.log"); + // 使用日志格式化组件,这个格式是可以任意修改的,这里我们使用的是默认的格式 + SimpleFormatter formatter = new SimpleFormatter(); + // 在处理器中设置输出格式 + handler.setFormatter(formatter); + handler1.setFormatter(formatter); + + // 在记录器中添加处理器 + logger.addHandler(handler); + logger.addHandler(handler1); + + // 设置打印日志的级别,要将记录器与处理器 + logger.setLevel(Level.ALL); + handler.setLevel(Level.CONFIG); + handler1.setLevel(Level.ALL); + + // 在控制台和指定位置进行日志信息的输出 + logger.severe("severe信息"); + logger.warning("warining信息"); + logger.info("info信息"); + logger.config("config信息"); + logger.fine("fine信息"); + logger.finer("finer信息"); + logger.finest("finest信息"); + } +} diff --git "a/JUL/src/com/yunbocheng/JUL/\350\277\275\345\212\240\346\227\245\345\277\227\344\277\241\346\201\257.java" "b/JUL/src/com/yunbocheng/JUL/\350\277\275\345\212\240\346\227\245\345\277\227\344\277\241\346\201\257.java" new file mode 100644 index 0000000..df15326 --- /dev/null +++ "b/JUL/src/com/yunbocheng/JUL/\350\277\275\345\212\240\346\227\245\345\277\227\344\277\241\346\201\257.java" @@ -0,0 +1,18 @@ +package com.yunbocheng.JUL; + +import org.junit.Test; + +public class 追加日志信息 { + + @Test + public void test(){ + /* + * 做文件日志打印,新日志会覆盖掉原来的日志 + * 但是我们在实际开发中想要的追加新的日志。 + * + * 重点 :如果想追加信息,此时只需要在日志配置文件中加入 + * java.util.logging.FileHandler.append = true + * 此时代表追加。 + * */ + } +} diff --git a/Log4j2/Log4j2.iml b/Log4j2/Log4j2.iml new file mode 100644 index 0000000..61b5919 --- /dev/null +++ b/Log4j2/Log4j2.iml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Log4j2/pom.xml b/Log4j2/pom.xml new file mode 100644 index 0000000..ff165a8 --- /dev/null +++ b/Log4j2/pom.xml @@ -0,0 +1,62 @@ + + + + 4.0.0 + + com.yunbocheng + Log4j2 + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.11 + + + + + org.apache.logging.log4j + log4j-core + 2.12.1 + + + + + org.apache.logging.log4j + log4j-api + 2.12.1 + + + + + org.slf4j + slf4j-api + 1.7.25 + + + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.12.1 + + + + + com.lmax + disruptor + 3.3.7 + + + + + + diff --git "a/Log4j2/src/main/java/com/yunbocheng/AsyncLogger\346\226\271\345\274\217\345\256\236\347\216\260\345\205\250\345\261\200\345\210\267\346\226\260.java" "b/Log4j2/src/main/java/com/yunbocheng/AsyncLogger\346\226\271\345\274\217\345\256\236\347\216\260\345\205\250\345\261\200\345\210\267\346\226\260.java" new file mode 100644 index 0000000..0ff1745 --- /dev/null +++ "b/Log4j2/src/main/java/com/yunbocheng/AsyncLogger\346\226\271\345\274\217\345\256\236\347\216\260\345\205\250\345\261\200\345\210\267\346\226\260.java" @@ -0,0 +1,35 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AsyncLogger方式实现全局刷新 { + + @Test + public void test01(){ + /* + * 实现全局异步 + * 全局异步: + * 所有的日志都是异步的日志记录,在配置文件上不用做任何的改动 + * 只需要在类路径 resources 下添加一个properties属性文件,做一步配置即可。 + * 文件名要求是:log4j2.component.properties + * + * */ + + Logger logger = LoggerFactory.getLogger(AsyncLogger方式实现全局刷新.class); + // slf4j 中存在5种日志输出级别,此时使用是slf4j的记录器,而不是log4j2的,所以只能输出slf4j中的五种级别。 + for (int i = 0; i < 100; i++) { + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } + + // 系统业务逻辑 + for (int i = 0; i < 100; i++) { + System.out.println("-----------"); + } + } +} diff --git "a/Log4j2/src/main/java/com/yunbocheng/AsyncLogger\346\226\271\345\274\217\345\256\236\347\216\260\346\267\267\345\220\210\345\274\202\346\255\245.java" "b/Log4j2/src/main/java/com/yunbocheng/AsyncLogger\346\226\271\345\274\217\345\256\236\347\216\260\346\267\267\345\220\210\345\274\202\346\255\245.java" new file mode 100644 index 0000000..9cb6a5e --- /dev/null +++ "b/Log4j2/src/main/java/com/yunbocheng/AsyncLogger\346\226\271\345\274\217\345\256\236\347\216\260\346\267\267\345\220\210\345\274\202\346\255\245.java" @@ -0,0 +1,12 @@ +package com.yunbocheng; + +import org.junit.Test; + +public class AsyncLogger方式实现混合异步 { + @Test + public void test01(){ + /* + * + * */ + } +} diff --git "a/Log4j2/src/main/java/com/yunbocheng/Log4j2\344\270\216SLF4J\350\201\224\345\220\210\344\275\277\347\224\250.java" "b/Log4j2/src/main/java/com/yunbocheng/Log4j2\344\270\216SLF4J\350\201\224\345\220\210\344\275\277\347\224\250.java" new file mode 100644 index 0000000..9d5f270 --- /dev/null +++ "b/Log4j2/src/main/java/com/yunbocheng/Log4j2\344\270\216SLF4J\350\201\224\345\220\210\344\275\277\347\224\250.java" @@ -0,0 +1,35 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Log4j2与SLF4J联合使用 { + @Test + public void test01(){ + /* + * 虽然log4j2也是日志门面,现在市场的主流趋势仍是SLF4J + * 所以我们仍然需要使用SLF4J作为日志门面,搭配log4j2强大的日志实现功能,进行日志的相关操作。 + * + * 配置 SLF4J + log4j2 (最强大的日志搭配框架) + * 1. 在pom.xml文件中导入SLF4J的日志门面 + * 2. 导入log4j的适配器 log4j-slf4j-impl + * 3. 导入log4j2的日志门面 + * 4. 导入log4j2的日志实现 + * + * 这里不仅需要导入 slf4j 的日志门面技术还需要导入 log4j2的日志门面。 + * 执行原理: + * slf4j门面调用的是log4j2的门面,在由log4j2的门面调用log4j2的实现。 + * */ + + // 此时使用的 slf4j门面技术中的类和方法来实现日志信息的输出 + Logger logger = LoggerFactory.getLogger(Log4j2与SLF4J联合使用.class); + // slf4j 中存在5种日志输出级别,此时使用是slf4j的记录器,而不是log4j2的,所以只能输出slf4j中的五种级别。 + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + + } +} diff --git "a/Log4j2/src/main/java/com/yunbocheng/Log4j2\345\237\272\347\241\200\346\240\207\347\255\276.java" "b/Log4j2/src/main/java/com/yunbocheng/Log4j2\345\237\272\347\241\200\346\240\207\347\255\276.java" new file mode 100644 index 0000000..19479b6 --- /dev/null +++ "b/Log4j2/src/main/java/com/yunbocheng/Log4j2\345\237\272\347\241\200\346\240\207\347\255\276.java" @@ -0,0 +1,32 @@ +package com.yunbocheng; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.Test; + +public class Log4j2基础标签 { + @Test + public void test01(){ + /* + * 使用配置文件 + * log4j是参考logback创作出来的,而不是参考log4j创作出来的 + * log4j的配置文件也是xml文件 + * log4j同样是默认加载类路径(resources)下的log4j2.xml文件中的配置。 + * 注意:此时的配置文件叫做 log4j2.xml + * + * 根标签,所以日志相关信息,都是在跟标签中配置的 + * + * 在很标签中,可以加入属性 + * status="debug" 日志框架本身的日志输出级别 + * monitorInterval="5" 自动加载配置文件的间隔时间,不低于5秒 + * 这两个属性名不可以修改。 + * */ + Logger logger = LogManager.getLogger(Log4j2基础标签.class); + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信心"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Log4j2/src/main/java/com/yunbocheng/log4j2\346\227\245\345\277\227\346\213\206\345\210\206.java" "b/Log4j2/src/main/java/com/yunbocheng/log4j2\346\227\245\345\277\227\346\213\206\345\210\206.java" new file mode 100644 index 0000000..e5c4425 --- /dev/null +++ "b/Log4j2/src/main/java/com/yunbocheng/log4j2\346\227\245\345\277\227\346\213\206\345\210\206.java" @@ -0,0 +1,23 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class log4j2日志拆分 { + @Test + public void test01(){ + /* + * 日志文件的拆分 + * */ + Logger logger = LoggerFactory.getLogger(log4j2日志拆分.class); + // slf4j 中存在5种日志输出级别,此时使用是slf4j的记录器,而不是log4j2的,所以只能输出slf4j中的五种级别。 + for (int i = 0; i < 100; i++) { + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } + } +} diff --git "a/Log4j2/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" "b/Log4j2/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" new file mode 100644 index 0000000..7187638 --- /dev/null +++ "b/Log4j2/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" @@ -0,0 +1,24 @@ +package com.yunbocheng; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.Test; + +public class 入门案例 { + + @Test + public void test01(){ + /* + * 这个案例中我们单纯的使用Log4j2 门面+实现 + * 不使用 SLF4J 实现。 + * Log4j2和log4j提供了相同的输出级别。 + * */ + Logger logger = LogManager.getLogger(入门案例.class); + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信心"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Log4j2/src/main/java/com/yunbocheng/\345\274\202\346\255\245\345\256\236\347\216\260\344\275\277\347\224\250AsyncAppender.java" "b/Log4j2/src/main/java/com/yunbocheng/\345\274\202\346\255\245\345\256\236\347\216\260\344\275\277\347\224\250AsyncAppender.java" new file mode 100644 index 0000000..60f44f7 --- /dev/null +++ "b/Log4j2/src/main/java/com/yunbocheng/\345\274\202\346\255\245\345\256\236\347\216\260\344\275\277\347\224\250AsyncAppender.java" @@ -0,0 +1,35 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 异步实现使用AsyncAppender { + @Test + public void test01(){ + /* + * 异步日志使用AsyncAppender的方式 + * + * 1. 添加异步日志依赖 + * 2. 在 log4j.xml配置文件的 Appenders标签中,对于异步进行配置 + * 使用Async标签 + * 3. rootlogger引用Async + * */ + + //日志的记录 + Logger logger = LoggerFactory.getLogger(异步实现使用AsyncAppender.class); + // slf4j 中存在5种日志输出级别,此时使用是slf4j的记录器,而不是log4j2的,所以只能输出slf4j中的五种级别。 + for (int i = 0; i < 100; i++) { + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } + + // 系统业务逻辑 + for (int i = 0; i < 100; i++) { + System.out.println("-----------"); + } + } +} diff --git "a/Log4j2/src/main/java/com/yunbocheng/\346\227\245\345\277\227\346\226\207\344\273\266\350\276\223\345\207\272.java" "b/Log4j2/src/main/java/com/yunbocheng/\346\227\245\345\277\227\346\226\207\344\273\266\350\276\223\345\207\272.java" new file mode 100644 index 0000000..cd60dec --- /dev/null +++ "b/Log4j2/src/main/java/com/yunbocheng/\346\227\245\345\277\227\346\226\207\344\273\266\350\276\223\345\207\272.java" @@ -0,0 +1,22 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 日志文件输出 { + @Test + public void test01(){ + /* + * 使用 log4j2将日志信息输出到指定文件 + * + * 1. 配置xml配置文件 + * */ + Logger logger = LoggerFactory.getLogger(日志文件输出.class); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git a/Log4j2/src/main/resources/log4j2.component.properties b/Log4j2/src/main/resources/log4j2.component.properties new file mode 100644 index 0000000..8c6b568 --- /dev/null +++ b/Log4j2/src/main/resources/log4j2.component.properties @@ -0,0 +1 @@ +# Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \ No newline at end of file diff --git a/Log4j2/src/main/resources/log4j2.xml b/Log4j2/src/main/resources/log4j2.xml new file mode 100644 index 0000000..03f803c --- /dev/null +++ b/Log4j2/src/main/resources/log4j2.xml @@ -0,0 +1,97 @@ + + + + + E://test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Log4j2/target/classes/log4j2.component.properties b/Log4j2/target/classes/log4j2.component.properties new file mode 100644 index 0000000..8c6b568 --- /dev/null +++ b/Log4j2/target/classes/log4j2.component.properties @@ -0,0 +1 @@ +# Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \ No newline at end of file diff --git a/Log4j2/target/classes/log4j2.xml b/Log4j2/target/classes/log4j2.xml new file mode 100644 index 0000000..03f803c --- /dev/null +++ b/Log4j2/target/classes/log4j2.xml @@ -0,0 +1,97 @@ + + + + + E://test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Log4jTest/Log4jTest.iml b/Log4jTest/Log4jTest.iml new file mode 100644 index 0000000..35e855a --- /dev/null +++ b/Log4jTest/Log4jTest.iml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Log4jTest/pom.xml b/Log4jTest/pom.xml new file mode 100644 index 0000000..b687395 --- /dev/null +++ b/Log4jTest/pom.xml @@ -0,0 +1,51 @@ + + + + 4.0.0 + + com.yunbocheng + Log4jTest + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.11 + test + + + + + + mysql + mysql-connector-java + 8.0.26 + + + org.junit.jupiter + junit-jupiter + RELEASE + compile + + + + + log4j + log4j + 1.2.17 + compile + + + + + + + diff --git "a/Log4jTest/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213\344\273\245\345\217\212\346\227\245\345\277\227\347\272\247\345\210\253.java" "b/Log4jTest/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213\344\273\245\345\217\212\346\227\245\345\277\227\347\272\247\345\210\253.java" new file mode 100644 index 0000000..50e8ea1 --- /dev/null +++ "b/Log4jTest/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\344\276\213\344\273\245\345\217\212\346\227\245\345\277\227\347\272\247\345\210\253.java" @@ -0,0 +1,43 @@ +package com.yunbocheng; + + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; +import org.junit.jupiter.api.Test; + + + +public class 入门案例以及日志级别 { + + @Test + public void test01(){ + + /* + * Log4j入门案例 + * */ + + // 记载初始化配置,也就是配置一个处理器 + /* + * 这里可以点击这个configure()方法,可以看到这个方法中获取到一个父类的对象 + * 因为这里没有给定指定的父类,所以默认的继承的是最高父类 + * Logger root = Logger.getRootLogger(); + * + * 并且调用这个方法会创建一个处理器,并且会创建的这个处理器的级别是打印到控制台 + * 还给定一个处理器的打印格式 + * root.addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n"))); + * + * */ + BasicConfigurator.configure(); + // 创建一个日志的入口,也就是记录器,注意此时需要导入的包是apache的包 + // 此时需要使用反射机制来获取这个对象 + Logger logger = Logger.getLogger(入门案例以及日志级别.class); + + // 打印输出信息 + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Log4jTest/src/main/java/com/yunbocheng/\346\227\245\345\277\227\344\277\241\346\201\257\350\276\223\345\207\272\345\210\260\346\226\207\344\273\266.java" "b/Log4jTest/src/main/java/com/yunbocheng/\346\227\245\345\277\227\344\277\241\346\201\257\350\276\223\345\207\272\345\210\260\346\226\207\344\273\266.java" new file mode 100644 index 0000000..1e90133 --- /dev/null +++ "b/Log4jTest/src/main/java/com/yunbocheng/\346\227\245\345\277\227\344\277\241\346\201\257\350\276\223\345\207\272\345\210\260\346\226\207\344\273\266.java" @@ -0,0 +1,77 @@ +package com.yunbocheng; + +import org.apache.log4j.FileAppender; +import org.apache.log4j.Logger; +import org.junit.jupiter.api.Test; + +public class 日志信息输出到文件 { + + @Test + public void test01(){ + /* + * 将日志信息输出到指定文件中 + * 这里我们仍然使用配置文件中的打印格式 + * 以后只要使用log4j就使用配置文件方式,而不使用硬编码方式。 + * + * 之前我们在配置文件中配置的是输出到控制台相关的配置 + * 那么我们可以直接将输出到控制台改变为输出到指定文件。 + * 一般情况下我们也可以做多方向的输出,所以控制台的配置我们保留,但是我们不用。 + * + * */ + /* + * 使用这个输出到指定文件中的日志信息最主要的是定位到这个指定文件的位置。 + * 日志文件要保存到哪个相关的配置 + * 查看FileAppender的源码 + * protected boolean fileAppend; 代表是否追加信息,通过构造方法赋值为true + * protected int bufferSize; 缓冲区大小,通过构造方法赋值 8192 + * + * 使用setFile()方法来指定输出日志文件的位置 + * 通过ognl,可以推断setFile方法操作的属性就是file + * + * 如果有输出中文的需求怎么办? + * 观察 FileAppender 的父类 + * 找到 protected String encoding; 这个属性用来配置编码方式。 + * */ + // 使用该类的反射机制来获取到一个记录器,程序的入口 + Logger logger = Logger.getLogger(日志信息输出到文件.class); + + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } + + @Test + public void test02(){ + /* + * 将日志文件输出到文件中,进行日志信息的拆分。 + * 日志太多了,不方便管理和维护怎么办 + * FileAppender为我们提供了好用的子类来进一步的对于文件输出进行处理 + * RollingFileAppender + * DailyRollingFileAppender + * + * 1. RollingFileAppender + * 这个类是按照文件的大小进行拆分的操作。 + * 首先还是配置文件。 + * 如何进行拆分的,观察RollingFileAppender源码 + * protected long maxFileSize = 10485760L; 代表拆分文件的大小 + * protected int maxBackupIndex = 1; 代表拆分文件的数量 + * + * 2. DailyRollingFileAppender + * 这个类是按照时间来进行文件的拆分 + * 如何进行拆分的,观察RollingFileAppender源码 + * 注意这个前边的单引号。 + * private String datePattern = "'.'yyyy-MM-dd"; 默认是按照天来进行拆分 + * */ + Logger logger = Logger.getLogger(日志信息输出到文件.class); + + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Log4jTest/src/main/java/com/yunbocheng/\346\227\245\345\277\227\346\214\201\344\271\205\345\214\226_\345\260\206\346\225\260\346\215\256\345\255\230\345\202\250\345\210\260\346\225\260\346\215\256\345\272\223.java" "b/Log4jTest/src/main/java/com/yunbocheng/\346\227\245\345\277\227\346\214\201\344\271\205\345\214\226_\345\260\206\346\225\260\346\215\256\345\255\230\345\202\250\345\210\260\346\225\260\346\215\256\345\272\223.java" new file mode 100644 index 0000000..59c5f0e --- /dev/null +++ "b/Log4jTest/src/main/java/com/yunbocheng/\346\227\245\345\277\227\346\214\201\344\271\205\345\214\226_\345\260\206\346\225\260\346\215\256\345\255\230\345\202\250\345\210\260\346\225\260\346\215\256\345\272\223.java" @@ -0,0 +1,32 @@ +package com.yunbocheng; + +import org.apache.log4j.Logger; +import org.junit.jupiter.api.Test; + +public class 日志持久化_将数据存储到数据库 { + + @Test + public void test01(){ + /* + * 日志持久化,将日志持久化数据库表中 + * 第一步 :传创建表结构(字段的指定可以根据需求进行调整) + * CREATE TABLE tal_log( + * id int(11) NOT NULL AUTO_INCREMENT, + * name varchar(255) DEFAULT NULL COMMENT '项目名称', + * createTime varchar(255) DEFAULT NULL COMMENT '创建时间', + * ... + * PRIMARY KEY(id) + * ) + * */ + // 获取记录器对象,就是打印日志信息的入口 + Logger logger = Logger.getLogger(日志持久化_将数据存储到数据库.class); + // 输出日志信息 + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + + } +} diff --git "a/Log4jTest/src/main/java/com/yunbocheng/\350\207\252\345\256\232\344\271\211Logger\351\205\215\347\275\256.java" "b/Log4jTest/src/main/java/com/yunbocheng/\350\207\252\345\256\232\344\271\211Logger\351\205\215\347\275\256.java" new file mode 100644 index 0000000..0d5bb29 --- /dev/null +++ "b/Log4jTest/src/main/java/com/yunbocheng/\350\207\252\345\256\232\344\271\211Logger\351\205\215\347\275\256.java" @@ -0,0 +1,65 @@ +package com.yunbocheng; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.junit.jupiter.api.Test; + +public class 自定义Logger配置 { + + @Test + public void test01(){ + /* + * Log4j自定义的logger + * 我们以前所创建出来的logger对象,默认都是继承rootLogger的 + * 我们也可以自定义logger,让其他logger来继承这个logger。 + * + * 这种继承关系就是按照包结构的关系来进行指定的。 + * 例如:我们一直使用默认的Logger是继承其rootLogger + * Logger logger = Logger.getLogger(日志持久化_将数据存储到数据库.class); + * 这时候获取logger对象的路径是 + * com.yunbocheng.自定义Logger配置 + * 它的父logger就是上层的路径或者是更上层的路径 + * 例如: + * com.yunbocheng + * com + * 参照logger是如何加载配置文件的 + * 查看PropertyConfigurator的源码 + * static final String LOGGER_PREFIX = "log4j.logger."; + * 以上这个属性 log4j.logger. 就是我们在配置文件中对于自定义logger的配置属性 + * */ + /* + # 配置根节点logger + log4j.rootLogger = trace,console + + # 配置自定义logger + log4j.logger.com.yunbocheng = info,file + + 观察结果: + 从输出的位置来看,控制台输出了信息,日志文件也会输出信息。 + 所以可以得出结论,如果根节点的logger和自定义父logger配置的输出位置是不同的 + 则取二者的并集,也就是配置的位置都会进行日志的输出。 + + 如果二者配置的日志级别不同,主要以按照我们自定义的父logger的级别输出为主。 + + + */ + Logger logger = Logger.getLogger(日志持久化_将数据存储到数据库.class); + // 输出日志信息 + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } + + @Test + public void test02(){ + /* + * 自定义logger的应用场景 + * 我们之所以要自定义logger,就是为了针对不同的操作系统信息做更加灵活的输出操作。 + * 例如: + * 我们可以在原有案例的基础之上,加一个apache的日志输出。 + * */ + } +} diff --git "a/Log4jTest/src/main/java/com/yunbocheng/\351\205\215\347\275\256\346\226\207\344\273\266_\350\276\223\345\207\272\345\210\260\346\216\247\345\210\266\345\217\260.java" "b/Log4jTest/src/main/java/com/yunbocheng/\351\205\215\347\275\256\346\226\207\344\273\266_\350\276\223\345\207\272\345\210\260\346\216\247\345\210\266\345\217\260.java" new file mode 100644 index 0000000..3dff5bb --- /dev/null +++ "b/Log4jTest/src/main/java/com/yunbocheng/\351\205\215\347\275\256\346\226\207\344\273\266_\350\276\223\345\207\272\345\210\260\346\216\247\345\210\266\345\217\260.java" @@ -0,0 +1,89 @@ +package com.yunbocheng; + +import org.apache.log4j.Logger; +import org.apache.log4j.helpers.LogLog; +import org.junit.jupiter.api.Test; + + +public class 配置文件_输出到控制台 { + + /* + * 配置文件的使用 + * + * 1. 观察源码 BasicConfigurator.configure(); + * 可以得到两条信息: + * (1)创建了根节点的对象, Logger root = Logger.getRootLogger(); + * (2)根节点添加了ConsoleAppender对象(表示默认打印到控制台,自定义的格式输出) + * 2. 我们这一次,不使用这个默认的处理器 BasicConfigurator.configure(); + * 自定义的配置文件来实现功能 + * 通过我们对于以上第一点的分析,我们的配置文件需要提供Logger、Appender、Layout + * 这3个组件的信息(通过配置来代替以上的代码) + * 3. 分析: + * Logger logger = Logger.getLogger(配置文件.class); + * 进入getManager.getLogger(class.getName()); + * LogManager :日志管理器 + * + * 点击LogManage,看看这个日志管理器中都实现了什么 + * 可以发现里边有很多的常量信息,他们代表的就是不同形式(后缀名不同)的配置文件 + * 我们最常见的就是log4j.properties属性文件(语法简单,使用方便) + * + * 4. log4j.properties属性文件的加载时机 + * 继续观察LogManager,找到其中的静态代码块static + * 在static静态代码块中,我们可以找到 + * Loader.getResource("log4j.properties"); + * 这行代码给我们的最大的一个提示信息就是 + * 系统默认要从当前的类路径下找到log4j.properties + * 对于我们当前的项目是Maven工程,那么这个根路径是 resources 下 + * + * */ + @Test + public void test01(){ + Logger logger = Logger.getLogger(配置文件_输出到控制台.class); + // 打印输出信息 + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } + + @Test + public void test02(){ + /* + * 日志输出详细信息的开关 + * */ + + // 打开输出详细日志信息 + LogLog.setInternalDebugging(true); + Logger logger = Logger.getLogger(配置文件_输出到控制台.class); + // 打印输出信息 + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } + + @Test + public void test03(){ + /* + * 关于log4j.properties layout属性的配置 + * 这个配置的是日志输出的格式 + * 这个输出格式 也是在Log4j的配置文件中修改。 + * 最长使用的是自定义的输出格式 即 PatternLayout + * + * 这个时候需要修改log4j.properties文件中的日志信息输出格式。 + * 需要在默认输出的配置文件下加入一行自定义格式的输出日志格式信息。 + * */ + Logger logger = Logger.getLogger(配置文件_输出到控制台.class); + // 添加打印信息 + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git a/Log4jTest/src/main/resources/log4j.properties b/Log4jTest/src/main/resources/log4j.properties new file mode 100644 index 0000000..ccdca9d --- /dev/null +++ b/Log4jTest/src/main/resources/log4j.properties @@ -0,0 +1,50 @@ +# ????????????????????????? +# ??????rootLogger??logger??????????logger????? +log4j.rootLogger = trace,console + +# ?????logger????????????logger ????? +log4j.logger.com.yunbocheng = info,file + +# ??????????? +log4j.appender.console = org.apache.log4j.ConsoleAppender +log4j.appender.console.layout = org.apache.log4j.PatternLayout +log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n + +# ???????????? +log4j.appender.file = org.apache.log4j.FileAppender +log4j.appender.file.layout = org.apache.log4j.PatternLayout +log4j.appender.file.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +# ???????????? +log4j.appender.file.file = E://log4j.log +# ?????????????? +log4j.appender.file.encoding = UTF-8 + +# ???????????? +log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender +log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout +log4j.appender.rollingFile.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +log4j.appender.rollingFile.file = E://log4j.log +log4j.appender.rollingFile.encoding = UTF-8 +# ??????????? +log4j.appender.rollingFiler.maxFileSize = 1MB +# ??????? +log4j.appender.rollingFiler.maxBackupIndex = 5 + +# ?????????? +log4j.appender.dailyRollingFile = org.apache.log4j.DailyRollingFileAppender +log4j.appender.dailyRollingFile.layout = org.apache.log4j.PatternLayout +log4j.appender.dailyRollingFile.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +log4j.appender.dailyRollingFile.file = E://log4j.log +log4j.appender.dailyRollingFile.encoding = UTF-8 +# ???????????????????????? +appender.dailyRollingFile.datePattern = '.'yyyy-MM-dd HH:mm:ss + +# ??????? ??????????? +log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender +log4j.appender.logDB.layout = org.apache.log4j.PatternLayout +log4j.appender.logDB.Driver = com.mysql.jdbc.Driver +log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/log +log4j.appender.logDB.User = root +log4j.appender.logDB.Password = 567cybtfboys +# ???????????????insert?? +log4j.appender.logDB.Sql = INSERT INTO tab_log(name,create,level,category,fileName,message) values('project_log','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%m') diff --git a/Log4jTest/target/classes/log4j.properties b/Log4jTest/target/classes/log4j.properties new file mode 100644 index 0000000..ccdca9d --- /dev/null +++ b/Log4jTest/target/classes/log4j.properties @@ -0,0 +1,50 @@ +# ????????????????????????? +# ??????rootLogger??logger??????????logger????? +log4j.rootLogger = trace,console + +# ?????logger????????????logger ????? +log4j.logger.com.yunbocheng = info,file + +# ??????????? +log4j.appender.console = org.apache.log4j.ConsoleAppender +log4j.appender.console.layout = org.apache.log4j.PatternLayout +log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n + +# ???????????? +log4j.appender.file = org.apache.log4j.FileAppender +log4j.appender.file.layout = org.apache.log4j.PatternLayout +log4j.appender.file.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +# ???????????? +log4j.appender.file.file = E://log4j.log +# ?????????????? +log4j.appender.file.encoding = UTF-8 + +# ???????????? +log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender +log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout +log4j.appender.rollingFile.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +log4j.appender.rollingFile.file = E://log4j.log +log4j.appender.rollingFile.encoding = UTF-8 +# ??????????? +log4j.appender.rollingFiler.maxFileSize = 1MB +# ??????? +log4j.appender.rollingFiler.maxBackupIndex = 5 + +# ?????????? +log4j.appender.dailyRollingFile = org.apache.log4j.DailyRollingFileAppender +log4j.appender.dailyRollingFile.layout = org.apache.log4j.PatternLayout +log4j.appender.dailyRollingFile.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +log4j.appender.dailyRollingFile.file = E://log4j.log +log4j.appender.dailyRollingFile.encoding = UTF-8 +# ???????????????????????? +appender.dailyRollingFile.datePattern = '.'yyyy-MM-dd HH:mm:ss + +# ??????? ??????????? +log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender +log4j.appender.logDB.layout = org.apache.log4j.PatternLayout +log4j.appender.logDB.Driver = com.mysql.jdbc.Driver +log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/log +log4j.appender.logDB.User = root +log4j.appender.logDB.Password = 567cybtfboys +# ???????????????insert?? +log4j.appender.logDB.Sql = INSERT INTO tab_log(name,create,level,category,fileName,message) values('project_log','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%m') diff --git a/Logback/Logback.iml b/Logback/Logback.iml new file mode 100644 index 0000000..2710329 --- /dev/null +++ b/Logback/Logback.iml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Logback/pom.xml b/Logback/pom.xml new file mode 100644 index 0000000..07d8707 --- /dev/null +++ b/Logback/pom.xml @@ -0,0 +1,43 @@ + + + + 4.0.0 + + com.yunbocheng + Logback + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.11 + + + + + org.slf4j + slf4j-api + 1.7.29 + + + + + ch.qos.logback + logback-classic + 1.2.3 + test + + + + + + + diff --git "a/Logback/src/main/java/com/yunbocheng/Logback\351\205\215\347\275\256\346\226\207\344\273\266.java" "b/Logback/src/main/java/com/yunbocheng/Logback\351\205\215\347\275\256\346\226\207\344\273\266.java" new file mode 100644 index 0000000..75594f6 --- /dev/null +++ "b/Logback/src/main/java/com/yunbocheng/Logback\351\205\215\347\275\256\346\226\207\344\273\266.java" @@ -0,0 +1,23 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Logback配置文件 { + @Test + public void test01(){ + /* + * Logback配置文件的使用 + * 在resources下创建一个logback.xml文件,这个配置文件可以自动读取出来。 + * */ + + // 使用slf4j门面技术来获取一个logback日志记录器 + Logger logger = LoggerFactory.getLogger(Logback配置文件.class); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Logback/src/main/java/com/yunbocheng/\344\275\277\347\224\250\350\277\207\346\273\244\345\231\250\346\233\264\347\273\206\347\262\222\345\272\246\347\232\204\346\211\223\345\215\260\346\227\245\345\277\227.java" "b/Logback/src/main/java/com/yunbocheng/\344\275\277\347\224\250\350\277\207\346\273\244\345\231\250\346\233\264\347\273\206\347\262\222\345\272\246\347\232\204\346\211\223\345\215\260\346\227\245\345\277\227.java" new file mode 100644 index 0000000..d79c586 --- /dev/null +++ "b/Logback/src/main/java/com/yunbocheng/\344\275\277\347\224\250\350\277\207\346\273\244\345\231\250\346\233\264\347\273\206\347\262\222\345\272\246\347\232\204\346\211\223\345\215\260\346\227\245\345\277\227.java" @@ -0,0 +1,20 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 使用过滤器更细粒度的打印日志 { + @Test + public void test01(){ + /* + * 使用过滤器更细粒度的打印日志信息 + * */ + Logger logger = LoggerFactory.getLogger(使用过滤器更细粒度的打印日志.class); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Logback/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\345\210\227.java" "b/Logback/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\345\210\227.java" new file mode 100644 index 0000000..e034439 --- /dev/null +++ "b/Logback/src/main/java/com/yunbocheng/\345\205\245\351\227\250\346\241\210\345\210\227.java" @@ -0,0 +1,28 @@ +package com.yunbocheng; + + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 入门案列 { + + @Test + public void test01(){ + /* + * 入门案例: + * logback有5个级别的日志输出格式 + * trace(追踪信息) < debug(普通信息) < info(重要信息) < warn(警告信息) < error(错误信息) + * logback默认的打印级别是:debug + * + * */ + // 这里我们还是使用slf4j的门面技术来实现logback + Logger logger = LoggerFactory.getLogger(入门案列.class); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + + } +} diff --git "a/Logback/src/main/java/com/yunbocheng/\345\260\206\346\227\245\345\277\227\344\277\241\346\201\257\346\211\223\345\215\260\345\210\260\346\214\207\345\256\232\346\226\207\344\273\266.java" "b/Logback/src/main/java/com/yunbocheng/\345\260\206\346\227\245\345\277\227\344\277\241\346\201\257\346\211\223\345\215\260\345\210\260\346\214\207\345\256\232\346\226\207\344\273\266.java" new file mode 100644 index 0000000..191e431 --- /dev/null +++ "b/Logback/src/main/java/com/yunbocheng/\345\260\206\346\227\245\345\277\227\344\277\241\346\201\257\346\211\223\345\215\260\345\210\260\346\214\207\345\256\232\346\226\207\344\273\266.java" @@ -0,0 +1,26 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 将日志信息打印到指定文件 { + + @Test + public void test01(){ + /* + * 将日志信息打印到文件中 + * 只需要修改 main-->resources下的logback.xml文件配置即可 + * + * + * 还可以同时在多个位置打印日志信息(控制台、文件) + * 打印到文件中默认是以追加的方法打印的 + * */ + Logger logger = LoggerFactory.getLogger(将日志信息打印到指定文件.class); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Logback/src/main/java/com/yunbocheng/\345\274\202\346\255\245\346\227\245\345\277\227.java" "b/Logback/src/main/java/com/yunbocheng/\345\274\202\346\255\245\346\227\245\345\277\227.java" new file mode 100644 index 0000000..bdb0fe3 --- /dev/null +++ "b/Logback/src/main/java/com/yunbocheng/\345\274\202\346\255\245\346\227\245\345\277\227.java" @@ -0,0 +1,29 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 异步日志 { + @Test + public void test01(){ + /* + * 在实际的开发中,我们需要将日志信息与系统信息同时打印输出 + * 也就是多线程 + * */ + // 打印日志信息 + Logger logger = LoggerFactory.getLogger(异步日志.class); + for (int i = 0; i < 1000; i++) { + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } + + // 打印系统信息 + System.out.println(1); + System.out.println(2); + System.out.println(3); + } +} diff --git "a/Logback/src/main/java/com/yunbocheng/\346\227\245\345\277\227\347\232\204\346\213\206\345\210\206\345\222\214\345\275\222\346\241\243\346\223\215\344\275\234.java" "b/Logback/src/main/java/com/yunbocheng/\346\227\245\345\277\227\347\232\204\346\213\206\345\210\206\345\222\214\345\275\222\346\241\243\346\223\215\344\275\234.java" new file mode 100644 index 0000000..f5502ee --- /dev/null +++ "b/Logback/src/main/java/com/yunbocheng/\346\227\245\345\277\227\347\232\204\346\213\206\345\210\206\345\222\214\345\275\222\346\241\243\346\223\215\344\275\234.java" @@ -0,0 +1,21 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 日志的拆分和归档操作 { + @Test + public void test01(){ + /* + * 日志文档的拆分及归档压缩 + * + * */ + Logger logger = LoggerFactory.getLogger(日志的拆分和归档操作.class); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Logback/src/main/java/com/yunbocheng/\346\227\245\345\277\227\350\276\223\345\207\272\344\270\272html\346\226\207\344\273\266.java" "b/Logback/src/main/java/com/yunbocheng/\346\227\245\345\277\227\350\276\223\345\207\272\344\270\272html\346\226\207\344\273\266.java" new file mode 100644 index 0000000..5debe4d --- /dev/null +++ "b/Logback/src/main/java/com/yunbocheng/\346\227\245\345\277\227\350\276\223\345\207\272\344\270\272html\346\226\207\344\273\266.java" @@ -0,0 +1,23 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 日志输出为html文件 { + @Test + public void test01(){ + /* + * 将日志输出成为一个html文件 + * + * 这个html文件是由logback来帮我们控制样式和格式 + * 内容由我们自己来定义。 + * */ + Logger logger = LoggerFactory.getLogger(日志输出为html文件.class); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/Logback/src/main/java/com/yunbocheng/\350\207\252\345\256\232\344\271\211logger.java" "b/Logback/src/main/java/com/yunbocheng/\350\207\252\345\256\232\344\271\211logger.java" new file mode 100644 index 0000000..9f20ed6 --- /dev/null +++ "b/Logback/src/main/java/com/yunbocheng/\350\207\252\345\256\232\344\271\211logger.java" @@ -0,0 +1,18 @@ +package com.yunbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class 自定义logger { + @Test + public void test01(){ + Logger logger = LoggerFactory.getLogger(日志输出为html文件.class); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git a/Logback/src/main/resources/logback.xml b/Logback/src/main/resources/logback.xml new file mode 100644 index 0000000..8bebcae --- /dev/null +++ b/Logback/src/main/resources/logback.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + ${logDir}/logback.log + + + + ${pattern} + + + + + + + ${logDir}/logback.html + + + + ${pattern} + + + + + + + + + + + + System.err + + + + + + + + ${pattern} + + + + + + + + + ${pattern} + + + ${logDir}/roll_logback.log + + + + + + + ${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz + + + 1KB + + + + + + + + + + + System.err + + + + + ${pattern} + + + + + + + WARN + + + ACCEPT + + + DENY + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Logback/target/classes/logback.xml b/Logback/target/classes/logback.xml new file mode 100644 index 0000000..8bebcae --- /dev/null +++ b/Logback/target/classes/logback.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + ${logDir}/logback.log + + + + ${pattern} + + + + + + + ${logDir}/logback.html + + + + ${pattern} + + + + + + + + + + + + System.err + + + + + + + + ${pattern} + + + + + + + + + ${pattern} + + + ${logDir}/roll_logback.log + + + + + + + ${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz + + + 1KB + + + + + + + + + + + System.err + + + + + ${pattern} + + + + + + + WARN + + + ACCEPT + + + DENY + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index a7c574a..9a5f3f9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,97 @@ -# Journal -Java日志 +# Java日志框架 + +
+ +
+ + +
+ +
+ + + + + +
+ +
+ +## 一、Java日志框架家族 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/%E6%97%A5%E5%BF%97.jpg) + +## 二、Java日志依赖 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/%E6%97%A5%E5%BF%97%E6%A1%86%E6%9E%B6.png) + +## 三、清单 + +### 2.JUL + +- [入门案例以及默认级别](./JUL/src/com/yunbocheng/JUL/入门以及默认级别展示.java) +- [JUL配置文件](./JUL/src/com/yunbocheng/JUL/JUL配置文件.java) +- [自定义日志级别](./JUL/src/com/yunbocheng/JUL/追加日志信息.java) +- [JUL-Logger中的父子关系](./JUL/src/com/yunbocheng/JUL/JULLogger中的父子关系.java) +- [追加日志信息](./JUL/src/com/yunbocheng/JUL/追加日志信息.java) + + +### 1.Log4j + +- [Log4j配置文件](E:\JavaProject\journal\Log4jTest\src\main\resources\log4j.properties) +- [入门案例以及日志级别](./src/main/java/com/yunbocheng/入门案例以及日志级别.java) +- [日志信息输出到文件](./com/yunbocheng/日志信息输出到文件.java) +- [配置文件-输出到控制台](./com/yunbocheng/配置文件_输出到控制台.java) +- [配置文件-输出到控制台](./com/yunbocheng/配置文件_输出到控制台.java) + + +### 3. jQuery + + +- [第一个jQuery网页](./JQuery语法以及测试程序/src/jqury/第一个jQuery网页.html) +- [DOM对象转化为jQuery对象](./JQuery语法以及测试程序/src/jqury/DOM对象转化为jQuery对象.html) +- [jQuery对象转换为DOM对象](./JQuery语法以及测试程序/src/jqury/jQuery对象转换为DOM对象.html) +- [jQuery绑定事件与基本过滤器](./JQuery语法以及测试程序/src/jqury/jQuery绑定事件与基本过滤器.html) +- [on 事件绑定](./JQuery语法以及测试程序/src/jqury/on事件绑定.html) +- [表单对象属性过滤器](./JQuery语法以及测试程序/src/jqury/表单对象属性过滤器.html) +- [表单选择器与jQuery函数](./JQuery语法以及测试程序/src/jqury/表单选择器与jQuery函数.html) +- [jQuery库函数hide函数等](./JQuery语法以及测试程序/src/jqury/jQuery库函数hide函数等.html) +- [JQuery概念](./JQuery概念.md) +- [jQuery思维导图](./jQuery思维导图.pdf) +- [jQuery官方文档](./JQuery语法以及测试程序/src/jqury/jquery-3.6.0.js) + +### 4.省市级联查询项目 + +- [省市级联查询](./Jquery和Ajax实现省市级联查询) + +## 四、参考文献 + +W3C在线文档 : + +> - [W3C官方文档](https://tomcat.apache.org/tomcat-5.5-doc/servletapi/) + +## 五、反馈及改进 + +如果您在学习的时候遇到了任何问题,或者清单有任何可以改进的地方, + +非常欢迎提出issues,看到就会回馈.并且将您添加到项目贡献者列表中。 + +## 六、参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request,填写必要信息。 +5. 等待审核即可。通过之后会邮件通知您。 + +## 七、许可证 + +在 MIT 许可下分发。有关更多信息,请参阅[`LICENSE`](./LICENSE)。 + +## 八、致谢 + +> 1. 感谢动力节点提供的Ajax在线课程视频资料 [Ajax在线课程](https://www.bilibili.com/video/BV15k4y167XM) +> 2. 感谢动力节点提供的JQuery在线课程视频资料 [JQuery在线课程](https://www.bilibili.com/video/BV1Jg4y1B7n4) +> 2. 感谢JetBrains提供的配套开发环境许可证 [官方网站](https://www.jetbrains.com/) +> 3. 感谢Gitee提供的图床平台 [相关地址](https://gitee.com/YunboCheng/imageBad) + diff --git a/SLF4J/SLF4J.iml b/SLF4J/SLF4J.iml new file mode 100644 index 0000000..549de88 --- /dev/null +++ b/SLF4J/SLF4J.iml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SLF4J/pom.xml b/SLF4J/pom.xml new file mode 100644 index 0000000..d7045d9 --- /dev/null +++ b/SLF4J/pom.xml @@ -0,0 +1,85 @@ + + + + 4.0.0 + + com.yumbocheng + SLF4J + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.11 + + + + + + + + org.slf4j + slf4j-api + 1.7.29 + + + + + ch.qos.logback + logback-classic + 1.2.3 + test + + + + + org.slf4j + log4j-over-slf4j + 1.7.25 + + + + + + + + + + + + + + + + + + diff --git "a/SLF4J/src/main/java/com/yumbocheng/SFL4J\346\227\245\345\277\227\351\233\206\346\210\220\347\232\204\345\210\206\347\261\273.java" "b/SLF4J/src/main/java/com/yumbocheng/SFL4J\346\227\245\345\277\227\351\233\206\346\210\220\347\232\204\345\210\206\347\261\273.java" new file mode 100644 index 0000000..8f9f188 --- /dev/null +++ "b/SLF4J/src/main/java/com/yumbocheng/SFL4J\346\227\245\345\277\227\351\233\206\346\210\220\347\232\204\345\210\206\347\261\273.java" @@ -0,0 +1,34 @@ +package com.yumbocheng; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SFL4J日志集成的分类 { + + @Test + public void test01(){ + /* + * 测试一:pom.xml中存在slf4j与logback + * pom.xml文件种存在多个日志框架,测试使用框架的顺序 + * 如果在pom.xml文件种存在多个日志框架,默认使用先导入的日志框架实现(也就是谁在最上边就先打印谁) + * 不论谁在上下,只要存在多个日志框架,那么都会报错 + * ( Class path contains multiple SLF4J bindings ) + * + * 测试二:pom.xml文件中删除slf4j文件,只留下logback框架。 + * 留下logback框架,此时打印的日志信息是黑色的,这个是logback的风格, + * 此时不会在出现报错信息。 + * + * 通过测试,我们发现修改了底层的日志框架,但是源代码完全没有改变。 + * + * */ + + Logger loggr = LoggerFactory.getLogger(打印异常信息.class); + try { + // 以下代码会打印的错误信息是 : ClassNotFoundException(找不到指定的类) + Class.forName("aaa"); + } catch (ClassNotFoundException e) { + loggr.info("xxx类中的xxx方法出现了异常"); + loggr.info("错误信息是:", e); + } + } +} diff --git "a/SLF4J/src/main/java/com/yumbocheng/SLF4J\351\233\206\346\210\220JUL.java" "b/SLF4J/src/main/java/com/yumbocheng/SLF4J\351\233\206\346\210\220JUL.java" new file mode 100644 index 0000000..9c191fd --- /dev/null +++ "b/SLF4J/src/main/java/com/yumbocheng/SLF4J\351\233\206\346\210\220JUL.java" @@ -0,0 +1,29 @@ +package com.yumbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SLF4J集成JUL { + + @Test + public void test01(){ + /* + * 我们使用SLF4J来集成JUL日志框架 + * 这个也是SLF4J之前的日志框架,此时需要适配器 + * 此时需要的适配器是 z + * + * 适配器导入之后,JUL日志的实现不用导入依赖的 + * 因为JUL是jdk内置的,不需要额外的导入 + * + * 从结果看是JUL日志打印的,默认是info级别的输出的。 + * */ + Logger logger = LoggerFactory.getLogger(SLF4J集成log4j的方法.class); + // 打印输出信息 + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/SLF4J/src/main/java/com/yumbocheng/SLF4J\351\233\206\346\210\220log4j\347\232\204\346\226\271\346\263\225.java" "b/SLF4J/src/main/java/com/yumbocheng/SLF4J\351\233\206\346\210\220log4j\347\232\204\346\226\271\346\263\225.java" new file mode 100644 index 0000000..78fcff6 --- /dev/null +++ "b/SLF4J/src/main/java/com/yumbocheng/SLF4J\351\233\206\346\210\220log4j\347\232\204\346\226\271\346\263\225.java" @@ -0,0 +1,41 @@ +package com.yumbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class SLF4J集成log4j的方法 { + + @Test + public void test01(){ + /* + * 绑定log4j + * 由于log4j是在slf4j之前出品的日志框架实现 + * 所以并没有遵循slf4j的API规范。 + * + * 此时我们需要绑定一个适配器 slf4j-log4j12 + * 此时运行会发现: + * log4j:WARN No appenders could be found for logger + * 这就说明我们此时使用的日志框架是log4j + * 此时我们就可以按照log4j的日志框架那样的操作 + * 导入配置文件。 + * + * 重点:这个时候我们可以看到上边导入的包文件,全部都是 slf4j 中的类或者接口 + * 完全没有使用到这个 log4j 包,这些工作都是通过在pom.xml文件中添加依赖的完成的。 + * 此时就非常完美的使用门面技术来实现了这个log4j代码,而且此时不需要修改源代码 + * 只需要在pom.xml文件中添加实现logback的依赖即可实现logback日志框架,打印出logback日志信息。 + * + * 我们虽然顶层使用的是log4j做的打印,但是从当前代码使用来看 + * 我们其实使用的仍然是slf4j日志门面,至于日志是log4打印的(或者是logback打印的) + * 都是由slf4j进行操作的,我们不关心。 + * */ + Logger logger = LoggerFactory.getLogger(SLF4J集成log4j的方法.class); + // 打印输出信息 + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} diff --git "a/SLF4J/src/main/java/com/yumbocheng/sfl4j_nop\347\246\201\346\255\242\346\227\245\345\277\227\346\211\223\345\215\260.java" "b/SLF4J/src/main/java/com/yumbocheng/sfl4j_nop\347\246\201\346\255\242\346\227\245\345\277\227\346\211\223\345\215\260.java" new file mode 100644 index 0000000..44d10cd --- /dev/null +++ "b/SLF4J/src/main/java/com/yumbocheng/sfl4j_nop\347\246\201\346\255\242\346\227\245\345\277\227\346\211\223\345\215\260.java" @@ -0,0 +1,32 @@ +package com.yumbocheng; + + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class sfl4j_nop禁止日志打印 { + + @Test + public void test01(){ + /* + * 使用log4j-nop + * 表示不记录日志 + * 在我们使用slf4j-nop的时候 + * 首先还是需要向pom.xml文件中导入实现类依赖 + * 这个实现依赖,根据simple与logback属于同一级别。 + * 所以如果想让这个nop发挥效果,禁止所有日志的打印 + * 那么就必须将这个slf4j-nop的依赖放在所有日志依赖的上方 + * */ + + Logger logger = LoggerFactory.getLogger(sfl4j_nop禁止日志打印.class); + + try { + // 以下代码会打印的错误信息是 : ClassNotFoundException(找不到指定的类) + Class.forName("aaa"); + } catch (ClassNotFoundException e) { + logger.info("xxx类中的xxx方法出现了异常"); + logger.info("错误信息是:", e); + } + } +} diff --git "a/SLF4J/src/main/java/com/yumbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" "b/SLF4J/src/main/java/com/yumbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" new file mode 100644 index 0000000..3534f5c --- /dev/null +++ "b/SLF4J/src/main/java/com/yumbocheng/\345\205\245\351\227\250\346\241\210\344\276\213.java" @@ -0,0 +1,55 @@ +package com.yumbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.slf4j.LoggerFactory.*; + +public class 入门案例 { + + @Test + public void test01(){ + + /* + * 入门案例: + * SLF4J : 对日志划分的级别 + * + * trace : 日志追踪信息 + * debug : 日志详细信息 + * info : 日志的关键信息 (默认的打印级别) + * warn : 日志警告信息 + * error : 日志错误信息 + * + * 在没有任何其他日志实现框架的基础之上 + * SLF4J使用的就是自带的框架slf4j-simple + * slf4j-simple也必须以单独依赖的形式导入进来。 + * */ + // 注意:这里使用的包是SLF4J的 + Logger logger = LoggerFactory.getLogger(入门案例.class); + logger.trace("trace信息"); + logger.debug("debug信息"); + logger.info("info信息"); + logger.warn("warn信息"); + logger.error("error信息"); + + } + + @Test + public void test02(){ + /* + * 我们输出动态的信息时,可以使用占位符的形式来代替字符串的拼接 + * + * + * */ + Logger logger = LoggerFactory.getLogger(入门案例.class); + String name = "张三"; + int age = 10; + // 以下是使用字符串拼接的形式打印信息,很麻烦 + // logger.info("姓名为:" + name + ",年龄为:" + age); + + // 现在使用占位符来动态输出这个信息 + // logger.info("学生信息-姓名:{},年龄:{}",new Object[]{name,age}); + logger.info("学生信息-姓名:{},年龄:{}",name,age); + } +} diff --git "a/SLF4J/src/main/java/com/yumbocheng/\346\211\223\345\215\260\345\274\202\345\270\270\344\277\241\346\201\257.java" "b/SLF4J/src/main/java/com/yumbocheng/\346\211\223\345\215\260\345\274\202\345\270\270\344\277\241\346\201\257.java" new file mode 100644 index 0000000..f03a46d --- /dev/null +++ "b/SLF4J/src/main/java/com/yumbocheng/\346\211\223\345\215\260\345\274\202\345\270\270\344\277\241\346\201\257.java" @@ -0,0 +1,43 @@ +package com.yumbocheng; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class 打印异常信息 { + + @Test + public void test01(){ + /* + * 一般情况下,我们的异常信息都是记录在控制台上(这是我们开发环境的一种日志打印方式) + * 我们会根据这个异常信息来找到错误,处理bug + * + * 但是在真是生产环境中(比如项目已经上线),对于服务器或者是系统相关的问题 + * 在控制台上其实也会提供响应的异常或者处理信息的输出 + * 但是这种错误输出方法(输出的时间、位置、格式...)都是服务器系统默认的。 + * + * 我们可以通过日志技术,选择将异常以日志打印的方法,进行输出查看 + * 输出的时间、位置(控制台、文件)、格式。完全由我们自己取进行定义。 + * */ + // 编译器提供的默认的打印格式(输出到控制台) + // System.out.println(1); + + Logger loggr = LoggerFactory.getLogger(打印异常信息.class); + try { + // 以下代码会打印的错误信息是 : ClassNotFoundException(找不到指定的类) + Class.forName("aaa"); + } catch (ClassNotFoundException e) { + // 这行代码的含义是:打印栈的追踪信息 + // 这个时候也是使用的默认打印方法(位置和格式),打印到控制台,打印的是trace级别 + // e.printStackTrace(); + // 自定义日志信息输出级别 + loggr.info("xxx类中的xxx方法出现了异常"); + // 此时e是引用类型对象,不能根前面的{}做有效的字符串拼接 + // 如果后面是拼接的字符串,可以使用这个{} + // loggr.info("其具体错误是:{}",e); + // 这个info为我们添加了一个直接获取异常对象的方法 + // void info(String var1, Throwable var2); + loggr.info("错误信息是:",e); + } + } +} diff --git "a/SLF4J/src/main/java/com/yumbocheng/\346\227\245\345\277\227\351\207\215\346\236\204.java" "b/SLF4J/src/main/java/com/yumbocheng/\346\227\245\345\277\227\351\207\215\346\236\204.java" new file mode 100644 index 0000000..3b34dea --- /dev/null +++ "b/SLF4J/src/main/java/com/yumbocheng/\346\227\245\345\277\227\351\207\215\346\236\204.java" @@ -0,0 +1,18 @@ +package com.yumbocheng; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.junit.Test; + +public class 日志重构 { + + @Test + public void test01(){ + /* + * 这个时候我们使用log4j将输出日志格式转换为 logback+slf4j + * 此时需要使用 slf4j 提供的桥接器 log4j-over-slf4j 来实现 + * */ + Logger logger = LogManager.getLogger(日志重构.class); + logger.info("info信息"); + } +} diff --git a/SLF4J/src/main/resources/log4j.properties b/SLF4J/src/main/resources/log4j.properties new file mode 100644 index 0000000..9f0d8b5 --- /dev/null +++ b/SLF4J/src/main/resources/log4j.properties @@ -0,0 +1,7 @@ +# ??????????????(?????console?????) +log4j.rootLogger = trace,console + +# ????????? ??????(?????????) +log4j.appender.console = org.apache.log4j.ConsoleAppender +log4j.appender.console.layout = org.apache.log4j.PatternLayout +log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n diff --git a/SLF4J/target/classes/log4j.properties b/SLF4J/target/classes/log4j.properties new file mode 100644 index 0000000..f89a4e3 --- /dev/null +++ b/SLF4J/target/classes/log4j.properties @@ -0,0 +1,7 @@ +# ?????logger +log4j.rootLogger = trace,console + +# ????????? +log4j.appender.console = org.apache.log4j.ConsoleAppender +log4j.appender.console.layout = org.apache.log4j.PatternLayout +log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n diff --git "a/\346\227\245\345\277\227\344\273\213\347\273\215.md" "b/\346\227\245\345\277\227\344\273\213\347\273\215.md" new file mode 100644 index 0000000..2bfc8ff --- /dev/null +++ "b/\346\227\245\345\277\227\344\273\213\347\273\215.md" @@ -0,0 +1,1283 @@ +# Java日志框架 + +## 1. Java日志介绍 + +- **Java日志框架内中的xml配置文件中的标签是固定的,不可以自定义** + +- 配置文件基本结构: + + 以标签开头, + + 包含0或多个子标签, + + 包含0或多个标签, + + 最多只能有一个标签。 + +![image-20210909160501355](C:/Users/YunboCheng/AppData/Roaming/Typora/typora-user-images/image-20210909160501355.png) + +**以下是SLF4J门面技术。** + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210907174951.png) + +**这个是SLF4J门面技术,**这个深绿色的代表网络适配器。 + +- 日志文件是用于记录系统操作事件的文件集合。 +- 日志文件他具有处理历史数据、诊断问题的追踪以及理解系统的活动等重要作用。 +- 日志主要分为两种:调试日志与系统日志(工作中大部分使用) + +```java +// 使用反射机制的这个类只要是该项目的 src下的类都可以。 +Logger logger = LogManager.getLogger(入门案例.class); +``` + +### 1.1 调试日志 + +- 我们平时使用的debug功能只能暂时查看运行信息,而不能长期的保存这些运行信息。而调试日志可以更加方便的“重新”这些问题,即可以保存这些运行信息。 + +### 1.2 系统日志 + +- 系统日志是用来记录系统中的硬件、软件和系统相关问题的信息。同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因,或者寻找收到攻击留下来的痕迹。 +- 系统日志包括系统日志、应用日志和安全日志几种。 + +## 2.日志框架 + +### 2.1 日志框架的作用 + +- 控制日志输出的内容和格式。 +- 控制日志输出的位置。 +- 日志文件相关的优化,如异步操作、归档、压缩。 +- 日志系统的维护。 +- 面向接口开发——日志的门面。 + +### 2.2 日志框架的价值 + +- 我们可以直接使用别人写好的日志框架,提高开发效率。 + +### 2.3 市面流行的日志框架 + +- JUL:java util logging Java原生日志框架。 +- Log4j:Apache的一个开源项目。 +- Logbcak :由Log4j之父做的另一个开源项目,业界中称为 log4j 后浪。他是一个可靠、通用且灵活的Java日志框架。 +- Log4j2 :Log4j的第二个版本,各个方面与Logback及其相似。具有插件式结构、配置文件优化等特征,在Spring Boot1.4版本之后就不在支持 log4j ,所以出现了第二个版本的。 +- JCL +- SLF4j + +### 2.4 日志门面和日志框架的区别 + +- 日志框架技术 :JUL、Log4j、Logbcak、Log4j2 + +- 日志门面技术 :JCL、SLF4j + +为什么要使用日志门面技术: + +- 每一种日志框架都有自己单独的API,要使用对应的框架就要使用对应的API,这就大大的增加了应用程序代码对于日志框架的耦合性。使用日志门面技术之后,不论底层是什么日志框架,我们拿到代码之后可以使用自己习惯的日志框架就行解读,不用修改一行代码。 + +image-20210901205346469 + +- 其实框架1调用的是自己的方法a() ,框架2调用的自己的方法b() ,此时将这两个方法抽取出来称为方法c(); + +## 3. JUL + +### 3.1 JUL 简介 + +- JUL全程 Java Util Logging,它是java原生的日志框架,使用时不需要另外引入第三方的类库,相对于其他的框架使用方便,学习简单,主要使用在小型应用中。 + +### 3.2 JUL 组件介绍 + + + + + +### 3.3 日志的级别(Level) + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210901220551.png) + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210901221349.png) + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210901221622.png) + +- 注意:其中包含这个800,也就是info +- info是默认的打印信息级别。 + +```java +Logger logger = Logger.getLogger("com.yunbocheng.JUL.JULTest.test01"); +logger.severe("severe信息"); +logger.warning("warining信息"); +logger.info("info信息"); +logger.config("config信息"); +logger.fine("fine信息"); +logger.finer("finer信息"); +logger.finest("finest信息"); +``` + +此时打印的结果是 :只有info级别以及比info级别高的日志信息 + + + +### 3.4 入门案例 + +- 见项目 “入门以及默认级别展示” 。 + +### 3.5 自定义日志级别 + +- 见项目 “自定义日志级别 ” + +**总结 :** + +- 用户使用Logger来进行日志的记录,Logger可以同时持有多个处理器Handler。(同时在控制台和自定义位置进行日志信息的输出) +- 日志的记录使用的是Logger,日志的输出使用的是Handler。 +- 添加了哪些handler对象,就相当于需要根据所添加的handler将日志信息输出到指定的位置上,例如:控制台、指定位置文件..... + +### 3.6 JUL Logger中的父子关系。 + +- 见项目”JUL中的父子关系“ + +### 3.7 JUL配置文件解析 + +- 见项目”JUL配置文件“ + +```apl +以上所有的配置相关的操作,都是一Java硬编码的形式进行的。 +我们可以使用更加清晰,更加专业的一种做法,就是配置文件。 +如果我们没有自己添加这个配置文件,则会使用系统默认的配置文件。 + +这个配置文件: + java.home --> 找到jre文件夹 --> lib --> logging.properties +``` + + **配置文件中的#代表的注释,可以删除掉。** + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210904155133.png) + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210904155347.png) + +### 3.8 自定义配置文件 + +- 我们将配置文件修改为自定义的输出级别 + + ![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210904155857.png) + +- 如果想要获取到这个自定义的配置文件,此时一定需要一个输入流来读取这个文件。项目见”JUL配置文件“ + +### 3.9 日志信息的追加 + +- 只需要在日志配置文件中加入 :**java.util.logging.FileHandler.append = true** + +### 3.10 JUL日志框架使用方式总结(原理解析) + + ![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210904164300.png) + +## 4. Log4j + +### 4.1 Log4j简介 + +- Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、CUI组件,甚至可以是套接口服务器、NT的事件记录器。只要是我们需要的地方,一般都可以输出日志信息。 +- 我们可以控制每一条日志信息输出的格式。 +- 通过定义每一条日志信息的级别,我们能够更加细致的控制日志的生成过程。 +- 这些设置可以通过一个配置文件来灵活的进行配置,而不需要修改应用的代码。 + +- **Log4j --> Log for java** + +- **我们使用log4j技术,主要使用的是其配置文件**,我们也可以使用硬代码的格式在Java中来写这个日志配置信息。 + +- 从时间上讲,log4j的产生时间要比JUL早。 + +### 4.2 Log4j组件 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210904170749.png) + + + + + + + + + + + + + + + +### 4.3 日志输出格式说明 + + + +### 4.4 Log4j的级别 + + + +- **其中 debug 是我们在没有进行设置的情况下,默认的日志输出级别。** + +### 4.5 配置文件 + +- 将项目中的项目”配置文件“ + +![image-20210905195941294](https://gitee.com/YunboCheng/imageBad/raw/master/image/image-20210905195941294.png) + +### 4.6 使用默认配置文件打印日志 + +- 代码在项目“配置文件”中 + +- 注意:这个日志配置文件必须在main-->rescoures文件下,且名字必须是log4j.properties文件。此时log4j日志文件会自动加载这个配置文件。 +- **注意:在properties配置文件中,每一条命令后不要加分号,否则会报错。** + +```properties +# 以下是配置文件的代码信息 +# 这行代码代表让这个日志执行指定的配置信息 +# 这个trace代表的是输出级别,这个console是我们自定义的一个名称(见名思意)appenderName +# 这个可以设置打印到多个地方,中间用逗号隔开。 +# 这个Logger是继承的根节点rootLogger。 +log4j.rootLogger = trace,console +#配置appender输出方法 +log4j.appender.console = org.apache.log4j.ConsoleAppender +#配置输出信息的格式 +log4j.appender.console.layout = org.apache.log4j.SimpleLayout +``` + +- 以上使用的是默认的日志信息打印格式。(SimpleLayout) + +```java +// 以下是输出日志信息的代码 +public void test01(){ + Logger logger = Logger.getLogger(配置文件.class); + // 打印输出信息 + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); +} +``` + +### 4.7 自定义配置打印日志信息格式 + +- 代码在项目“配置文件”中 + +```properties +#这行代码的代表打印到控制台 +log4j.rootLogger = trace,console +#配置appender输出位置 +log4j.appender.console = org.apache.log4j.ConsoleAppender +#配置输出信息的格式 +log4j.appender.console.layout = org.apache.log4j.PatternLayout +#这行是设置自定义的日志信息打印格式 +log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} +``` + +- 这个是使用的自定义日志信息打印格式 PatternLayout,这个时候只需要在默认的配置文件中加入一行指定打印日志信息格式的代码即可。 + +### 4.8 将日志输出到指定文件中的配置 + +- 源代码见项目“日志信息输出到文件” + +```properties +#这行代码的代表打印到控制台 +log4j.rootLogger = trace,file +#配置appender输出位置 +log4j.appender.file = org.apache.log4j.ConsoleAppender +#配置输出信息的格式 +log4j.appender.console.file = org.apache.log4j.PatternLayout +#这行是设置自定义的日志信息打印格式 +log4j.appender.file.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +#第一个file是我们自己命名的appenderName,第二个file是用来指定文件的位置。 +log4j.appender.file.file = E://log4j.log +#设置输出日志的编码格式(输出中文的日志信息) +log4j.appender.file.encoding = UTF-8 +``` + +- 此时这个日志信息会输出到这个指定位置的文件中。 + +### 4.9 将日志信息输出到多个位置 + +- 源代码见项目“日志信息输出到文件” + +- 同时输入到控制台和指定文件中 + +```properties +# 需要将以上输出到控制台和文件的代码都要写上 +# 最主要的是修改打印到的位置代码,这是代表可以在 appenderName 为这个两个的地方输出 +# 这个 file,console是我们自定义的名称,(见名思意原则就是代表控制台和文件) +log4j.rootLogger = trace,file,console +``` + +### 4.10 根据文件大小拆分配置文件(RollingFileAppender) + +- 源代码见项目“日志信息输出到文件” + +```properties +log4j.rootLogger = trace,rollingFile,console +# RollingFileAppender的配置,我们可以针对实际含义起名 +log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender +log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout +log4j.appender.rollingFile.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +log4j.appender.rollingFile.file = E://log4j.log +log4j.appender.rollingFile.encoding = UTF-8 +# 指定日志文件的大小 +log4j.appender.rollingFiler.maxFileSize = 1MB +# 指定日志文件的数量 +log4j.appender.rollingFiler.maxBackupIndex = 5 +``` + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210905234827.png) + +- 这个时候日志6会覆盖掉日志1。以下就是生成的5个文件。这5个文件会以序号进行排列。 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210905235008.png) + +### 4.11 根据时间来拆分日志文件(DailyRollingFileAppender) + +- 源代码见项目“日志信息输出到文件” +- 这个会根据你输入的时间间隔来生成新的日志信息,这个时间可以是一天,也可以是一秒,需要注意的是这个并不是自动为我们生成新的日志文件,是我们手动生成的日志文件,比如:你设置的间隔是 yyyy-MM-dd ,这个时候如果你现在输出了一个日志文件,那么在这个时间开始的后24个小时内都不会生成新的日志文件,在这24小时内输出的日志文件都会存储到这个一个旧的日志文件中。即使过了24个小时,系统也不会为我们自动生成一个新的日志文件,需要程序员自己生成一个新的日志文件,加可以精确到秒,那么一秒就会为我们生成一个新的日志文件。 + +```properties +# DailyRollingFileAppender的配置,我们可以针对实际含义起名 +log4j.appender.dailyRollingFile = org.apache.log4j.DailyRollingFileAppender +log4j.appender.dailyRollingFile.layout = org.apache.log4j.PatternLayout +log4j.appender.dailyRollingFile.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +log4j.appender.dailyRollingFile.file = E://log4j.log +log4j.appender.dailyRollingFile.encoding = UTF-8 +#不要忘记前边的那个点 +appender.dailyRollingFile.datePattern = '.'yyyy-MM-dd HH:mm:ss +``` + +- 在这个类中没有提供覆盖的方法。 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210906000658.png) + +### 4.12 日志持久化(将日志信息存储到数据库) + +- 项目源码见 “日志持久化_将数据存储到数据库” + +- 第一步 :需要在Maven中添加mysql依赖。 + +- 第二步 :在配置文件中配置连接数据库的信息并且设置插入语句。 + + **注意:这个插入语句必须在一行上。** + +```properties +# 持久化日志信息 将日志信息存储到数据库 +log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender +log4j.appender.logDB.layout = org.apache.log4j.PatternLayout +log4j.appender.logDB.Driver = com.mysql.jdbc.Driver +log4j.appender.logDB.URL = jdbc:mysql://localhost/log +log4j.appender.logDB.User = root +log4j.appender.logDB.Password = 567cybtfboys +# 此时要像数据库中插入数据,使用insert语句 +log4j.appender.logDB.Sql = INSERT INTO tab_log(id,name,create,level,category,fileName,message) values('project_log','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%m') +``` + +- 第三步 :在主方法中输出日志信息 + +```java +Logger logger = Logger.getLogger(日志持久化_将数据存储到数据库.class); +// 输出日志信息 +logger.fatal("fatal信息"); +logger.error("error信息"); +logger.warn("warn信息"); +logger.info("info信息"); +logger.debug("debug信息"); +logger.trace("trace信息"); +``` + +### 4.13 自定义Logger的配置 + +- 见项目 “自定义Logger配置” + +- 第一步 :配置自定义logger + +```properties +# 使用最高父类rootLogger配置logger,这个时候继承的是父logger(根节点) +log4j.rootLogger = trace,console + +# 配置自定义logger,此时使用的是自定义的父logger (自定义) +log4j.logger.com.yunbocheng = info,file +``` + +- 输出结果 + +```markdown +从输出的位置来看,控制台输出了信息,日志文件也会输出信息。所以可以得出结论,如果根节点的logger和自定义父logger配置的输出位置是不同的则取二者的并集,也就是配置的位置都会进行日志的输出。 + +如果二者配置的日志级别不同,主要以按照我们自定义的父logger的级别输出为主。 +``` + +## 5.JCL (日志门面技术) + +### 5.1 JCL简介 + +- JCL是Apache提供的一个**通用日志API** + + + + + +- ```java + LoggerFactory // 这个叫日志工厂 + ``` + +### 5.2 入门案例以及JCL是如选择日志框架的 + +- 详细信息见 “入门案例” + +## 6. SLF4J (日志门面技术) + +- 只要使用到日志框架,百分之九九使用的都是SLF4J门面技术。 + +### 6.1 门面模式(外观模式) + +- 他属于GoF23种设计模式的一种。 +- 门面技术,核心是:外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更容易使用。 + +### 6.2 日志门面 + + + +- 外观模式主要提现Java种得一种好得封装性。更简单说,就是对外提供得接口要尽量简单。 + + + +- 这就相当于是一个门面技术,我们吃什么不需要和每一位厨师打交道,只需要和前台打交道即可。这个前台就相当于是一个API接口。 + +### 6.3 常见得日志框架及日志门面 + + ![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210907085306.png) + +### 6.4 SLF4J简介 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210907122610.png) + +### 6.5 SLF4J桥接技术 + +- 为什么使用桥接技术 +- 因为在SLF4J出现之前已经出现了一些日志框架(比如:log4j、JUL、JCL等) 这些框架没有继承这个SLF4J的日志API接口。这个时候就需要使用这个桥接技术。在SLF4J之后出现的日志框架都实现了这个SLF4J接口,就不用桥接技术实现。 + +### 6.6 入门案例 + +- 见项目”入门案列“ + +### 6.7 SLF4J动态打印信息的实现 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210907132547.png) + +- 见项目“入门案列” + +### 6.8 打印异常信息 + +- 见项目 “打印异常信息” + +### 6.9 SLf4J集成日志框架(logback) + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210907145131.png) + +- SLf4J集成logback日志框架 + - **注意:如果在pom.xml文件种存在多个日志框架,默认使用先导入的日志框架实现(也就是谁在最上边就先打印谁)** + - 不论谁在上下,只要存在多个日志框架,那么都会报错( Class path contains multiple SLF4J bindings ) + - 在实际应用的时候,我们一般情况下,仅仅只是做一种日志实现的集成就可以了 + +### 6.10 SLF4J集成log4j + +- 源码见项目 ”SLF4J集成log4j的方法“ + +- 这个是slf4j以前出现的日志框架,此时需要绑定一个适配器 slf4j-log4j12 +- 在pom.xml文件中修饰依赖配置 + +```xml + + + org.slf4j + slf4j-api + 1.7.29 + + + + + org.slf4j + slf4j-log4j12 + 1.7.25 + + + + + log4j + log4j + 1.2.17 + +``` + +- 还需要有log4j日志框架的配置文件(这个配置文件在main-->resources下)并且这个配置文件需要声明为 **log4j.properties** + +```properties +# 使用根节点的logger对象 +log4j.rootLogger = trace,console + +# 将日志信息输出到控制台 +log4j.appender.console = org.apache.log4j.ConsoleAppender +log4j.appender.console.layout = org.apache.log4j.PatternLayout +log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n +``` + +- 主函数: + +```java +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +// 注意此时使用的是 slf4j 中的类和接口来创建的logger对象,而不是log4j +Logger logger = LoggerFactory.getLogger(SLF4J集成log4j的方法.class); +// 打印输出信息 +logger.error("error信息"); +logger.warn("warn信息"); +logger.info("info信息"); +logger.debug("debug信息"); +logger.trace("trace信息"); +``` + +- 此时输出的结果就是log4j格式的输出结果 + + + +### 6.11 SLF4J集成log4j + +- 源码见项目 ”SLF4J集成JUL的方法“ + +- 这个是slf4j以前出现的日志框架,此时需要绑定一个适配器 slf4j-jdk14 +- 在pom.xml文件中修饰依赖配置 + +```xml + + + org.slf4j + slf4j-api + 1.7.29 + + + + + org.slf4j + slf4j-jdk14 + 1.7.25 + + +``` + +- 使用JUL也不需要配置文件,只有log4j需要配置文件 +- 实现主类 + +```java +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +// 此时的这个logger对象也是通过 slf4j 获取的,完全不需要JUL参与 +Logger logger = LoggerFactory.getLogger(SLF4J集成log4j的方法.class); +// 打印输出信息 +logger.error("error信息"); +logger.warn("warn信息"); +logger.info("info信息"); +logger.debug("debug信息"); +logger.trace("trace信息"); +``` + +- 输出结果 (此时输出的就是JUL格式的日志信息) + + + +- 从结果看是JUL日志打印的,默认是info级别的输出的。 + +### 6.12 同时集成多个日志会出现错误信息 + +- 一次集成多个日志框架会发生错误,也可以打印出日志信息,只不过打印的日志信息格式是pom.xml文件中最上边的那个日志框架。 + +### 6.13 日志重构需求 + +- 我们以前都是使用SLF4J来实现JUL与log4j,导入的都是slf4j的包。此时需要使用log4j包下的类和方法将日志重构为 **slf4j + logback**的组合。在不接触源码的情况下实现这个需求。 +- 首先将所有关于其他日志实现和门面依赖全部去除。仅仅只留下log4j的依赖,测试的过程中,只是使用log4j相关的组件。 +- 这个时候需要使用桥接器来实现这个需求。桥接器解决的是项目中日志的重构问题。当前系统中存在之前的日志API,可以通过桥接器转换到slf4j的实现。 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210907203819.png) + +- 以上除了绿色和蓝色的都是桥接器。 + +- 桥接器的使用步骤: + +1. 第一步 :删除之前旧的日志框架依赖(此时是使用log4j --> slf4j+logback) + +```xml + + +log4j +log4j +1.2.17 + +``` + +2. 添加 slf4j 提供的桥接组件 (此时我们需要添加log4j的桥接器) + +```xml + + + org.slf4j + slf4j-api + 1.7.29 + + + + + ch.qos.logback + logback-classic + 1.2.3 + test + + + + + org.slf4j + log4j-over-slf4j + 1.7.25 + +``` + +3. 打印日志信息函数 + +```java +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.junit.Test; +//注意:此时使用了 log4j包下的类和方法实现了 logback日志格式的输出。 +// 此时需要使用 slf4j提供的log4j-over-slf4j桥接器 +Logger logger = LogManager.getLogger(日志重构.class); +logger.info("info信息"); +``` + +4. 输出结果 (一看是黑色的日志信息,一看就是logback打印的输出的日志信息) + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210907205946.png) + +- 证明了现在使用的确实是slf4j门面+logback实现。 + +- 在重构之后,就会为我们造成这样一种假象,我们明明使用的是**log4j包**下的日志组件资源,但是真正日志的实现,却是使用**slf4j门面+logback实现**,这就是桥接器给我们带来的效果。 + +**注意:** + +1. 桥接器如果配置在适配器的上方,则执行报错,不能同时出现。 +2. 桥接器如果配置在适配器的下方,则不会执行桥接器,没有任何意义。 +3. 在实际开发中,我们不要在pom.xml中同时给出适配器和桥接器。 + +## 7. Logback + +### 7.1 Logback简介 + +![image-20210908081658358](https://gitee.com/YunboCheng/imageBad/raw/master/image/image-20210908081658358.png) + +### 7.2 Logback中的组件 + +![image-20210908081929996](https://gitee.com/YunboCheng/imageBad/raw/master/image/image-20210908081929996.png) + +### 7.3 Logback配置文件 + +Logback提供了3种配置文件 + +- logback.groovy +- logback-test.xml +- logback.xml + +如果都不存在则采用默认的配置。 + +### 7.4 日志输出格式 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210908165035.png) + +注意:-10代表给案例设置10个字符,左对齐。+10代表给案例设置10个字符,右对其。 + +### 7.4 入门案例 + +- 项目见”入门案列“ + +- ```markdown + trace(追踪信息) < debug(普通信息) < info(重要信息) < warn(警告信息) < error(错误信息) 其中debug为默认的打印级别。 + ``` + +1. pom.xml项目依赖文件 + +```xml + + + org.slf4j + slf4j-api + 1.7.29 + + + + + ch.qos.logback + logback-classic + 1.2.3 + test + +``` + +2. 编写打印日志信息代码 + +```java +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +// 注意:以上都是使用的 slf4j 门面技术来实现的这个logback的日志框架。完全不需要使用logback包中的类和方法。使用的是 slf4j 的门面技术。 +// 这里我们还是使用slf4j的门面技术来实现logback +Logger logger = LoggerFactory.getLogger(入门案列.class); +logger.error("error信息"); +logger.warn("warn信息"); +logger.info("info信息"); +logger.debug("debug信息"); +logger.trace("trace信息"); +``` + +3. 此时没有修改打印日志信息的级别,所以此时打印的为默认级别(debug)。 + +![image-20210908163904110](https://gitee.com/YunboCheng/imageBad/raw/master/image/image-20210908163904110.png) + +### 7.5 使用Logback配置文件(logback.xml)来打印日志信息 + +- 配置文件中的信息以及实现方式见项目 “Logback配置文件”。 + +### 7.6 Logback将日志信息打印到指定文件 + +- 配置文件中的信息以及实现方式见项目 “Logback配置文件”。 + +### 7.7 Logback同时在多个位置打印日志信息(文件、控制台) + +- 此时只需要修改配置文件中的信息即可 + +```xml + + + + + + +``` + +```xml + + + + + + + + + +``` + +### 7.8 将日志信息打印html文件 + +- 此时需要修改配置文件信息,此时的配置文件信息比较特殊 + +```xml + + + + + + + ${logDir}/logback.html + + + + ${pattern} + + + + + + + +``` + +- 注意:我们只能设置打印的日志信息内容,不能设置这个网页的打印格式以及样式。 +- **但是,当我们打印出logback.html文件后,我们可以人为的修改其中的样式以及格式** + +- 这个html中包含 HTML+CSS。 + +- 在实际的开发中,如果日志文件不是很大,我们可以考虑使用html进行日志打印,因为可读性强。 + +### 7.9 Logback日志拆分和归档压缩 + +- 其实我们在XML中使用的这些标签都是来自class类中的属性 + +```xml + + + + + + ${pattern} + + + ${logDir}/roll_logback.log + + + + + + ${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz + + 1KB + + + +``` + +### 7.10 通过过滤器更细粒度的打印日志信息 + +- 修改其中的XML配置文件 + +```xml + + + + + System.err + + + + ${pattern} + + + + + WARN + + ACCEPT + + DENY + +``` + +### 7.11 异步日志 + +- 以前一直使用的同步日志(一根线程) + +为什么要使用异步日志 + +- 在实际的开发中,代码的执行顺序肯定是自上而下执行的,这个时候如果我们的日志信息非常的庞大,那么我们的系统信息需要等待日志信息全部打印完毕之后才可以打印系统信息,此时系统会处于一种停滞状态,对系统本身业务代码的执行效率非常的低。 + +异步日志的作用 + +- 在我们打印日志信息的同时不会影响系统代码的执行。 + +配置异步日志的方式 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210909094258.png) + +```xml + + + + + + + + +``` + +异步日志的原理: + +- **系统会为日志操作单独的分配出来一根线程,原来用来执行当前方法的主线程会继续向下执行。** + +- 线程1 : 系统业务代码执行 线程2 :打印日志 两根线程争夺CPU的使用权。 + +**在实际的我们使用异步日志的方式来实现业务。** + +### 7.12 自定义logger + +```xml + + + + + + +``` + +- 此时打印出的日志信息级别全是info级别和比info级别高的日志信息。 + +### 7.13 Logbcak的补充 + +- 关于异步日志的补充 + +![image-20210909095921798](https://gitee.com/YunboCheng/imageBad/raw/master/image/image-20210909095921798.png) + +- 不同配置文件之间的转换 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210909100308.png) + +## 8. Log4j2 + +### 8.1 Log4j2简介 + +- Apache Log4j2是对Log4j的升级,它提供了Logback中可用的许多改进,同时修复了Logback架构中的一些问题。被誉为是目前最优秀的java日志框架。 + +### 8.2 Log4j2特征 + +- **性能提升**:在多线程场景中,异步记录器的吞吐量比Log4j 1.x 和 Logback高18倍,延迟低。 +- **自定重新加载配置**:与Logback一样,Log4j2可以在修改时自动重载加载配置。与Logback不同,它会在从重新配置发生时不会丢失日志事件。 +- **高级过滤**:与Logback一样,Log4j2支持基于 Log事件中的上下文数据,标记,正则表达式和其他组件进行过滤。此外,过滤器还可以与记录器关联。与Logback不同,Log4j2可以在任何这些情况下使用通用的Filter类。 + +- **插件架构**:Log4j2 使用插件模式配置组件。因为,无需编写代码来创建和配置 Appender、Layout、Pattern Converyer 等。在配置了的情况下,Log4j2自动识别插件并使用他们。 +- **无垃圾回收机制**:在稳态日志记录期间,**Log4j2 在独立应用程序中是无垃圾的**,在web应用程序中式低垃圾。这减少了垃圾收集器的压力,并且可以提供更好的响应性能。 + +### 8.3 主流日志框架 + +- 目前市场上最主流的日志门面技术是 SLF4J,虽然 Log4j2 也是日志门面,因为它的日志实现功能非常强大,性能优越。所以我们一般情况下还是将Log4j2看做是日志的实现。 +- SLF4J + Log4j2 的组合,是市场上最强大的日志功能实现方式,绝对是主流日志框架。 + +### 8.4 入门案列 + +- 这个案例不使用 SLF4J 来实现,仅用Log4j2来实现。 + +1. 配置pom.xml文件 (这些依赖其实就是一个jar包) + +```xml + + + org.apache.logging.log4j + log4j-core + 2.12.1 + + + + org.apache.logging.log4j + log4j-api + 2.12.1 + +``` + +- 实现日志输出 + +```java +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.Test; +// 以上没有使用 SLF4J门面技术,完全使用的log4j中的类和方法进行实习的。 +public class 入门案例 { + @Test + public void test01(){ + /* + * 这个案例中我们单纯的使用Log4j2 门面+实现 + * 不使用 SLF4J 实现。 + * Log4j2和log4j提供了相同的输出级别。 + * Log4j2的默认输出级别是 error + * */ + Logger logger = LogManager.getLogger(入门案例.class); + logger.fatal("fatal信息"); + logger.error("error信息"); + logger.warn("warn信心"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); + } +} +``` + +- 运行结果 + + + +- 此时会观察到 ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration 这句话的含义是:没有找到 Log4j2的配置文件,使用默认的打印日志信息格式。 +- 出现这句话就说明此时这个日志是使用 Log4j2框架实现的。 + +### 8.5 配置文件基础标签 + +- 见项目 “Log4j2基础标签” + +- 对于Log4j2配置文件中的标签,要求首字母都大写。logback中的首字母是小写。 + +### 8.6 Log4j2与SLF4J联合使用(使用slf4j来实现log42日志) + +- 见项目 “Log4j2与SLF4J联合使用” +- 这里不仅需要导入 slf4j 的日志门面技术还需要导入 log4j2的日志门面。 +- 执行原理:slf4j门面调用的是log4j2的门面,在由log4j2的门面调用log4j2的实现。 + +1. 需要在pom.xml文件中导入多个依赖 + +```xml + + + org.apache.logging.log4j + log4j-core + 2.12.1 + + + + org.apache.logging.log4j + log4j-api + 2.12.1 + + + + org.slf4j + slf4j-api + 1.7.25 + + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.12.1 + +``` + +- 配饰 log4j2配置文件(此时将日志信息输出到控制台) + +```xml + + + + + + + + + + + + + + + + + +``` + +- 实现日志输出 + +```java +// 注意:我们使用的都是 slf4j门面技术中的类与方法实现的日志信息的打印,没有适应到log4j2. +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +// 注意:此时使用的 slf4j 的门面技术,输出的是 slfj的日志级别(有5个级别) +Logger logger = LoggerFactory.getLogger(Log4j2与SLF4J联合使用.class); +// slf4j 中存在5种日志输出级别,此时使用是slf4j的记录器,而不是log4j2的,所以只能输出slf4j中的五种级别。 +logger.error("error信息"); +logger.warn("warn信息"); +logger.info("info信息"); +logger.debug("debug信息"); +logger.trace("trace信息"); +``` + +- 注意:虽然表面使用的是 slf4j,但是底层使用的是log4j2门面技术与log4j2的实现框架。 + +- 输出结果: + + + +### 8.7 日志文件输出 + +- 将项目 “日志文件输出”。 + +1. 配置 log4j2.xml 文件 + +```xml + + + D://test + + + + + + + + + + + + + + + + + + + + +``` + +- 实现日志输出 (和上边一样,次数省略不写) + +- 输出结果(输出的格式是我们自定义的格式) + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210909164802.png) + +### 8.8 日志文件拆分 + +- 这个很重要。详细的解释见项目 “log4j2日志拆分”。 + +### 8.9 log4j2 中的异步日志 + +- 日志默认是同步的,异步日志就是分配单独的线程做日志记录。 + +- **异步日志是 log4j2 中最大的特色。** + + + +- 可以将这两种实现日志的方式看做完全不一样。 + +#### 8.9.1 AsyncAppender 方法(实际中用的少) + +- AsyncAppender是通过引用别的 Appender 来实现的,当有日志事件到达时,会开启另外一个线程来处理他们。AsyncAppender默认使用Java中自带的类库(util类库),不需要导入外部类库。AsyncAppender 应该是在它引用 Appender 之后配置,因为如果在Appender的时候出现异常,对应用来说是无法感知的。当使用此 Appender 的时候,在多线程的环境下需要注意,阻塞队列容易受到锁争用的的影响,这可能会对性能产生影响。这个时候,我们需要使用无锁的异步记录器 (AsyncLogger) + +#### 8.9.2 AsyncLogger 方法(实际中用的多) + +- AsyncLogger才是log4j2实现异步最重要的功能体现,也是官方推荐的异步方式。 +- 它可以使调用Logger.log返回更快。其中包括全局异步和混合异步。 +- 全局异步:所有的日志都异步的记录,在配置文件上下不用做任何的改动,只需要在jvm启动的时候增加一个参数即可实现,实际开发中使用较少。 +- 混合异步:你可以同时在应用中使用同步日志和异步日志,这使得日志的配置方式更加的灵活。混合日志需要修改配置文件来实现,使用AsyncLogger标记配置,实际开发中使用较多。 + +### 8.10 log4j2使用AsyncAppender方法实现异步日志 + +- 使用AsyncAppender方式实现的全局异步日志输出 + +1. 在 pom.xml 文件中加入异步日志依赖 + +```xml + + + com.lmax + disruptor + 3.3.7 + +``` + +2. 在 log4j.xml配置文件的 Appenders标签中,对于异步进行配置,使用Async标签。 + +```xml + + + + + + + + + + + + + + +``` + +- 测试全局异步输出日志信息 + +```java +//日志的记录 +Logger logger = LoggerFactory.getLogger(Log4j2与SLF4J联合使用.class); +// slf4j 中存在5种日志输出级别,此时使用是slf4j的记录器,而不是log4j2的,所以只能输出slf4j中的五种级别。 +for (int i = 0; i < 100; i++) { + logger.error("error信息"); + logger.warn("warn信息"); + logger.info("info信息"); + logger.debug("debug信息"); + logger.trace("trace信息"); +} +// 系统业务逻辑 +for (int i = 0; i < 100; i++) { + System.out.println("-----------"); +} +``` + +- 输出结果(观察结果可以发现,此时实现了异步日志的输出) + + + +### 8.11 log4j2使用AsyncLogger 方法实现异步日志(全局异步) + +- 全局异步 :所有的日志都是异步的日志记录,在配置文件上不用做任何的改动。 + +1. 只需要在类路径 resources 下添加一个properties属性文件,做一步配置即可。 + 文件名要求是:log4j2.component.properties +2. 在log4j2.component.properties配置文件中,加入下面这行代码即可。 + +```properties +Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector +``` + +3. 修改 log4j2.xml 文件中的配置信息(只需要将输出的位置修改即可) + +```xml + + + + + + + +``` + +- 输出结果(实现了全局异步) + +![image-20210909194218880](https://gitee.com/YunboCheng/imageBad/raw/master/image/image-20210909194218880.png) + +### 8.12 log4j2使用AsyncLogger 方法实现异步日志(混合异步) + +- 同时在应用中使用同步日志和异步日志。 +- 需求:假设我们现在有自定义的logger -- com.yunbocheng 让自定义的logger是异步的,让rootlogger是同步的。 + +注意:在做测试前,一定要将全局的异步配置注释掉(resources下的properties),使用 # 注释。 + +```properties +#Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector +``` + +1. 注释掉全局异步的文件(以上) +2. 修改 xml配置文件 + +```xml + + + + + + + + + + + + + +``` + +- 以上都在控制台上进行输出。 + +注意: + +- AsyncAppender、AsyncLogger不要同时出现,没有这个需求,效果也不会叠加。 +- 如果同时出现,那么效率会以AsyncAppender为主。 +- AsyncLogger中的全局异步和混合异步也不要同时出现,没有这个需求,效果也不会叠加。 + +各种语言的异步日志强度比较 + +![](https://gitee.com/YunboCheng/imageBad/raw/master/image/20210909202717.png) +