# logback ###### tags: `logback` `java` Logback is intended as a successor to the popular log4j project. ## 模組 * `logback-core` 另外兩個模組的基礎。 * `logback-classic` 延伸了`logback-core`並大幅改進`log4j`。 * `logback-access` 整合 Servlet containers 提供 HTTP access logs 功能。 ## 構成 Logback 由三個元件構成:Logger、Appenders、Layouts。 ### Logger context `TRACE` &#60; `DEBUG` &#60; `INFO` &#60; `WARN` &#60; `ERROR` ### Appenders ### Layouts (待續) ## 依存性 * `logback-classic` * `slf4j-api` * `logback-core` ## 配置 透過 Java 或 XML 兩種方式設定;這個[鏈結](https://logback.qos.ch/translator/)能將`log4j.properties`轉為`logback.xml`。 ### 順序 1. `logback-test.xml` 2. `logback.groovy` 3. `logback.xml` 4. 觀察`/META-INF/services/ch.qos.logback.classic.spi.Configurator`、實作`ch.qos.logback.classic.spi.Configurator`的 class。 5. 以上都沒有的話就套用`ch.qos.logback.classic.BasicConfigurator`。 > It takes about 100 miliseconds for Joran to parse a given logback configuration file. To shave off those miliseconds at aplication start up, you can use the service-provider loading facility (item 4 above) to load your own custom Configurator class with BasicConfigrator serving as a good starting point. 解析設定檔大概要100毫秒,直接採用第4種方式能有效地節省應用程式啟動時間。 ### XML ``` <?xml encoding="UTF-8" version="1.0"?> <configuration debug="true" scan="true" scanPeriod="30 seconds" packagingData="true"> <contextName>myAppName</contextName> <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <logger name="" level="TRACE|DEBUG|INFO|WARN|ERROR|ALL|OFF|INHERITED|NULL" additivity="true|false"/> <root level="TRACE|DEBUG|INFO|WARN|ERROR|ALL|OFF"> <appender-ref ref="STDOUT"/> </root> </configuration> ``` #### 變數 > Earlier versions of this document used the term "property substitution" instead of the term "variable". Please consider both terms interchangeable although the latter term conveys a clearer meaning. 早期稱**屬性替代**。 ### Java #### `ConsoleAppender`[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](http://logback.qos.ch/apidocs/?ch/qos/logback/core/ConsoleAppender.html "ch.qos.logback.core.ConsoleAppender") |子元素|類型|預設|描述| |-|-|-|-| |`encoder`|`ch.qos.logback.core.encoder.Encoder`|`OutputStreamAppender`|See `OutputStreamAppender` properties.| |`target`|`String`|`System.out`|`System.out`或`System.err`| |`withJansi`|`boolean`|`false`|Setting withJansi to true activates the Jansi library which provides support for ANSI color codes on Windows machines. On a Windows host, if this property is set to true, then you should put "org.fusesource.jansi:jansi:1.17" on the class path. Note that Unix-based operating systems such as Linux and Mac OS X support ANSI color codes by default.| ``` <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern> </encoder> </appender> ``` #### `FileAppender`[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](http://logback.qos.ch/apidocs/?ch/qos/logback/core/FileAppender.html "ch.qos.logback.core.FileAppender") ##### `RollingFileAppender`[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](http://logback.qos.ch/apidocs/?ch/qos/logback/core/rolling/RollingFileAppender.html "ch.qos.logback.core.rolling.RollingFileAppender") #### `DBAppender`[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](http://logback.qos.ch/apidocs/?ch/qos/logback/classic/db/DBAppender.html "ch.qos.logback.core.DBAppender") ##### 先決條件 在`logback-classic`的`src/main/java/ch/qos/logback/classic/db/script`可以找到對應常見 RDBMS 的 DDL。 ###### `logging_event`資料表 * MySQL/MariaDB ``` CREATE TABLE `logging_event` ( `event_id` BIGINT AUTO_INCREMENT PRIMARY KEY, -- 官方的設計是將此欄位放在最後 `occurred` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 這是我自己新增的欄位 `timestmp` BIGINT NOT NULL, `formatted_message` TEXT NOT NULL, `logger_name` VARCHAR(256) NOT NULL, `level_string` VARCHAR(256) NOT NULL, `thread_name` VARCHAR(256), `reference_flag` SMALLINT, `arg0` VARCHAR(256), `arg1` VARCHAR(256), `arg2` VARCHAR(256), `arg3` VARCHAR(256), `caller_filename` VARCHAR(256) NOT NULL, `caller_class` VARCHAR(256) NOT NULL, `caller_method` VARCHAR(256) NOT NULL, `caller_line` CHAR(4) NOT NULL )COLLATE=utf8mb4_general_ci; ``` * PostgreSQL ``` CREATE TABLE "logging_event" ( "event_id" serial8 PRIMARY KEY, -- 官方的設計是將此欄位放在最後 "occurred" timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 這是我自己新增的欄位 "timestmp" int8 NOT NULL, "formatted_message" text NOT NULL, "logger_name" varchar NOT NULL, "level_string" varchar NOT NULL, "thread_name" varchar, "reference_flag" int2, "arg0" varchar, "arg1" varchar, "arg2" varchar, "arg3" varchar, "caller_filename" varchar NOT NULL, "caller_class" varchar NOT NULL, "caller_method" varchar NOT NULL, "caller_line" varchar NOT NULL ); ``` ###### `logging_event_property`資料表 * MySQL/MariaDB ``` CREATE TABLE `logging_event_exception` ( `event_id` BIGINT NOT NULL, `i` SMALLINT NOT NULL, `trace_line` VARCHAR(256) NOT NULL, PRIMARY KEY(`event_id`, `i`), FOREIGN KEY (`event_id`) REFERENCES `logging_event`(`event_id`) )COLLATE=utf8mb4_general_ci; ``` * PostgreSQL ``` CREATE TABLE "logging_event_exception" ( "event_id" int8 NOT NULL, "i" int2 NOT NULL, "trace_line" varchar NOT NULL, PRIMARY KEY("event_id", "i"), FOREIGN KEY ("event_id") REFERENCES "logging_event"("event_id") ); ``` ###### `logging_event_exception`資料表 * MySQL/MariaDB ``` CREATE TABLE `logging_event_property` ( `event_id` BIGINT NOT NULL, `mapped_key` VARCHAR(256) NOT NULL, `mapped_value` TEXT, PRIMARY KEY(`event_id`, `mapped_key`), FOREIGN KEY (`event_id`) REFERENCES `logging_event`(`event_id`) )COLLATE=utf8mb4_general_ci; ``` * PostgreSQL ``` CREATE TABLE "logging_event_property" ( "event_id" int8 NOT NULL, "mapped_key" varchar NOT NULL, "mapped_value" text, PRIMARY KEY("event_id", "mapped_key"), FOREIGN KEY ("event_id") REFERENCES "logging_event"("event_id") ); ``` ##### `<connectionSource/>` 以下實作`ConnectionSource`[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](http://logback.qos.ch/apidocs/?ch/qos/logback/core/db/ConnectionSource.html "ch.qos.logback.core.db.ConnectionSource")的類別可取得`Connection`[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://docs.oracle.com/javase/8/docs/api/?java/sql/Connection.html "java.sql.Connection"): * `DriverManagerConnectionSource` * `DataSourceConnectionSource` * `JNDIConnectionSource` [How to create JNDI context in Spring Boot with Embedded Tomcat Container](https://stackoverflow.com/questions/24941829/how-to-create-jndi-context-in-spring-boot-with-embedded-tomcat-container) * `https://stackoverflow.com/questions/52552866/spring-boot-2-embedded-tomcat-jndi-datasource-configuration`