aboutsummaryrefslogtreecommitdiffstats
path: root/operation-utils/src/main/java/org/openecomp/logger/Stopwatch.java
diff options
context:
space:
mode:
Diffstat (limited to 'operation-utils/src/main/java/org/openecomp/logger/Stopwatch.java')
-rw-r--r--operation-utils/src/main/java/org/openecomp/logger/Stopwatch.java253
1 files changed, 253 insertions, 0 deletions
diff --git a/operation-utils/src/main/java/org/openecomp/logger/Stopwatch.java b/operation-utils/src/main/java/org/openecomp/logger/Stopwatch.java
new file mode 100644
index 0000000..e86713d
--- /dev/null
+++ b/operation-utils/src/main/java/org/openecomp/logger/Stopwatch.java
@@ -0,0 +1,253 @@
+
+/*-
+ * ============LICENSE_START==========================================
+ * OPENECOMP - DCAE
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ */
+
+package org.openecomp.logger;
+
+import static com.att.eelf.configuration.Configuration.MDC_BEGIN_TIMESTAMP;
+import static com.att.eelf.configuration.Configuration.MDC_ELAPSED_TIME;
+import static com.att.eelf.configuration.Configuration.MDC_END_TIMESTAMP;
+import static com.att.eelf.configuration.Configuration.MDC_TARGET_ENTITY;
+import static com.att.eelf.configuration.Configuration.MDC_TARGET_SERVICE_NAME;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.slf4j.MDC;
+
+
+/**
+ * This class is used to time events to determine their duration. The stop watch allows for the same types of operations
+ * as a real stop watch, that is, it allows the timing to be stopped, started, cleared, and read. The accumulated time
+ * is the total of all times between start and stop events. The watch can be repeatedly stopped and restarted, and will
+ * accumulate all durations between start/stop pairs.
+ */
+public class Stopwatch {
+
+ public static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
+ public static final TimeZone utc = TimeZone.getTimeZone("UTC");
+ public static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT);
+ public static EcompLogger ecompLogger = EcompLogger.getEcompLogger();
+
+ /**
+ * This is the object that maintains our state on the thread local storage
+ */
+ public static class StopwatchState {
+ /**
+ * The accumulated duration
+ */
+ private long duration;
+
+ /**
+ * Indicates that the watch is running
+ */
+ private boolean running = false;
+
+ /**
+ * The last recorded start time
+ */
+ private long startTime;
+
+ public String target;
+
+ public String op;
+
+ @Override
+ public String toString() {
+ return "StopwatchState [duration=" + duration + ", running=" + running + ", startTime=" + startTime + "]";
+ }
+
+ }
+
+ public static class StopwatchStateStack {
+ private List<StopwatchState> l = new ArrayList<Stopwatch.StopwatchState>();
+
+ public StopwatchState top() {
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": top 1 " + l);
+ if (l.size() == 0) {
+ ecompLogger.warn(GenericMessagesMessageEnum.ECOMP_LOGGER_TOP_ON_EMPTY_STACK);
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": top empty");
+ push(null,null);
+ }
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": top 2 " + l);
+ return l.get(l.size()-1);
+ }
+
+ public void push(String targetEntity, String target) {
+ l.add(new StopwatchState());
+ top().op = targetEntity;
+ top().target = target;
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": push 2 " + l);
+ }
+
+ public void pop() {
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": pop 1 " + l);
+ if (l.size() == 0) {
+ ecompLogger.warn(GenericMessagesMessageEnum.ECOMP_LOGGER_POP_ON_EMPTY_STACK);
+ return;
+ }
+ l.remove(l.size()-1);
+ }
+
+ public void clear() {
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": clear 1" + l);
+ l.clear();
+ }
+ }
+
+ /**
+ * Thread local storage wrapper
+ */
+ private static ThreadLocal<StopwatchStateStack> tls = new ThreadLocal<>();
+
+ static {
+ isoFormatter.setTimeZone(utc);
+ }
+
+ /**
+ * Looks up the Thread Local storage object containing the Stopwatch state, and creates it if it does not already
+ * exist.
+ *
+ * @return The state object
+ */
+ private static StopwatchStateStack getState() {
+ StopwatchStateStack state = tls.get();
+ if (state == null) {
+ state = new StopwatchStateStack();
+ tls.set(state);
+ }
+ return state;
+ }
+
+ /**
+ * Clears (and possibly stops) the watch.
+ */
+ public static void clear() {
+ getState().clear();
+ }
+
+ /**
+ * The accumulated duration of the watch (in nano-seconds)
+ *
+ * @return The accumulated time
+ */
+ public static long getDuration() {
+ StopwatchState state = getState().top();
+ return state.duration;
+ }
+
+ /**
+ * Determines if the stopwatch is currently running or not
+ *
+ * @return True if the watch is running
+ */
+ public static boolean isRunning() {
+ StopwatchState state = getState().top();
+ return state.running;
+ }
+
+ /**
+ * Starts the watch if not already running.
+ */
+ public static void start() {
+ StopwatchState state = getState().top();
+ if (!state.running) {
+ state.running = true;
+ state.startTime = System.currentTimeMillis();
+ MDC.put(MDC_BEGIN_TIMESTAMP, isoFormatter.format(new Date(state.startTime)));
+ }
+ }
+
+ /**
+ * Stops the accumulation of time on the watch if running
+ */
+ public static void stop() {
+ StopwatchState state = getState().top();
+ if (state.running) {
+ long stopTime = System.currentTimeMillis();
+ state.duration += (stopTime - state.startTime);
+ state.running = false;
+ MDC.put(MDC_END_TIMESTAMP,isoFormatter.format(new Date(stopTime)));
+ MDC.put(MDC_ELAPSED_TIME, String.valueOf(state.duration));
+ }
+ if (!EcompLogger.isNullOrEmpty(state.target))
+ MDC.put(MDC_TARGET_ENTITY, state.target);
+ if (state.op != null)
+ MDC.put(MDC_TARGET_SERVICE_NAME, state.op);
+ }
+
+ /**
+ * Gets the amount of time since the stop watch was last started without stopping the watch or accumulating the
+ * previous time .
+ */
+ public static double getCurrentDuration() {
+ StopwatchState state = getState().top();
+ if (state.running) {
+ return (System.currentTimeMillis() - state.startTime);
+ }
+ return 0L;
+ }
+
+ public static void pushNewWatch(String targetEntity, String target) {
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": pushNewWatch 1" + getState().l);
+ getState().push(targetEntity,target);
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": pushNewWatch 2" + getState().l);
+ }
+
+ public static void popWatch() {
+ stop();
+ getState().pop();
+ }
+
+ public static void clearAndStart() {
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + " clearAndStart 1" + getState().l);
+ clear();
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": clearAndStart 2" + getState().l);
+ pushAndStart(null,null);
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": clearAndStart 3" + getState().l);
+ }
+
+ public static void stopAndPop() {
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": stopAndPop 1" + getState().l);
+ stop();
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": stopAndPop 2" + getState().l);
+ popWatch();
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": stopAndPop 3" + getState().l);
+ }
+
+ public static void pushAndStart(String targetEntity, String target) {
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": pushAndStart 1" + getState().l);
+ pushNewWatch(targetEntity,target);
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": pushAndStart 2" + getState().l);
+ start();
+// System.out.println("WWWWWW: " + Thread.currentThread().getName() + ": pushAndStart 3" + getState().l);
+ }
+
+ public static boolean emptyStack() {
+ return getState().l.size() == 0;
+ }
+
+ public static String getTopTarget() {
+ return getState().top().target;
+ }
+}