e1d641f9cc157f08dfb7e8d2262428394e8c6f8c
[aai/aai-common.git] / aai-core / src / main / java / org / openecomp / aai / logging / LoggingContext.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * org.openecomp.aai
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.aai.logging;
22
23 import com.att.eelf.configuration.EELFLogger;
24 import com.att.eelf.configuration.EELFManager;
25 import org.json.JSONException;
26 import org.json.JSONObject;
27 import org.slf4j.MDC;
28
29 import java.net.InetAddress;
30 import java.net.UnknownHostException;
31 import java.util.Iterator;
32 import java.util.UUID;
33 import java.util.concurrent.TimeUnit;
34
35 public class LoggingContext {
36
37         public enum StatusCode {
38                 COMPLETE,
39                 ERROR
40         }
41
42         private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(LoggingContext.class);
43
44         private static final String PREVIOUS_CONTEXT_KEY = "_PREVIOUS_CONTEXT";
45
46         //ECOMP Specific Log Event Fields
47         public static enum LoggingField {
48                 START_TIME("startTime"),
49                 REQUEST_ID("requestId"),
50                 SERVICE_INSTANCE_ID("serviceInstanceId"),
51                 SERVER_NAME("serverName"),
52                 SERVICE_NAME("serviceName"),
53                 PARTNER_NAME("partnerName"),
54                 STATUS_CODE("statusCode"),
55                 RESPONSE_CODE("responseCode"),
56                 RESPONSE_DESCRIPTION("responseDescription"),
57                 INSTANCE_UUID("instanceUUID"),
58                 SEVERITY("severity"),
59                 SERVER_IP_ADDRESS("serverIpAddress"),
60                 ELAPSED_TIME("elapsedTime"),
61                 SERVER("server"),
62                 CLIENT_IP_ADDRESS("clientIpAddress"),
63                 UNUSED("unused"),
64                 PROCESS_KEY("processKey"),
65                 CUSTOM_FIELD_1("customField1"),
66                 CUSTOM_FIELD_2("customField2"),
67                 CUSTOM_FIELD_3("customField3"),
68                 CUSTOM_FIELD_4("customField4"),
69                 
70                 //ECOMP Specific Metric Log Event Fields
71                 TARGET_ENTITY("targetEntity"),
72
73                 //A&AI Specific Log Event Fields
74                 COMPONENT("component"),
75                 STOP_WATCH_START("stopWatchStart");
76
77                 private final String text;
78
79                 private LoggingField(final String text) {
80                         this.text = text;
81                 }
82
83                 public String toString() {
84                         return text;
85                 }
86         }
87
88
89         public static void init() {
90                 LoggingContext.clear();
91                 LoggingContext.startTime();
92                 LoggingContext.server();
93                 LoggingContext.serverIpAddress();
94         }
95
96         private static void startTime() {
97                 MDC.put(LoggingField.START_TIME.toString(), LogFormatTools.getCurrentDateTime());
98         }
99
100         public static void requestId(UUID requestId) {
101                 MDC.put(LoggingField.REQUEST_ID.toString(), requestId.toString());
102         }
103
104         public static void requestId(String requestId) {
105                 try {
106                         MDC.put(LoggingField.REQUEST_ID.toString(), UUID.fromString(requestId).toString());
107                 } catch (IllegalArgumentException e) {
108                         final UUID generatedRequestUuid = UUID.randomUUID();
109                         MDC.put(LoggingField.REQUEST_ID.toString(), generatedRequestUuid.toString());
110                         LOGGER.warn("Unable to use UUID " + requestId + " (Not formatted properly). Using generated UUID=" + generatedRequestUuid);
111                 }
112         }
113
114         public static void serviceInstanceId(String serviceInstanceId) {
115                 MDC.put(LoggingField.SERVICE_INSTANCE_ID.toString(), serviceInstanceId);
116         }
117
118         public static void serverName(String serverName) {
119                 MDC.put(LoggingField.SERVER_NAME.toString(), serverName);
120         }
121
122         public static void serviceName(String serviceName) {
123                 MDC.put(LoggingField.SERVICE_NAME.toString(), serviceName);
124         }
125
126         public static void partnerName(String partnerName) {
127                 MDC.put(LoggingField.PARTNER_NAME.toString(), partnerName);
128         }
129
130         public static void statusCode(LoggingContext.StatusCode statusCode) {
131                 MDC.put(LoggingField.STATUS_CODE.toString(), statusCode.toString());
132         }
133
134         public static String responseCode() {
135                 return (String) MDC.get(LoggingField.RESPONSE_CODE.toString());
136         }
137
138         public static void responseCode(String responseCode) {
139                 MDC.put(LoggingField.RESPONSE_CODE.toString(), responseCode);
140         }
141
142         public static void responseDescription(String responseDescription) {
143                 MDC.put(LoggingField.RESPONSE_DESCRIPTION.toString(), responseDescription);
144         }
145
146         public static void instanceUuid(UUID instanceUuid) {
147                 MDC.put(LoggingField.INSTANCE_UUID.toString(), instanceUuid.toString());
148         }
149
150         public static void severity(int severity) {
151                 MDC.put(LoggingField.SEVERITY.toString(), String.valueOf(severity));
152         }
153
154         private static void serverIpAddress() {
155                 try {
156                         MDC.put(LoggingField.SERVER_IP_ADDRESS.toString(), InetAddress.getLocalHost().getHostAddress());
157                 } catch (UnknownHostException e) {
158                         LOGGER.warn("Unable to resolve server IP address - will not be displayed in logged events");
159                 }
160         }
161
162         public static void elapsedTime(long elapsedTime, TimeUnit timeUnit) {
163                 MDC.put(LoggingField.ELAPSED_TIME.toString(), String.valueOf(TimeUnit.MILLISECONDS.convert(elapsedTime, timeUnit)));
164         }
165
166         private static void server() {
167                 try {
168                         MDC.put(LoggingField.SERVER.toString(),  InetAddress.getLocalHost().getCanonicalHostName());
169                 } catch (UnknownHostException e) {
170                         LOGGER.warn("Unable to resolve server IP address - hostname will not be displayed in logged events");
171                 }
172         }
173
174         public static void clientIpAddress(InetAddress clientIpAddress) {
175                 MDC.put(LoggingField.CLIENT_IP_ADDRESS.toString(), clientIpAddress.getHostAddress());
176         }
177
178         public static void clientIpAddress(String clientIpAddress) {
179                 try {
180                         MDC.put(LoggingField.CLIENT_IP_ADDRESS.toString(), InetAddress.getByName(clientIpAddress).getHostAddress());
181                 } catch (UnknownHostException e) {
182                         //Ignore, will not be thrown since InetAddress.getByName(String) only
183                         //checks the validity of the passed in string
184                 }
185         }
186
187         public static void unused(String unused) {
188                 LOGGER.warn("Using field '" + LoggingField.UNUSED + "' (seems like this should go unused...)");
189                 MDC.put(LoggingField.UNUSED.toString(), unused);
190         }
191
192         public static void processKey(String processKey) {
193                 MDC.put(LoggingField.PROCESS_KEY.toString(), processKey);
194         }
195
196         public static void customField1(String customField1) {
197                 MDC.put(LoggingField.CUSTOM_FIELD_1.toString(), customField1);
198         }
199
200         public static void customField2(String customField2) {
201                 MDC.put(LoggingField.CUSTOM_FIELD_2.toString(), customField2);
202         }
203
204         public static void customField3(String customField3) {
205                 MDC.put(LoggingField.CUSTOM_FIELD_3.toString(), customField3);
206         }
207
208         public static void customField4(String customField4) {
209                 MDC.put(LoggingField.CUSTOM_FIELD_4.toString(), customField4);
210         }
211
212         public static void component(String component) {
213                 MDC.put(LoggingField.COMPONENT.toString(), component);
214         }
215
216         public static void targetEntity(String targetEntity) {
217                 MDC.put(LoggingField.TARGET_ENTITY.toString(), targetEntity);
218         }
219
220         public static void stopWatchStart() {
221                 MDC.put(LoggingField.STOP_WATCH_START.toString(), String.valueOf(System.nanoTime()));
222         }
223
224         public static double stopWatchStop() {
225                 final long stopWatchEnd = System.nanoTime();
226                 final Long stopWatchStart = Long.valueOf(MDC.get(LoggingField.STOP_WATCH_START.toString()));
227
228                 if (stopWatchStart == null) throw new StopWatchNotStartedException();
229
230                 MDC.remove(LoggingField.STOP_WATCH_START.toString());
231
232                 final double elapsedTimeMillis = (stopWatchEnd - stopWatchStart) / 1000.0 / 1000.0;
233
234                 LoggingContext.elapsedTime((long) elapsedTimeMillis, TimeUnit.MILLISECONDS);
235
236                 return elapsedTimeMillis;
237         }
238
239         public static void put(String key, String value) {
240                 MDC.put(key, value);
241         }
242
243         public static void clear() {
244                 MDC.clear();
245         }
246
247         public static void remove(String key) {
248                 MDC.remove(key);
249         }
250
251         public static void save() {
252                 final JSONObject context = new JSONObject();
253
254                 for (LoggingField field : LoggingField.values()) {
255                         if (field == LoggingField.ELAPSED_TIME) continue;
256
257                         try {
258                                 context.put(field.toString(), MDC.get(field.toString()));
259                         } catch (JSONException e) {
260                                 //Ignore - only occurs when the key is null (which can't happen)
261                                 //                      or the value is invalid (everything is converted to a string
262                                 //                      before it get put() to the MDC)
263                         }
264                 }
265
266                 MDC.put("_PREVIOUS_CONTEXT", context.toString());
267         }
268
269         public static void restore() {
270                 
271                 final String rawPreviousContext = MDC.get(PREVIOUS_CONTEXT_KEY);
272         
273                 if (rawPreviousContext == null) {
274                         throw new LoggingContextNotExistsException();
275                 }
276
277                 try {
278                         final JSONObject previousContext = new JSONObject(rawPreviousContext);
279
280                         @SuppressWarnings("unchecked")
281                         final Iterator<String> keys = previousContext.keys();
282         
283                         while (keys.hasNext()) {
284                                 final String key = keys.next();
285
286                                 try {
287                                         MDC.put(key, previousContext.getString(key));
288                                 } catch (JSONException e) {
289                                         //Ignore, only occurs when the key is null (cannot happen)
290                                         //                      or the value is invalid (they are all strings)
291                                 }
292                         }
293         
294                         MDC.remove(PREVIOUS_CONTEXT_KEY);
295                 } catch (JSONException e) {
296                         //Ignore, the previousContext is serialized from a JSONObject
297                 }
298         }
299 }