fluent-logger-java
fluent-logger-java copied to clipboard
Initial UnknownHostException is Unrecoverable
The RawSocketSender
takes a host and port in its constructor and coverts these into an InetSocketAddress
, which tries to resolve the hostname. On RawSocketSender
connect this InetSocketAddress
is used to reconnect, but if it wasn't resolved during fluent-logger init then it will fail over and over. The code snipped from RawSocketSender
is below:
public RawSocketSender(String host, int port, int timeout, int bufferCapacity, Reconnector reconnector) {
msgpack = new MessagePack();
msgpack.register(Event.class, Event.EventTemplate.INSTANCE);
pendings = ByteBuffer.allocate(bufferCapacity);
server = new InetSocketAddress(host, port); // Create InetSocketAddress on init
this.reconnector = reconnector;
name = String.format("%s_%d_%d_%d", host, port, timeout, bufferCapacity);
this.timeout = timeout;
}
private void connect() throws IOException {
try {
socket = new Socket();
socket.connect(server, timeout); // Reconnection uses pre-resolved server field
out = new BufferedOutputStream(socket.getOutputStream());
} catch (IOException e) {
throw e;
}
}
This issue comes up when using the fluent-logger in a highly dynamic environment (like on Docker Swarm) where apps may come up before a DNS entry in Consul is even resolvable. It also means that during failover of a Fluent host (triggering a DNS change) the then failing socket connection will always try the old Fluent host IP and never re-resolve the DNS entry.
My recommendation is to store the Fluent host and port as private fields within the RawSocketSender
, not a resolved InetSocketAddress
(now stored as this.server
) and create a new InetSocketAddress
on every socket connection.
I understand there will be performance implications of this and am happy to submit a PR, but wanted to bring it up in an issue in case there were reasons for implementing the RawSocketSender
the current way.
The performance implication could mitigated. The JVM has a DNS lookup cache for which ttl is customizable, most OS as well. So what would be the drawback of what you suggested ?