a708ed6715666cfa3ab086276bd5e5b5f17c8382
[sdc.git] /
1 /*
2  * Copyright © 2016-2017 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.logging;
18
19 import java.net.InetAddress;
20 import java.net.UnknownHostException;
21 import java.util.UUID;
22 import java.util.concurrent.atomic.AtomicLong;
23 import java.util.prefs.BackingStoreException;
24 import java.util.prefs.Preferences;
25
26 /**
27  * Collect information the is required for logging, but should not concern the business code of an application. For
28  * example, host name and IP address.
29  *
30  * @author evitaliy
31  * @since 04 Mar 2018
32  */
33 @SuppressWarnings({"UseOfSystemOutOrSystemErr", "CallToPrintStackTrace", "squid:S106", "squid:S1148"})
34 public class GlobalLoggingContext {
35
36     // should be cashed to avoid low-level call, but with a timeout to account for IP or FQDN changes
37     private static final HostAddressCache HOST_ADDRESS_CACHE = new HostAddressCache();
38
39     @SuppressWarnings("squid:S1075")
40     private static final String INSTANCE_UUID_PREFERENCES_PATH = "/logging/instance/uuid";
41
42     private static final String INSTANCE_ID;
43
44     static {
45         INSTANCE_ID = readInstanceId();
46     }
47
48     private GlobalLoggingContext() {
49         // prevent instantiation
50     }
51
52     /**
53      * A unique ID of the logging entity. Is useful to distinguish between different nodes of the same application. It
54      * is assumed, that the node can be re-started, in which case the unique ID must be retained.
55      *
56      * @return unique logging entity ID
57      */
58     public static String getInstanceId() {
59         return INSTANCE_ID;
60     }
61
62     /**
63      * Local host address as returned by Java runtime. A value of host address will be cached for the interval specified
64      * in {@link HostAddressCache#REFRESH_TIME}
65      *
66      * @return local host address, may be null if could not be read for some reason
67      */
68     public static InetAddress getHostAddress() {
69         return HOST_ADDRESS_CACHE.get();
70     }
71
72     private static String readInstanceId() {
73
74         try {
75
76             // On Linux, by default this will be ~/.java/.userPrefs/prefs.xml
77             final Preferences preferences = Preferences.userRoot();
78             String existingId = preferences.get(INSTANCE_UUID_PREFERENCES_PATH, null);
79             if (existingId != null) {
80                 return existingId;
81             }
82
83             String newId = UUID.randomUUID().toString();
84             preferences.put(INSTANCE_UUID_PREFERENCES_PATH, newId);
85             preferences.flush();
86             return newId;
87
88         } catch (BackingStoreException e) {
89             e.printStackTrace();
90             // don't fail if there's a problem to use the store for some unexpected reason
91             return UUID.randomUUID().toString();
92         }
93     }
94
95     private static class HostAddressCache {
96
97         private static final long REFRESH_TIME = 60000L;
98
99         private final AtomicLong lastUpdated = new AtomicLong(0L);
100         private InetAddress hostAddress;
101
102         InetAddress get() {
103
104             long current = System.currentTimeMillis();
105             if (current - lastUpdated.get() > REFRESH_TIME) {
106
107                 synchronized (this) {
108
109                     try {
110                         // set now to register the attempt even if failed
111                         lastUpdated.set(current);
112                         hostAddress = InetAddress.getLocalHost();
113                     } catch (UnknownHostException e) {
114                         e.printStackTrace(); // can't really use logging
115                         hostAddress = null;
116                     }
117                 }
118             }
119
120             return hostAddress;
121         }
122     }
123 }