You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@reef.apache.org by we...@apache.org on 2014/11/12 01:50:48 UTC

incubator-reef git commit: REEF-24: Adding LogScope

Repository: incubator-reef
Updated Branches:
  refs/heads/master 16dd52a35 -> 141e4a321


REEF-24: Adding LogScope

Adds classes to be used within a try() block that automatically log the beginning and end times of the block.

Contributed by  Julia Wang Julia Wang <jw...@yahoo.com>

Closes #10


Project: http://git-wip-us.apache.org/repos/asf/incubator-reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-reef/commit/141e4a32
Tree: http://git-wip-us.apache.org/repos/asf/incubator-reef/tree/141e4a32
Diff: http://git-wip-us.apache.org/repos/asf/incubator-reef/diff/141e4a32

Branch: refs/heads/master
Commit: 141e4a321061403fc777087207869695aedd3b84
Parents: 16dd52a
Author: Julia Wang <jw...@yahoo.com>
Authored: Fri Oct 31 17:36:52 2014 -0700
Committer: Markus Weimer <we...@apache.org>
Committed: Tue Nov 11 16:38:49 2014 -0800

----------------------------------------------------------------------
 .../apache/reef/util/logging/LogLevelName.java  |  30 ++
 .../org/apache/reef/util/logging/LogParser.java | 164 ++++++++++
 .../apache/reef/util/logging/LoggingScope.java  |  33 ++
 .../reef/util/logging/LoggingScopeFactory.java  | 324 +++++++++++++++++++
 .../reef/util/logging/LoggingScopeImpl.java     | 108 +++++++
 .../org/apache/reef/util/LoggingScopeTest.java  | 100 ++++++
 6 files changed, 759 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/141e4a32/reef-common/src/main/java/org/apache/reef/util/logging/LogLevelName.java
----------------------------------------------------------------------
diff --git a/reef-common/src/main/java/org/apache/reef/util/logging/LogLevelName.java b/reef-common/src/main/java/org/apache/reef/util/logging/LogLevelName.java
new file mode 100644
index 0000000..a25a578
--- /dev/null
+++ b/reef-common/src/main/java/org/apache/reef/util/logging/LogLevelName.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.reef.util.logging;
+
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.annotations.NamedParameter;
+
+/**
+ * Name of a log Level as a string such as "INFO", "FINE"
+ */
+@NamedParameter(default_value = "FINE")
+public class LogLevelName implements Name<String> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/141e4a32/reef-common/src/main/java/org/apache/reef/util/logging/LogParser.java
----------------------------------------------------------------------
diff --git a/reef-common/src/main/java/org/apache/reef/util/logging/LogParser.java b/reef-common/src/main/java/org/apache/reef/util/logging/LogParser.java
new file mode 100644
index 0000000..4f6ed04
--- /dev/null
+++ b/reef-common/src/main/java/org/apache/reef/util/logging/LogParser.java
@@ -0,0 +1,164 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.reef.util.logging;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * Parse logs for reporting
+ */
+public class LogParser {
+
+  public static String endIndicators[] = {
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.BRIDGE_SETUP,
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.EVALUATOR_SUBMIT,
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.EVALUATOR_BRIDGE_SUBMIT,
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.DRIVER_START,
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.EVALUATOR_LAUNCH,
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.EVALUATOR_ALLOCATED,
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.ACTIVE_CONTEXT,
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.HTTP_REQUEST,
+      LoggingScopeImpl.EXIT_PREFIX + LoggingScopeFactory.TASK_COMPLETE
+  };
+
+  public static String startIndicators[] = {
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.DRIVER_START,
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.BRIDGE_SETUP,
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.EVALUATOR_BRIDGE_SUBMIT,
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.EVALUATOR_SUBMIT,
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.EVALUATOR_ALLOCATED,
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.EVALUATOR_LAUNCH,
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.ACTIVE_CONTEXT,
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.HTTP_REQUEST,
+      LoggingScopeImpl.START_PREFIX + LoggingScopeFactory.TASK_COMPLETE
+  };
+
+  private LogParser() {
+  }
+
+  /**
+   * Get lines from a given file with a specified filter, trim the line by removing strings before removeBeforeToken and after removeAfterToken
+   * @param fileName
+   * @param filter
+   * @return
+   * @throws IOException
+   */
+  public static ArrayList<String> getFilteredLinesFromFile(final String fileName, final String filter, final String removeBeforeToken, final String removeAfterToken) throws IOException{
+    final ArrayList<String> filteredLines = new ArrayList<String>();
+    try (final FileReader fr =  new FileReader(fileName)) {
+      try (final BufferedReader in = new BufferedReader(fr)) {
+        String line = "";
+        while ((line = in.readLine()) != null) {
+          if (line.trim().length() == 0) {
+            continue;
+          }
+          if (line.contains(filter)) {
+            String trimedLine;
+            if (removeBeforeToken != null) {
+              final String[] p = line.split(removeBeforeToken);
+              if (p.length > 1) {
+                trimedLine = p[p.length-1];
+              } else {
+                trimedLine = line.trim();
+              }
+            } else {
+              trimedLine = line.trim();
+            }
+            if (removeAfterToken != null) {
+              final String[] p = trimedLine.split(removeAfterToken);
+              if (p.length > 1) {
+                trimedLine = p[0];
+              }
+            }
+            filteredLines.add(trimedLine);
+          }
+        }
+      }
+    }
+    return filteredLines;
+  }
+
+  /**
+   * get lines from given file with specified filter
+   * @param fileName
+   * @param filter
+   * @return
+   * @throws IOException
+   */
+  public static ArrayList<String> getFilteredLinesFromFile(final String fileName, final String filter) throws IOException {
+    return getFilteredLinesFromFile(fileName, filter, null, null);
+  }
+
+  /**
+   * filter array list of lines and get the last portion of the line separated by the token, like ":::"
+   * @param original
+   * @param filter
+   * @return
+   */
+  public static ArrayList<String> filter(final ArrayList<String> original, final String filter, final String token) {
+    final ArrayList<String> result = new ArrayList<String>();
+    for (String line : original) {
+      if (line.contains(filter)) {
+        final String[] p = line.split(token);
+        if (p.length > 1) {
+          result.add(p[p.length-1]);
+        }
+      }
+    }
+    return result;
+  }
+
+  /**
+   * find lines that contain stage indicators. The stageIndicators must be in sequence which appear in the lines.
+   * @param lines
+   * @param stageIndicators
+   * @return
+   */
+  public static ArrayList<String> findStages(final ArrayList<String> lines, final String[] stageIndicators) {
+    ArrayList<String> stages = new ArrayList<String>();
+
+    int i = 0;
+    for (String line: lines) {
+      if (line.contains(stageIndicators[i])){
+        stages.add(stageIndicators[i]);
+        if (i < stageIndicators.length - 1) {
+          i++;
+        }
+      }
+    }
+    return stages;
+  }
+
+  public static ArrayList<String> mergeStages(ArrayList<String> startStages, ArrayList<String> endStages) {
+    ArrayList<String> mergeStage = new ArrayList<String>();
+    for (int i = 0; i < startStages.size(); i++) {
+      String end = startStages.get(i).replace(LoggingScopeImpl.START_PREFIX, LoggingScopeImpl.EXIT_PREFIX);
+      if (endStages.contains(end)) {
+        mergeStage.add(startStages.get(i)  + "   " + end);
+      } else {
+        mergeStage.add(startStages.get(i));
+      }
+    }
+    return mergeStage;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/141e4a32/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScope.java
----------------------------------------------------------------------
diff --git a/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScope.java b/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScope.java
new file mode 100644
index 0000000..c67edd7
--- /dev/null
+++ b/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScope.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.reef.util.logging;
+
+import com.google.common.base.Stopwatch;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Log time elapsed for a scope
+ */
+public interface LoggingScope extends AutoCloseable {
+
+  @Override
+  public void close();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/141e4a32/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java
----------------------------------------------------------------------
diff --git a/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java b/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java
new file mode 100644
index 0000000..e64d158
--- /dev/null
+++ b/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeFactory.java
@@ -0,0 +1,324 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.reef.util.logging;
+
+import org.apache.reef.tang.JavaConfigurationBuilder;
+import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.annotations.Parameter;
+import org.apache.reef.wake.time.event.StartTime;
+
+import javax.inject.Inject;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Create Logging scope objects
+ */
+public class LoggingScopeFactory {
+
+  private static final Logger LOG = Logger.getLogger(LoggingScopeFactory.class.getName());
+  public static final String DRIVER_START = "Driver Start Handler";
+  public static final String DRIVER_STOP = "Driver Stop Handler";
+  public static final String BRIDGE_SETUP = "Bridge setup";
+  public static final String EVALUATOR_REQUESTOR = "Evaluator requestor passed to C#";
+  public static final String EVALUATOR_BRIDGE_SUBMIT = "Evaluator request submit cross bridge";
+  public static final String EVALUATOR_SUBMIT = "Evaluator submit";
+  public static final String EVALUATOR_LAUNCH = "Evaluator launch";
+  public static final String EVALUATOR_ALLOCATED = "Evaluator allocated";
+  public static final String EVALUATOR_COMPLETED = "Evaluator completed";
+  public static final String EVALUATOR_FAILED = "Evaluator failed";
+  public static final String ACTIVE_CONTEXT = "Active context created";
+  public static final String TASK_RUNNING = "Task running";
+  public static final String TASK_COMPLETE = "Task complete";
+  public static final String TASK_MESSAGE = "Task message";
+  public static final String CONTEXT_MESSAGE = "Context message";
+  public static final String CONTEXT_CLOSE = "Context close";
+  public static final String DRIVER_RESTART = "Driver restart";
+  public static final String DRIVER_RESTART_COMPLETE = "Driver restart complete";
+  public static final String DRIVER_RESTART_RUNNING_TASK = "Driver restart running task";
+  public static final String DRIVER_RESTART_ACTIVE_CONTEXT = "Driver restart active context";
+  public static final String TASK_SUSPEND = "Task suspend";
+  public static final String DRIVER_SUBMIT = "Driver submit";
+  public static final String REEF_SUBMIT = "Reef submit";
+  public static final String LOCAL_JOB_SUBMIT = "Local job submit";
+  public static final String HTTP_REQUEST = "Http request";
+  public static final String HTTP_SERVER = "Http server";
+
+  /**
+   * Log level. Client can set it through LogLevelName named parameter
+   */
+  private final Level logLevel;
+
+  /**
+   * User can inject a LoggingScopeFactory with injected log level as a string
+   */
+  @Inject
+  private LoggingScopeFactory(@Parameter(LogLevelName.class) final String logLevelName) {
+    this.logLevel = Level.parse(logLevelName);
+  }
+
+  /**
+   * Get a new instance of LoggingScope with msg through new
+   * @param msg
+   * @return
+   */
+  public LoggingScope getNewLoggingScope(final String msg) {
+    return new LoggingScopeImpl(LOG, logLevel, msg);
+  }
+
+  /**
+   * Get a new instance of LoggingScope with msg and params through new
+   * @param msg
+   * @param params
+   * @return
+   */
+  public LoggingScope getNewLoggingScope(final String msg, final Object params[]) {
+    return new LoggingScopeImpl(LOG, logLevel, msg, params);
+  }
+
+  /**
+   * The method is to measure the time used to start the driver. It can be inserted to the code between start driver till it is started
+   * @param startTime
+   * @return
+   */
+  public LoggingScope driverStart(final StartTime startTime) {
+    return new LoggingScopeImpl(LOG, logLevel, DRIVER_START + " :" + startTime);
+  }
+
+  /**
+   * The method is to measure the time used to stop the driver. It can be inserted to the code between start driver stop till it is stopped
+   * @param timeStamp
+   * @return
+   */
+  public LoggingScope driverStop(final long timeStamp) {
+    return new LoggingScopeImpl(LOG, logLevel, this.DRIVER_STOP + " :" + timeStamp);
+  }
+
+  /**
+   * The method is to measure the time used to set up Java CRL bridge. It can be inserted to the code between beginning of bridge set up and the end of it
+   * @return
+   */
+  public LoggingScope setupBridge() {
+    return new LoggingScopeImpl(LOG, logLevel, BRIDGE_SETUP);
+  }
+
+  /**
+   * The method is to measure the time used to pass EvaluatorRequestor from Java to .Net. It can be inserted to the code between beginning to send EvaluatorRequestor to CLR until it is returned.
+   * @return
+   */
+  public LoggingScope evaluatorRequestorPassToCs() {
+    return new LoggingScopeImpl(LOG, logLevel, EVALUATOR_REQUESTOR);
+  }
+
+  /**
+   * The method is to measure the time used to submit Evaluator request from CLR to Java driver. It can be inserted to evaluator submit() method.
+   * @param evaluatorsNumber
+   * @return
+   */
+  public LoggingScope evaluatorRequestSubmitToJavaDriver(final int evaluatorsNumber) {
+    return new LoggingScopeImpl(LOG, logLevel, EVALUATOR_BRIDGE_SUBMIT + ":" + evaluatorsNumber);
+  }
+
+  /**
+   * The method is to measure the time used to submit a Evaluator request at java side
+   * @param evaluatorNumber
+   * @return
+   */
+  public LoggingScope evaluatorSubmit(final int evaluatorNumber) {
+    return new LoggingScopeImpl(LOG, logLevel, EVALUATOR_SUBMIT + ":" + evaluatorNumber);
+  }
+
+  /**
+   * This is to measure the time on evaluatorAllocated handler
+   * @param evaluatorId
+   * @return
+   */
+  public LoggingScope evaluatorAllocated(final String evaluatorId) {
+    return new LoggingScopeImpl(LOG, logLevel, EVALUATOR_ALLOCATED + " :" + evaluatorId);
+  }
+
+  /**
+   * This is to measure the time to launch an evaluator
+   * @param evaluatorId
+   * @return
+   */
+  public LoggingScope evaluatorLaunch(final String evaluatorId) {
+    return new LoggingScopeImpl(LOG, logLevel, EVALUATOR_LAUNCH + " :" + evaluatorId);
+  }
+
+  /**
+   * This is to measure the time in calling evaluatorCompleted handler
+   * @param evaluatorId
+   * @return
+   */
+  public LoggingScope evaluatorCompleted(final String evaluatorId) {
+    return new LoggingScopeImpl(LOG, logLevel, EVALUATOR_COMPLETED + " :" + evaluatorId);
+  }
+
+  /**
+   * This is to measure the time in calling evaluatorFailed handler
+   * @param evaluatorId
+   * @return
+   */
+  public LoggingScope evaluatorFailed(final String evaluatorId) {
+    return new LoggingScopeImpl(LOG, logLevel, this.EVALUATOR_FAILED + " :" + evaluatorId);
+  }
+
+  /**
+   * This is to measure the time in calling activeContext handler
+   * @param contextId
+   * @return
+   */
+  public LoggingScope activeContextReceived(final String contextId) {
+    return new LoggingScopeImpl(LOG, logLevel, ACTIVE_CONTEXT + " :" + contextId);
+  }
+
+  /**
+   * This is to measure the time in calling closedContext handler
+   * @param contextId
+   * @return
+   */
+  public LoggingScope closedContext(final String contextId) {
+    return new LoggingScopeImpl(LOG, logLevel, this.CONTEXT_CLOSE + " :" + contextId);
+  }
+
+  /**
+   * This is to measure the time in calling runningTaskHandler
+   * @param taskId
+   * @return
+   */
+  public LoggingScope taskRunning(final String taskId) {
+    return new LoggingScopeImpl(LOG, logLevel, TASK_RUNNING + " :" + taskId);
+  }
+
+  /**
+   * This is to measure the time in calling taskCompletedHandler
+   * @param taskId
+   * @return
+   */
+  public LoggingScope taskCompleted(final String taskId) {
+    return new LoggingScopeImpl(LOG, logLevel, TASK_COMPLETE + " :" + taskId);
+  }
+
+  /**
+   * This is to measure the time in calling taskSuspendedHandler
+   * @param taskId
+   * @return
+   */
+  public LoggingScope taskSuspended(final String taskId) {
+    return new LoggingScopeImpl(LOG, logLevel, TASK_SUSPEND + " :" + taskId);
+  }
+
+  /**
+   * This is to measure the time in calling taskMessageReceivedHandler
+   * @param msg
+   * @return
+   */
+  public LoggingScope taskMessageReceived(final String msg) {
+    return new LoggingScopeImpl(LOG, logLevel, TASK_MESSAGE + " :" + msg);
+  }
+
+  /**
+   * This is to measure the time in calling contextMessageReceivedHandler
+   * @param msg
+   * @return
+   */
+  public LoggingScope contextMessageReceived(final String msg) {
+    return new LoggingScopeImpl(LOG, logLevel, CONTEXT_MESSAGE + " :" + msg);
+  }
+
+  /**
+   * This is to measure the time in calling driverRestartHandler
+   * @param startTime
+   * @return
+   */
+  public LoggingScope driverRestart(final StartTime startTime) {
+    return new LoggingScopeImpl(LOG, logLevel, DRIVER_RESTART + " :" + startTime);
+  }
+
+  /**
+   * This is to measure the time in calling driverRestartCompletedHandler
+   * @param timeStamp
+   * @return
+   */
+  public LoggingScope driverRestartCompleted(final long timeStamp) {
+    return new LoggingScopeImpl(LOG, logLevel, DRIVER_RESTART_COMPLETE + " :" + timeStamp);
+  }
+
+  /**
+   * This is to measure the time in calling driverRestartRunningTaskHandler
+   * @param taskId
+   * @return
+   */
+  public LoggingScope driverRestartRunningTask(final String taskId) {
+    return new LoggingScopeImpl(LOG, logLevel, DRIVER_RESTART_RUNNING_TASK + " :" + taskId);
+  }
+
+  /**
+   * This is to measure the time in calling driverRestartActiveContextReceivedHandler
+   * @param contextId
+   * @return
+   */
+  public LoggingScope driverRestartActiveContextReceived(final String contextId) {
+    return new LoggingScopeImpl(LOG, logLevel, DRIVER_RESTART_ACTIVE_CONTEXT + " :" + contextId);
+  }
+
+  /**
+   * This is to measure the time in handling a http request
+   * @param uri
+   * @return
+   */
+  public LoggingScope httpRequest(final String uri) {
+    return new LoggingScopeImpl(LOG, logLevel, this.HTTP_REQUEST + " :" + uri);
+  }
+
+  /**
+   * This is to measure the time used to create HttpServer
+   * @return
+   */
+  public LoggingScope httpServer() {
+    return new LoggingScopeImpl(LOG, logLevel, this.HTTP_SERVER);
+  }
+
+  /**
+   * This is to measure the time to submit a driver
+   * @param submitDriver
+   * @return
+   */
+  public LoggingScope driverSubmit(final Boolean submitDriver) {
+    return new LoggingScopeImpl(LOG, logLevel, DRIVER_SUBMIT + " :" + submitDriver);
+  }
+
+  /**
+   * This is to measure the time to call Reef.Submit
+   * @return
+   */
+  public LoggingScope reefSubmit() {
+    return new LoggingScopeImpl(LOG, logLevel, this.REEF_SUBMIT);
+  }
+
+  /**
+   * This is to measure the time for a job submission
+   * @return
+   */
+  public LoggingScope localJobSubmission() {
+    return new LoggingScopeImpl(LOG, logLevel, this.LOCAL_JOB_SUBMIT);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/141e4a32/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeImpl.java
----------------------------------------------------------------------
diff --git a/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeImpl.java b/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeImpl.java
new file mode 100644
index 0000000..f8743dd
--- /dev/null
+++ b/reef-common/src/main/java/org/apache/reef/util/logging/LoggingScopeImpl.java
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.reef.util.logging;
+
+import com.google.common.base.Stopwatch;
+import org.apache.reef.tang.annotations.Name;
+import org.apache.reef.tang.annotations.NamedParameter;
+import org.apache.reef.tang.annotations.Parameter;
+import org.apache.reef.util.Optional;
+
+import javax.inject.Inject;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Log time and duration for a scope
+ */
+public class LoggingScopeImpl implements LoggingScope {
+  public static final String TOKEN = ":::";
+  public static final String START_PREFIX = "START" + TOKEN;
+  public static final String EXIT_PREFIX = "EXIT" + TOKEN;
+  public static final String DURATION = " Duration = ";
+
+  private final Stopwatch stopWatch = new Stopwatch();
+
+  private final Logger logger;
+
+  private final String msg;
+
+  private final Object[] params;
+
+  private final Optional<Object[]> optionalParams;
+
+  private final Level logLevel;
+
+  /**
+   * A constructor of ReefLoggingScope. It starts the timer and logs the msg
+   *
+   * @param logger
+   * @param msg
+   * @param params
+   */
+  LoggingScopeImpl(final Logger logger, final Level logLevel, final String msg, final Object params[]) {
+    this.logger = logger;
+    this.logLevel = logLevel;
+    this.msg = msg;
+    this.params = params;
+    stopWatch.start();
+    this.optionalParams = Optional.ofNullable(params);
+
+    if (logger.isLoggable(logLevel)) {
+      final StringBuilder sb = new StringBuilder();
+      log(sb.append(START_PREFIX).append(msg).toString());
+    }
+  }
+
+  /**
+   * A constructor of ReefLoggingScope.  It starts the timer and and logs the msg.
+   *
+   * @param logger
+   * @param msg
+   */
+  LoggingScopeImpl(final Logger logger, final Level logLevel, final String msg) {
+    this(logger, logLevel, msg, null);
+  }
+
+  /**
+   * The close() will be called when the object is to deleted. It stops the timer and logs the time elapsed.
+   */
+  @Override
+  public void close() {
+    stopWatch.stop();
+
+    if (logger.isLoggable(logLevel)) {
+      final StringBuilder sb = new StringBuilder();
+      log(sb.append(EXIT_PREFIX).append(msg).append(DURATION).append(stopWatch.elapsedMillis()).toString());
+    }
+  }
+
+  /**
+   * log massage
+   * @param msg
+   */
+  private void log(final String msg) {
+    if (this.optionalParams.isPresent()) {
+      logger.log(logLevel, msg, params);
+    } else {
+      logger.log(logLevel, msg);
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/141e4a32/reef-common/src/test/java/org/apache/reef/util/LoggingScopeTest.java
----------------------------------------------------------------------
diff --git a/reef-common/src/test/java/org/apache/reef/util/LoggingScopeTest.java b/reef-common/src/test/java/org/apache/reef/util/LoggingScopeTest.java
new file mode 100644
index 0000000..fdb2aa1
--- /dev/null
+++ b/reef-common/src/test/java/org/apache/reef/util/LoggingScopeTest.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.reef.util;
+
+import org.apache.reef.tang.ConfigurationBuilder;
+import org.apache.reef.tang.ExternalConstructor;
+import org.apache.reef.tang.Injector;
+import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.exceptions.InjectionException;
+import org.apache.reef.util.logging.*;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.inject.Inject;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Test LoggingScope
+ */
+public class LoggingScopeTest {
+
+  private LoggingScopeFactory logFactory;
+
+  @Before
+  public void setUp() throws InjectionException {
+    final ConfigurationBuilder b = Tang.Factory.getTang().newConfigurationBuilder()
+        .bindNamedParameter(LogLevelName.class, "INFO");
+
+    final Injector i = Tang.Factory.getTang().newInjector(b.build());
+    logFactory = i.getInstance(LoggingScopeFactory.class);
+  }
+
+  /**
+   * Test getNewLoggingScope() in LoggingScopeFactory that injects LoggingScope object
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testGetNewLoggingScope() throws InjectionException {
+    try (final LoggingScope ls = logFactory.getNewLoggingScope("test")) {
+       Assert.assertTrue(true);
+    }
+  }
+
+  /**
+   * Test getNewLoggingScope() in LoggingScopeFactory that injects LoggingScope object with param as a parameter
+   * @throws InjectionException
+   */
+  @Test
+  public void testGetNewLoggingScopeWithParam() throws InjectionException {
+    try (final LoggingScope ls = logFactory.getNewLoggingScope("test first string = {0}, second = {1}", new Object[] { "first", "second" })) {
+      Assert.assertTrue(true);
+    }
+  }
+
+  /**
+   * Test calling predefined method in LoggingScopeFactory
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testLoggingScopeFactory() {
+    try (final LoggingScope ls = logFactory.activeContextReceived("test")) {
+      Assert.assertTrue(true);
+    }
+  }
+
+  /**
+   * Use default log level in injecting LoggingScopeFactory constructor
+   * @throws InjectionException
+   */
+  @Test
+  public void testLoggingScopeFactoryWithDefaultLogLevel() throws InjectionException {
+    final Injector i = Tang.Factory.getTang().newInjector(Tang.Factory.getTang().newConfigurationBuilder().build());
+    final LoggingScopeFactory logFactory = i.getInstance(LoggingScopeFactory.class);
+
+    try (final LoggingScope ls = logFactory.activeContextReceived("test")) {
+      Assert.assertTrue(true);
+    }
+  }
+}