2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.aai.logging;
23 import com.att.eelf.configuration.EELFLogger;
24 import com.att.eelf.configuration.EELFManager;
25 import org.json.JSONException;
26 import org.json.JSONObject;
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;
35 public class LoggingContext {
37 public enum StatusCode {
42 private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(LoggingContext.class);
44 private static final String PREVIOUS_CONTEXT_KEY = "_PREVIOUS_CONTEXT";
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"),
59 SERVER_IP_ADDRESS("serverIpAddress"),
60 ELAPSED_TIME("elapsedTime"),
62 CLIENT_IP_ADDRESS("clientIpAddress"),
64 PROCESS_KEY("processKey"),
65 CUSTOM_FIELD_1("customField1"),
66 CUSTOM_FIELD_2("customField2"),
67 CUSTOM_FIELD_3("customField3"),
68 CUSTOM_FIELD_4("customField4"),
70 //ECOMP Specific Metric Log Event Fields
71 TARGET_ENTITY("targetEntity"),
73 //A&AI Specific Log Event Fields
74 COMPONENT("component"),
75 STOP_WATCH_START("stopWatchStart");
77 private final String text;
79 private LoggingField(final String text) {
83 public String toString() {
89 public static void init() {
90 LoggingContext.clear();
91 LoggingContext.startTime();
92 LoggingContext.server();
93 LoggingContext.serverIpAddress();
96 private static void startTime() {
97 MDC.put(LoggingField.START_TIME.toString(), LogFormatTools.getCurrentDateTime());
100 public static void requestId(UUID requestId) {
101 MDC.put(LoggingField.REQUEST_ID.toString(), requestId.toString());
104 public static void requestId(String requestId) {
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);
114 public static void serviceInstanceId(String serviceInstanceId) {
115 MDC.put(LoggingField.SERVICE_INSTANCE_ID.toString(), serviceInstanceId);
118 public static void serverName(String serverName) {
119 MDC.put(LoggingField.SERVER_NAME.toString(), serverName);
122 public static void serviceName(String serviceName) {
123 MDC.put(LoggingField.SERVICE_NAME.toString(), serviceName);
126 public static void partnerName(String partnerName) {
127 MDC.put(LoggingField.PARTNER_NAME.toString(), partnerName);
130 public static void statusCode(LoggingContext.StatusCode statusCode) {
131 MDC.put(LoggingField.STATUS_CODE.toString(), statusCode.toString());
134 public static String responseCode() {
135 return (String) MDC.get(LoggingField.RESPONSE_CODE.toString());
138 public static void responseCode(String responseCode) {
139 MDC.put(LoggingField.RESPONSE_CODE.toString(), responseCode);
142 public static void responseDescription(String responseDescription) {
143 MDC.put(LoggingField.RESPONSE_DESCRIPTION.toString(), responseDescription);
146 public static void instanceUuid(UUID instanceUuid) {
147 MDC.put(LoggingField.INSTANCE_UUID.toString(), instanceUuid.toString());
150 public static void severity(int severity) {
151 MDC.put(LoggingField.SEVERITY.toString(), String.valueOf(severity));
154 private static void serverIpAddress() {
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");
162 public static void elapsedTime(long elapsedTime, TimeUnit timeUnit) {
163 MDC.put(LoggingField.ELAPSED_TIME.toString(), String.valueOf(TimeUnit.MILLISECONDS.convert(elapsedTime, timeUnit)));
166 private static void server() {
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");
174 public static void clientIpAddress(InetAddress clientIpAddress) {
175 MDC.put(LoggingField.CLIENT_IP_ADDRESS.toString(), clientIpAddress.getHostAddress());
178 public static void clientIpAddress(String clientIpAddress) {
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
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);
192 public static void processKey(String processKey) {
193 MDC.put(LoggingField.PROCESS_KEY.toString(), processKey);
196 public static void customField1(String customField1) {
197 MDC.put(LoggingField.CUSTOM_FIELD_1.toString(), customField1);
200 public static void customField2(String customField2) {
201 MDC.put(LoggingField.CUSTOM_FIELD_2.toString(), customField2);
204 public static void customField3(String customField3) {
205 MDC.put(LoggingField.CUSTOM_FIELD_3.toString(), customField3);
208 public static void customField4(String customField4) {
209 MDC.put(LoggingField.CUSTOM_FIELD_4.toString(), customField4);
212 public static void component(String component) {
213 MDC.put(LoggingField.COMPONENT.toString(), component);
216 public static void targetEntity(String targetEntity) {
217 MDC.put(LoggingField.TARGET_ENTITY.toString(), targetEntity);
220 public static void stopWatchStart() {
221 MDC.put(LoggingField.STOP_WATCH_START.toString(), String.valueOf(System.nanoTime()));
224 public static double stopWatchStop() {
225 final long stopWatchEnd = System.nanoTime();
226 final Long stopWatchStart = Long.valueOf(MDC.get(LoggingField.STOP_WATCH_START.toString()));
228 if (stopWatchStart == null) throw new StopWatchNotStartedException();
230 MDC.remove(LoggingField.STOP_WATCH_START.toString());
232 final double elapsedTimeMillis = (stopWatchEnd - stopWatchStart) / 1000.0 / 1000.0;
234 LoggingContext.elapsedTime((long) elapsedTimeMillis, TimeUnit.MILLISECONDS);
236 return elapsedTimeMillis;
239 public static void put(String key, String value) {
243 public static void clear() {
247 public static void remove(String key) {
251 public static void save() {
252 final JSONObject context = new JSONObject();
254 for (LoggingField field : LoggingField.values()) {
255 if (field == LoggingField.ELAPSED_TIME) continue;
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)
266 MDC.put("_PREVIOUS_CONTEXT", context.toString());
269 public static void restore() {
271 final String rawPreviousContext = MDC.get(PREVIOUS_CONTEXT_KEY);
273 if (rawPreviousContext == null) {
274 throw new LoggingContextNotExistsException();
278 final JSONObject previousContext = new JSONObject(rawPreviousContext);
280 @SuppressWarnings("unchecked")
281 final Iterator<String> keys = previousContext.keys();
283 while (keys.hasNext()) {
284 final String key = keys.next();
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)
294 MDC.remove(PREVIOUS_CONTEXT_KEY);
295 } catch (JSONException e) {
296 //Ignore, the previousContext is serialized from a JSONObject