Permalink
Browse files

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
  • Loading branch information...
davecramer committed Mar 23, 2017
1 parent 95a3f41 commit b97ad63089a9042cfef0ce97d1eaacce0fe47d4e
@@ -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>
@@ -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>
@@ -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.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 @@ private void setupLoggerFromProperties(final Properties props) {
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 @@ private void setupLoggerFromProperties(final Properties props) {
}
}

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);
}
@@ -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();
}
}
@@ -13,15 +13,20 @@

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 void testRegistration() throws Exception {
}
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);


}

}

}
@@ -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) {

}
}

0 comments on commit b97ad63

Please sign in to comment.