Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Temporary workaround to avoid debug logging from Netty.
- Because this will go into patch release, silence stdout while Netty logging loads. In next major or minor release, we'll fix this by either removing Slf4j from the classpath or configuring it properly.
- Loading branch information
Showing
4 changed files
with
222 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
community/server/src/main/java/org/neo4j/server/logging/Netty4LogBridge.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (c) 2002-2015 "Neo Technology," | ||
* Network Engine for Objects in Lund AB [http://neotechnology.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Neo4j is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.neo4j.server.logging; | ||
|
||
import io.netty.util.internal.logging.InternalLoggerFactory; | ||
|
||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
import java.io.PrintStream; | ||
|
||
import org.neo4j.logging.LogProvider; | ||
|
||
/** | ||
* Glue code for swapping in Neo4j logging into Netty4 | ||
*/ | ||
public class Netty4LogBridge | ||
{ | ||
private static final PrintStream NULL_OUTPUT = new PrintStream( new NullOutput() ); | ||
|
||
public static void setLogProvider( LogProvider logProvider ) | ||
{ | ||
// TODO: Undo below hack in next minor/major release | ||
// Netty 4 will look for and use Slf4j if it's on the classpath. In this release (2.3.x), | ||
// it is on the classpath, via `logback-classic`. However, we do not configure logback, | ||
// meaning some debug output leaks to stdout before we replace the logging below. | ||
// This should be fixed properly in the next release that is not a patch release. | ||
PrintStream originalStdOut = System.out; | ||
try | ||
{ | ||
System.setOut( NULL_OUTPUT ); | ||
InternalLoggerFactory.setDefaultFactory( new Netty4LoggerFactory( logProvider ) ); | ||
} | ||
finally | ||
{ | ||
System.setOut( originalStdOut ); | ||
} | ||
|
||
} | ||
|
||
private static class NullOutput extends OutputStream | ||
{ | ||
@Override | ||
public void write( int b ) throws IOException | ||
{ | ||
// no-op | ||
} | ||
} | ||
} |
132 changes: 132 additions & 0 deletions
132
community/server/src/test/java/org/neo4j/server/integration/StartupLoggingIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* | ||
* Copyright (c) 2002-2015 "Neo Technology," | ||
* Network Engine for Objects in Lund AB [http://neotechnology.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Neo4j is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.neo4j.server.integration; | ||
|
||
import org.hamcrest.Description; | ||
import org.hamcrest.Matcher; | ||
import org.hamcrest.TypeSafeMatcher; | ||
import org.junit.Test; | ||
|
||
import java.util.List; | ||
import java.util.concurrent.Callable; | ||
|
||
import org.neo4j.server.CommunityBootstrapper; | ||
import org.neo4j.test.SuppressOutput; | ||
import org.neo4j.test.server.ExclusiveServerTestBase; | ||
|
||
import static java.util.Arrays.asList; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
public class StartupLoggingIT extends ExclusiveServerTestBase | ||
{ | ||
@Test | ||
public void shouldLogHelpfulStartupMessages() throws Throwable | ||
{ | ||
// Given | ||
SuppressOutput suppressed = SuppressOutput.suppressAll(); | ||
|
||
// When | ||
suppressed.call( new Callable<Object>() | ||
{ | ||
@Override | ||
public Object call() throws Exception | ||
{ | ||
CommunityBootstrapper boot = new CommunityBootstrapper(); | ||
CommunityBootstrapper.start( boot, new String[]{} ); | ||
boot.stop(); | ||
return null; | ||
} | ||
}); | ||
|
||
// Then | ||
List<String> captured = suppressed.getOutputVoice().lines(); | ||
// TODO: Obviously the logging below is insane, but we added this test in a point release, so we don't want to break anyone grepping for this | ||
// This should be changed in 3.0.0. | ||
assertThat( captured, matchesLines( | ||
warn( "Config file \\[config/neo4j-server.properties\\] does not exist." ), | ||
warn( "Config file \\[config/neo4j.properties\\] does not exist." ), | ||
info( "Successfully started database" ), | ||
info( "Starting HTTP on port 7474 \\(.+ threads available\\)" ), | ||
info( "Mounting static content at /webadmin" ), | ||
info( "Mounting static content at /browser" ), | ||
info( "Remote interface ready and available at http://.+:7474/" ), | ||
|
||
info( "Successfully shutdown Neo4j Server" ), | ||
info( "Successfully stopped database" ), | ||
info( "Successfully shutdown database" ), | ||
info( "Successfully shutdown Neo Server on port \\[.+\\], database \\[.+\\]") | ||
) ); | ||
} | ||
|
||
public static Matcher<List<String>> matchesLines( final Matcher<String> ... lineMatchers ) | ||
{ | ||
return new TypeSafeMatcher<List<String>>() | ||
{ | ||
@Override | ||
protected boolean matchesSafely( List<String> lines ) | ||
{ | ||
if(lineMatchers.length != lines.size()) | ||
{ | ||
return false; | ||
} | ||
|
||
for ( int i = 0; i < lines.size(); i++ ) | ||
{ | ||
if( !lineMatchers[i].matches( lines.get( i ) ) ) | ||
{ | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
@Override | ||
public void describeTo( Description description ) | ||
{ | ||
description.appendList( "", "\n", "", asList(lineMatchers) ); | ||
} | ||
}; | ||
} | ||
|
||
public static Matcher<String> info( String messagePattern ) { return line("INFO", messagePattern); } | ||
public static Matcher<String> warn( String messagePattern ) { return line("WARN", messagePattern); } | ||
|
||
public static Matcher<String> line( final String level, final String messagePattern ) | ||
{ | ||
return new TypeSafeMatcher<String>() | ||
{ | ||
@Override | ||
protected boolean matchesSafely( String line ) | ||
{ | ||
// eg. 2015-10-27 15:44:18.049-0500 INFO Successfully started database | ||
// Assert rather than return boolean, to get the exact line in the error output | ||
assertTrue( "[" + line + "] should match pattern [" + messagePattern + "]", line.matches( ".*" + level + "\\s+" + messagePattern )); | ||
return true; | ||
} | ||
|
||
@Override | ||
public void describeTo( Description description ) | ||
{ | ||
description.appendText( level ).appendText( " " ).appendText( messagePattern ); | ||
} | ||
}; | ||
} | ||
} |