日志管理
openGauss JDBC驱动程序支持使用日志记录来帮助解决在应用程序中使用openGauss JDBC驱动程序时的问题。openGauss JDBC支持如下三种日志管理方式:
- 对接应用程序使用的SLF4J日志框架。
- 对接应用程序使用的JdkLogger日志框架。
SLF4J和JdkLogger是业界Java应用程序日志管理的主流框架,描述应用程序如何使用这些框架超出了本文范围,用户请参考对应的官方文档(SLF4J:<http://www.slf4j.org/manual.html>,JdkLogger:<https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html>)。
方式一:对接应用程序的SLF4J日志框架。
在建立连接时,url配置logger=Slf4JLogger。
可采用Log4j或Log4j2来实现SLF4J。当采用Log4j实现SLF4J,需要添加如下jar包:log4j-*.jar、slf4j-api-*.jar、slf4j-log4*-*.jar,(*区分版本),和配置文件:log4j.properties。若采用Log4j2实现SLF4J,需要添加如下jar包:log4j-api-*.jar、log4j-core-*.jar、log4j-slf4j18-impl-*.jar、slf4j-api-*-alpha1.jar(*区分版本),和配置文件:log4j2.xml。
此方式支持日志管控。SLF4J可通过文件中的相关配置实现强大的日志管控功能,建议使用此方式进行日志管理。
注意:
此方式依赖slf4j的通用API接口,如org.slf4j.LoggerFactory.getLogger(String name)、org.slf4j.Logger.debug(String var1)、org.slf4j.Logger.info(String var1)、org.slf4j.Logger.warn(String warn)、org.slf4j.Logger.warn(String warn)等,若以上接口发生变更,日志将无法打印。
示例:
1. public static Connection GetConnection(String username, String passwd){
3. String sourceURL = "jdbc:postgresql://10.10.0.13:8000/postgres?logger=Slf4JLogger";
4. Connection conn = null;
6. try{
7. //创建连接
8. conn = DriverManager.getConnection(sourceURL,username,passwd);
9. System.out.println("Connection succeed!");
10. }catch (Exception e){
11. e.printStackTrace();
12. return null;
13. }
14. return conn;
15. }
log4j.properties示例:
1. log4j.logger.org.postgresql=ALL, log_gsjdbc
3. # 默认文件输出配置
4. log4j.appender.log_gsjdbc=org.apache.log4j.RollingFileAppender
5. log4j.appender.log_gsjdbc.Append=true
6. log4j.appender.log_gsjdbc.File=gsjdbc.log
7. log4j.appender.log_gsjdbc.Threshold=TRACE
8. log4j.appender.log_gsjdbc.MaxFileSize=10MB
9. log4j.appender.log_gsjdbc.MaxBackupIndex=5
10. log4j.appender.log_gsjdbc.layout=org.apache.log4j.PatternLayout
11. log4j.appender.log_gsjdbc.layout.ConversionPattern=%d %p %t %c - %m%n
12. log4j.appender.log_gsjdbc.File.Encoding = UTF-8
log4j2.xml示例:
1. <?xml version="1.0" encoding="UTF-8"?>
2. <configuration status="OFF">
3. <appenders>
4. <Console name="Console" target="SYSTEM_OUT">
5. <PatternLayout pattern="%d %p %t %c - %m%n"/>
6. </Console>
7. <File name="FileTest" fileName="test.log">
8. <PatternLayout pattern="%d %p %t %c - %m%n"/>
9. </File>
10. <!--JDBC Driver日志文件输出配置,支持日志回卷,设定日志大小超过10MB时,创建新的文件,新文件的命名格式为:年-月-日-文件编号-->
11. <RollingFile name="RollingFileJdbc" fileName="gsjdbc.log" filePattern="%d{yyyy-MM-dd}-%i.log">
12. <PatternLayout pattern="%d %p %t %c - %m%n"/>
13. <Policies>
14. <SizeBasedTriggeringPolicy size="10 MB"/>
15. </Policies>
16. </RollingFile>
17. </appenders>
18. <loggers>
19. <root level="all">
20. <appender-ref ref="Console"/>
21. <appender-ref ref="FileTest"/>
22. </root>
23. <!--指定JDBC Driver日志,级别为:all,可查看所有日志,输出到gsjdbc.log文件中-->
24. <logger name="org.postgresql" level="all" additivity="false">
25. <appender-ref ref="RollingFileJdbc"/>
26. </logger>
27. </loggers>
28. </configuration>
方式二:对接应用程序使用的JdkLogger日志框架。
默认的Java日志记录框架将其配置存储在名为logging.properties的文件中。Java会在Java安装目录的文件夹中安装全局配置文件。logging.properties文件也可以创建并与单个项目一起存储。
logging.properties配置示例:
1. # 指定处理程序为文件。
2. handlers= java.util.logging.FileHandler
4. # 指定默认全局日志级别
5. .level= ALL
7. # 指定日志输出管控标准
8. java.util.logging.FileHandler.level=ALL
9. java.util.logging.FileHandler.pattern = gsjdbc.log
10. java.util.logging.FileHandler.limit = 500000
11. java.util.logging.FileHandler.count = 30
12. java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
13. java.util.logging.FileHandler.append=false
代码中使用示例:
1. System.setProperty("java.util.logging.FileHandler.pattern","jdbc.log");
2. FileHandler fileHandler = new FileHandler(System.getProperty("java.util.logging.FileHandler.pattern"));
3. Formatter formatter = new SimpleFormatter();
4. fileHandler.setFormatter(formatter);
5. Logger logger = Logger.getLogger("org.postgresql");
6. logger.addHandler(fileHandler);
7. logger.setLevel(Level.ALL);
8. logger.setUseParentHandlers(false);
链路跟踪功能
openGauss JDBC驱动程序提供了应用到数据库的链路跟踪功能,用于将数据库端离散的SQL和应用程序的请求关联起来。该功能需要应用开发者实现org.postgresql.log.Tracer接口类,并在url中指定接口实现类的全限定名。
url示例:
1. String URL = "jdbc:postgresql://127.0.0.1:8000/postgres?traceInterfaceClass=xxx.xxx.xxx.OpenGaussTraceImpl";
org.postgresql.log.Tracer接口类定义如下:
1. public interface Tracer {
2. // Retrieves the value of traceId.
3. String getTraceId();
4. }
org.postgresql.log.Tracer接口实现类示例:
1. import org.postgresql.log.Tracer;
3. public class OpenGaussTraceImpl implements Tracer {
4. private static MDC mdc = new MDC();
6. private final String TRACE_ID_KEY = "traceId";
8. public void set(String traceId) {
9. mdc.put(TRACE_ID_KEY, traceId);
10. }
12. public void reset() {
13. mdc.clear();
14. }
16. @Override
17. public String getTraceId() {
18. return mdc.get(TRACE_ID_KEY);
19. }
20. }
上下文映射示例,用于存放不同请求的生成的traceId。
1. import java.util.HashMap;
3. public class MDC {
4. static final private ThreadLocal<HashMap<String, String>> threadLocal = new ThreadLocal<>();
6. public void put(String key, String val) {
7. if (key == null || val == null) {
8. throw new IllegalArgumentException("key or val cannot be null");
9. } else {
10. if (threadLocal.get() == null) {
11. threadLocal.set(new HashMap<>());
12. }
13. threadLocal.get().put(key, val);
14. }
15. }
17. public String get(String key) {
18. if (key == null) {
19. throw new IllegalArgumentException("key cannot be null");
20. } else if (threadLocal.get() == null) {
21. return null;
22. } else {
23. return threadLocal.get().get(key);
24. }
25. }
27. public void clear() {
28. if (threadLocal.get() == null) {
29. return;
30. } else {
31. threadLocal.get().clear();
32. }
33. }
34. }
业务使用traceId示例。
1. String traceId = UUID.randomUUID().toString().replaceAll("-", "");
2. openGaussTrace.set(traceId);
3. pstm = con.prepareStatement("select * from test_trace_id where id = ?");
4. pstm.setInt(1, 1);
5. pstm.execute();
6. pstm = con.prepareStatement("insert into test_trace_id values(?,?)");
7. pstm.setInt(1, 2);
8. pstm.setString(2, "test");
9. pstm.execute();
10. openGaussTrace.reset();
注意: