postgresql-jdbc.git / summary / log / commit / refs
commit b97ad63089a9042cfef0ce97d1eaacce0fe47d4e
Author: Dave Cramer <davecramer@gmail.com>
Commit: GitHub <noreply@github.com>
Date: Thu Mar 23 12:08:36 2017 +0000
Honour setLogStream. If the logStream is set (#780)
* Honour setLogStream. If the logStream is set
then use it to output logs
Also set the parent logger level to the log level
requested.
* Added a WriterHandler, borrowed and attributed to apache
suppress our copyright check for that file
added the first test case for WriterHandler
* added seperate test for setLogStream
* suppress the output from the logging tests
* moved utility class to test
pgjdbc/pom.xml | 1 +
pgjdbc/src/main/checkstyle/suppressions.xml | 9 ++
pgjdbc/src/main/java/org/postgresql/Driver.java | 23 +++-
.../java/org/postgresql/util/WriterHandler.java | 125 +++++++++++++++++++++
.../java/org/postgresql/test/jdbc2/DriverTest.java | 75 +++++++++++++
.../java/org/postgresql/util/NullOutputStream.java | 29 +++++
6 files changed, 260 insertions(+), 2 deletions(-)
diff --git a/pgjdbc/pom.xml b/pgjdbc/pom.xml
index 0d2ba622..f78fa4f6 100644
--- a/pgjdbc/pom.xml
+++ b/pgjdbc/pom.xml
@@ -266,6 +266,7 @@
</dependencies>
<configuration>
<configLocation>src/main/checkstyle/checks.xml</configLocation>
+ <suppressionsLocation>src/main/checkstyle/suppressions.xml</suppressionsLocation>
<violationSeverity>error</violationSeverity>
<failOnViolation>true</failOnViolation>
<failsOnError>true</failsOnError>
diff --git a/pgjdbc/src/main/checkstyle/suppressions.xml b/pgjdbc/src/main/checkstyle/suppressions.xml
new file mode 100644
index 00000000..76e50708
--- /dev/null
+++ b/pgjdbc/src/main/checkstyle/suppressions.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE suppressions PUBLIC
+ "-//Puppy Crawl//DTD Suppressions 1.1//EN"
+ "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
+
+<suppressions>
+ <suppress files="WriterHandler\.java" checks="RegexpHeader"/>
+</suppressions>
diff --git a/pgjdbc/src/main/java/org/postgresql/Driver.java b/pgjdbc/src/main/java/org/postgresql/Driver.java
index d471f4d9..27c6b486 100644
--- a/pgjdbc/src/main/java/org/postgresql/Driver.java
+++ b/pgjdbc/src/main/java/org/postgresql/Driver.java
@@ -6,12 +6,14 @@
package org.postgresql;
import org.postgresql.jdbc.PgConnection;
+
import org.postgresql.util.ExpressionProperties;
import org.postgresql.util.GT;
import org.postgresql.util.HostSpec;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
import org.postgresql.util.SharedTimer;
+import org.postgresql.util.WriterHandler;
import java.io.IOException;
import java.io.InputStream;
@@ -29,8 +31,11 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Set;
+import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.logging.SimpleFormatter;
+import java.util.logging.StreamHandler;
/**
* The Java SQL framework allows for multiple database drivers. Each driver should supply a class
@@ -308,7 +313,7 @@ public class Driver implements java.sql.Driver {
loggerHandlerFile = null;
}
- java.util.logging.Handler handler = new java.util.logging.ConsoleHandler();
+ java.util.logging.Handler handler = null;
if (driverLogFile != null) {
try {
handler = new java.util.logging.FileHandler(driverLogFile);
@@ -318,7 +323,21 @@ public class Driver implements java.sql.Driver {
}
}
- handler.setFormatter(new java.util.logging.SimpleFormatter());
+ Formatter formatter = new SimpleFormatter();
+
+ if ( handler == null ) {
+ if (DriverManager.getLogWriter() != null) {
+ handler = new WriterHandler(DriverManager.getLogWriter());
+ } else if ( DriverManager.getLogStream() != null) {
+ handler = new StreamHandler(DriverManager.getLogStream(), formatter);
+ } else {
+ handler = new StreamHandler(System.err, formatter);
+ }
+ } else {
+ handler.setFormatter(formatter);
+ }
+
+ handler.setLevel(PARENT_LOGGER.getLevel());
PARENT_LOGGER.setUseParentHandlers(false);
PARENT_LOGGER.addHandler(handler);
}
diff --git a/pgjdbc/src/main/java/org/postgresql/util/WriterHandler.java b/pgjdbc/src/main/java/org/postgresql/util/WriterHandler.java
new file mode 100644
index 00000000..822f9536
--- /dev/null
+++ b/pgjdbc/src/main/java/org/postgresql/util/WriterHandler.java
@@ -0,0 +1,125 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.postgresql.util;
+
+import java.io.Writer;
+
+import java.util.logging.ErrorManager;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.SimpleFormatter;
+
+public class WriterHandler extends Handler {
+
+ private boolean doneHeader;
+
+ private Writer writer;
+
+ public WriterHandler(Writer inWriter) {
+ super();
+ setLevel(Level.INFO);
+ setFilter(null);
+ setFormatter(new SimpleFormatter());
+ writer = inWriter;
+ }
+
+ public WriterHandler(Writer inWriter, Formatter formatter) {
+ super();
+ setLevel(Level.INFO);
+ setFilter(null);
+ setFormatter(formatter);
+ writer = inWriter;
+
+ }
+
+ public synchronized void publish(final LogRecord record) {
+ if (!isLoggable(record)) {
+ return;
+ }
+ String msg;
+ try {
+ msg = getFormatter().format(record);
+ } catch (Exception ex) {
+ // We don't want to throw an exception here, but we
+ // report the exception to any registered ErrorManager.
+ reportError(null, ex, ErrorManager.FORMAT_FAILURE);
+ return;
+ }
+
+ try {
+ if (!doneHeader) {
+ writer.write(getFormatter().getHead(this));
+ doneHeader = true;
+ }
+ writer.write(msg);
+ } catch (Exception ex) {
+ // We don't want to throw an exception here, but we
+ // report the exception to any registered ErrorManager.
+ reportError(null, ex, ErrorManager.WRITE_FAILURE);
+ }
+ }
+
+ public boolean isLoggable(final LogRecord record) {
+ if (writer == null || record == null) {
+ return false;
+ }
+ return super.isLoggable(record);
+ }
+
+ public synchronized void flush() {
+ if (writer != null) {
+ try {
+ writer.flush();
+ } catch (Exception ex) {
+ // We don't want to throw an exception here, but we
+ // report the exception to any registered ErrorManager.
+ reportError(null, ex, ErrorManager.FLUSH_FAILURE);
+ }
+ }
+ }
+
+ private synchronized void flushAndClose() throws SecurityException {
+
+ if (writer != null) {
+ try {
+ if (!doneHeader) {
+ writer.write(getFormatter().getHead(this));
+ doneHeader = true;
+ }
+ writer.write(getFormatter().getTail(this));
+ writer.flush();
+ writer.close();
+ } catch (Exception ex) {
+ // We don't want to throw an exception here, but we
+ // report the exception to any registered ErrorManager.
+ reportError(null, ex, ErrorManager.CLOSE_FAILURE);
+ }
+ writer = null;
+
+ }
+ }
+
+ public synchronized void close() throws SecurityException {
+ flushAndClose();
+ }
+}
diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DriverTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DriverTest.java
index 9d26beaf..07416d81 100644
--- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DriverTest.java
+++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DriverTest.java
@@ -13,15 +13,20 @@ import static org.junit.Assert.fail;
import org.postgresql.Driver;
import org.postgresql.test.TestUtil;
+import org.postgresql.util.NullOutputStream;
+import org.postgresql.util.WriterHandler;
import org.junit.Test;
+import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;
+import java.util.logging.Handler;
+import java.util.logging.Logger;
/*
* Tests the dynamically created class org.postgresql.Driver
@@ -180,4 +185,74 @@ public class DriverTest {
}
fail("Driver has not been found in DriverManager's list but it should be registered");
}
+
+ @Test
+ public void testSetLogWriter() throws Exception {
+
+ // this is a dummy to make sure TestUtil is initialized
+ Connection con = DriverManager.getConnection(TestUtil.getURL(), TestUtil.getUser(), TestUtil.getPassword());
+ con.close();
+ String loggerLevel = System.getProperty("loggerLevel");
+ String loggerFile = System.getProperty("loggerFile");
+
+ try {
+
+ PrintWriter printWriter = new PrintWriter(new NullOutputStream(System.err));
+ DriverManager.setLogWriter(printWriter);
+ assertEquals(DriverManager.getLogWriter(), printWriter);
+ System.clearProperty("loggerFile");
+ System.clearProperty("loggerLevel");
+ Properties props = new Properties();
+ props.setProperty("user", TestUtil.getUser());
+ props.setProperty("password", TestUtil.getPassword());
+ props.setProperty("loggerLevel", "DEBUG");
+ con = DriverManager.getConnection(TestUtil.getURL(), props);
+
+ Logger logger = Logger.getLogger("org.postgresql");
+ Handler[] handlers = logger.getHandlers();
+ assertTrue(handlers[0] instanceof WriterHandler );
+ con.close();
+ } finally {
+ DriverManager.setLogWriter(null);
+ System.setProperty("loggerLevel", loggerLevel);
+ System.setProperty("loggerFile", loggerFile);
+
+ }
+
+ }
+
+ @Test
+ public void testSetLogStream() throws Exception {
+
+ // this is a dummy to make sure TestUtil is initialized
+ Connection con = DriverManager.getConnection(TestUtil.getURL(), TestUtil.getUser(), TestUtil.getPassword());
+ con.close();
+ String loggerLevel = System.getProperty("loggerLevel");
+ String loggerFile = System.getProperty("loggerFile");
+
+ try {
+
+ DriverManager.setLogStream(new NullOutputStream(System.err));
+ System.clearProperty("loggerFile");
+ System.clearProperty("loggerLevel");
+ Properties props = new Properties();
+ props.setProperty("user", TestUtil.getUser());
+ props.setProperty("password", TestUtil.getPassword());
+ props.setProperty("loggerLevel", "DEBUG");
+ con = DriverManager.getConnection(TestUtil.getURL(), props);
+
+ Logger logger = Logger.getLogger("org.postgresql");
+ Handler []handlers = logger.getHandlers();
+ assertTrue( handlers[0] instanceof WriterHandler );
+ con.close();
+ } finally {
+ DriverManager.setLogStream(null);
+ System.setProperty("loggerLevel", loggerLevel);
+ System.setProperty("loggerFile", loggerFile);
+
+
+ }
+
+ }
+
}
diff --git a/pgjdbc/src/test/java/org/postgresql/util/NullOutputStream.java b/pgjdbc/src/test/java/org/postgresql/util/NullOutputStream.java
new file mode 100644
index 00000000..764dc1ac
--- /dev/null
+++ b/pgjdbc/src/test/java/org/postgresql/util/NullOutputStream.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, PostgreSQL Global Development Group
+ * See the LICENSE file in the project root for more information.
+ */
+
+package org.postgresql.util;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * Created by davec on 3/14/17.
+ */
+public class NullOutputStream extends PrintStream {
+
+ public NullOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ @Override
+ public void write(int b) {
+
+ }
+
+ @Override
+ public void write(byte[] buf, int off, int len) {
+
+ }
+}
[parent: 95a3f41d6c0d]