Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redirect server output #12

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 34 additions & 10 deletions src/main/java/redis/embedded/AbstractRedisInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ abstract class AbstractRedisInstance implements Redis {
private Process redisProcess;
private final int port;

private ExecutorService executor;
private ExecutorService executor = Executors.newSingleThreadExecutor();
private PrintStream out = null; //Ignore Redis output.
private PrintStream err = System.err; //Forward Redis error messages to STDERR.

protected AbstractRedisInstance(int port) {
this.port = port;
Expand All @@ -42,14 +44,26 @@ public synchronized void start() throws EmbeddedRedisException {

private void logErrors() {
final InputStream errorStream = redisProcess.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));
Runnable printReaderTask = new PrintReaderRunnable(reader);
executor = Executors.newSingleThreadExecutor();
executor.submit(printReaderTask);
copyStreamInBackground(errorStream, err);
}

private void copyStreamInBackground(final InputStream copyFrom, PrintStream copyTo) {
BufferedReader reader = new BufferedReader(new InputStreamReader(copyFrom));
Runnable printReaderTask = new PrintReaderRunnable(reader, copyTo);
executor.submit(printReaderTask);
}

public void outTo(PrintStream out) {
this.out = out;
}

public void errTo(PrintStream err) {
this.err = err;
}

private void awaitRedisServerReady() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(redisProcess.getInputStream()));
InputStream stdoutStream = redisProcess.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdoutStream));
try {
StringBuffer outputStringBuffer = new StringBuffer();
String outputLine;
Expand All @@ -62,10 +76,18 @@ private void awaitRedisServerReady() throws IOException {
else{
outputStringBuffer.append("\n");
outputStringBuffer.append(outputLine);
if(out != null) {
out.println(outputLine);
}
}
} while (!outputLine.matches(redisReadyPattern()));
} finally {
IOUtils.closeQuietly(reader);
if(out != null) {
/* Continue reading of STDOUT in a background thread. */
copyStreamInBackground(stdoutStream, out);
} else {
IOUtils.closeQuietly(reader);
}
}
}

Expand Down Expand Up @@ -103,9 +125,11 @@ public List<Integer> ports() {

private static class PrintReaderRunnable implements Runnable {
private final BufferedReader reader;
private final PrintStream outputStream;

private PrintReaderRunnable(BufferedReader reader) {
private PrintReaderRunnable(BufferedReader reader, PrintStream outputStream) {
this.reader = reader;
this.outputStream = outputStream;
}

public void run() {
Expand All @@ -120,10 +144,10 @@ public void readLines() {
try {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
outputStream.println(line);
}
} catch (IOException e) {
e.printStackTrace();
/* reader has been closed. The connected Redis instance has possibly shut down. */
}
}
}
Expand Down
36 changes: 34 additions & 2 deletions src/main/java/redis/embedded/RedisSentinelBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -32,7 +33,9 @@ public class RedisSentinelBuilder {
private String sentinelConf;

private StringBuilder redisConfigBuilder;

private PrintStream out = null; //Ignore Redis output.
private PrintStream err = System.err; //Forward Redis error messages to STDERR.

public RedisSentinelBuilder redisExecProvider(RedisExecProvider redisExecProvider) {
this.redisExecProvider = redisExecProvider;
return this;
Expand Down Expand Up @@ -100,10 +103,39 @@ public RedisSentinelBuilder setting(String configLine) {
return this;
}

/**
* Redirect Redis server messages sent to STDOUT.
* Usage example:
* @code{
* RedisServerBuilder serverBuilder = RedisServer.builder().outTo(System.out).errTo(System.err);
RedisSentinelBuilder sentinelBuilder = new RedisSentinelBuilder().outTo(System.out).errTo(System.err);
RedisCluster.builder().withServerBuilder(serverBuilder).withSentinelBuilder(sentinelBuilder)... }
* @param out Stream to redirect Redis output to.
* @return {@code this}
*/
public RedisSentinelBuilder outTo(PrintStream out) {
this.out = out;
return this;
}

/**
* Redirect Redis server messages sent to STDERR.
* @param err Stream to redirect Redis output to.
* Usage example: @code{builder.errTo(System.err);}
* @return {@code itself}
*/
public RedisSentinelBuilder errTo(PrintStream err) {
this.err = err;
return this;
}

public RedisSentinel build() {
tryResolveConfAndExec();
List<String> args = buildCommandArgs();
return new RedisSentinel(args, port);
RedisSentinel sentinel = new RedisSentinel(args, port);
sentinel.outTo(out);
sentinel.errTo(err);
return sentinel;
}

private void tryResolveConfAndExec() {
Expand Down
30 changes: 29 additions & 1 deletion src/main/java/redis/embedded/RedisServerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.ArrayList;
Expand All @@ -21,6 +22,8 @@ public class RedisServerBuilder {
private int port = 6379;
private InetSocketAddress slaveOf;
private String redisConf;
private PrintStream out = null; //Ignore Redis output.
private PrintStream err = System.err; //Forward Redis error messages to STDERR.

private StringBuilder redisConfigBuilder;

Expand Down Expand Up @@ -71,11 +74,36 @@ public RedisServerBuilder setting(String configLine) {
return this;
}

/**
* Redirect Redis server messages sent to STDOUT.
* Usage example: @code{builder.outTo(System.out);}
* @param out Stream to receive Redis output.
* @return {@code this}
*/
public RedisServerBuilder outTo(PrintStream out) {
this.out = out;
return this;
}

/**
* Redirect Redis server messages sent to STDERR.
* @param err Stream to receive Redis output.
* Usage example: @code{builder.errTo(System.err);}
* @return {@code itself}
*/
public RedisServerBuilder errTo(PrintStream err) {
this.err = err;
return this;
}

public RedisServer build() {
setting("bind "+bind);
tryResolveConfAndExec();
List<String> args = buildCommandArgs();
return new RedisServer(args, port);
RedisServer server = new RedisServer(args, port);
server.outTo(out);
server.errTo(err);
return server;
}

public void reset() {
Expand Down