From 7bfc8089071c675b2dcdf557a896ffe4cf6953b0 Mon Sep 17 00:00:00 2001 From: vempo Date: Sun, 29 Apr 2018 18:34:48 +0300 Subject: Added fallback for host address in logging In some cases Java fails to get local hostname on Linux. Added a workaround that in such cases gets at least some meaningful host identification. Change-Id: Icf9b84ec6a0d6fbcbcb6a1578689b3e3be00261b Issue-ID: SDC-1275 Signed-off-by: vempo --- .../sdc/logging/context/HostAddressCache.java | 66 ++++++++++++++++++++-- .../sdc/logging/slf4j/GlobalContextProvider.java | 11 ++-- .../sdc/logging/context/HostAddressCacheTest.java | 4 +- 3 files changed, 68 insertions(+), 13 deletions(-) (limited to 'openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src') diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/context/HostAddressCache.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/context/HostAddressCache.java index afe2b0b1d1..0930888aac 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/context/HostAddressCache.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/context/HostAddressCache.java @@ -17,7 +17,11 @@ package org.openecomp.sdc.logging.context; import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; import java.net.UnknownHostException; +import java.util.Enumeration; +import java.util.Optional; /** * Holds a reference to local host address as returned by Java runtime. A value of host address will be cached for the @@ -28,7 +32,7 @@ import java.net.UnknownHostException; * @author evitaliy * @since 26 Mar 2018 */ -@SuppressWarnings({"UseOfSystemOutOrSystemErr", "CallToPrintStackTrace", "squid:S106", "squid:S1148"}) +@SuppressWarnings({"UseOfSystemOutOrSystemErr", "CallToPrintStackTrace", "squid:S106", "squid:S1148", "squid:S1166"}) public class HostAddressCache { private static final long DEFAULT_REFRESH_INTERVAL = 60000L; // 1 min @@ -54,16 +58,16 @@ public class HostAddressCache { * * @return local host address or null if it could not be read for some reason */ - public synchronized InetAddress get() { + public synchronized Optional get() { long current = System.currentTimeMillis(); if (current - cachedAddress.lastUpdated < interval) { - return cachedAddress.address; + return Optional.ofNullable(cachedAddress.address); } - InetAddress address = read(); + InetAddress address = read(); // register the attempt even if null, i.e. failed to get a meaningful address cachedAddress = new CacheEntry(current, address); - return address; + return Optional.ofNullable(address); } private InetAddress read() { @@ -71,9 +75,59 @@ public class HostAddressCache { try { return InetAddress.getLocalHost(); } catch (UnknownHostException e) { + System.err.println( + "[WARNING] Failed to get local host address. Using a fallback. If you are on Linux, make sure " + + "/etc/hosts contains the host name of your machine, " + + "e.g. '127.0.0.1 localhost my-host.example.com'."); + + e.printStackTrace(); // can't really use logging + return getFallbackLocalHost(); + } + } + + private InetAddress getFallbackLocalHost() { + + try { + + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + + while (networkInterfaces.hasMoreElements()) { + + InetAddress address = getAddress(networkInterfaces.nextElement()); + if (address != null) { + return address; + } + } + + return null; + + } catch (SocketException e) { e.printStackTrace(); // can't really use logging - return null; // let register the attempt even if failed + return null; + } + } + + private InetAddress getAddress(NetworkInterface networkInterface) throws SocketException { + + if (networkInterface.isLoopback() || networkInterface.isUp()) { + return null; } + + Enumeration interfaceAddresses = networkInterface.getInetAddresses(); + while (interfaceAddresses.hasMoreElements()) { + + InetAddress address = interfaceAddresses.nextElement(); + if (isHostAddress(address)) { + return address; + } + } + + return null; + } + + private boolean isHostAddress(InetAddress address) { + return !address.isLoopbackAddress() && !address.isAnyLocalAddress() && !address.isLinkLocalAddress() + && !address.isMulticastAddress(); } private static class CacheEntry { diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/GlobalContextProvider.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/GlobalContextProvider.java index 97cac2e9ca..f6e933d57b 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/GlobalContextProvider.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/main/java/org/openecomp/sdc/logging/slf4j/GlobalContextProvider.java @@ -19,6 +19,7 @@ package org.openecomp.sdc.logging.slf4j; import java.net.InetAddress; import java.util.EnumMap; import java.util.Map; +import java.util.Optional; import org.openecomp.sdc.logging.context.HostAddressCache; import org.openecomp.sdc.logging.context.InstanceId; @@ -38,11 +39,11 @@ class GlobalContextProvider implements ContextProvider { Map values = new EnumMap<>(ContextField.class); values.put(ContextField.INSTANCE_ID, InstanceId.get()); - InetAddress hostAddress = HOST_ADDRESS_CACHE.get(); - if (hostAddress != null) { - values.put(ContextField.SERVER, hostAddress.getHostName()); - values.put(ContextField.SERVER_IP_ADDRESS, hostAddress.getHostAddress()); - } + Optional hostAddress = HOST_ADDRESS_CACHE.get(); + hostAddress.ifPresent(address -> { + values.put(ContextField.SERVER, address.getHostName()); + values.put(ContextField.SERVER_IP_ADDRESS, address.getHostAddress()); + }); return values; } diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/context/HostAddressCacheTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/context/HostAddressCacheTest.java index 6d7a636840..f75b634177 100644 --- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/context/HostAddressCacheTest.java +++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-core/src/test/java/org/openecomp/sdc/logging/context/HostAddressCacheTest.java @@ -16,7 +16,7 @@ package org.openecomp.sdc.logging.context; -import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; import java.net.InetAddress; import java.net.UnknownHostException; @@ -37,7 +37,7 @@ public class HostAddressCacheTest extends PowerMockTestCase { @Test public void hostAddressIsAlwaysPopulated() { - assertNotNull(new HostAddressCache().get()); + assertTrue(new HostAddressCache().get().isPresent()); } @Test -- cgit 1.2.3-korg