Initial commit with all the necessary files
[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 }