diff --git a/appengine-managed-runtime/pom.xml b/appengine-managed-runtime/pom.xml
index 25fac14..09fc8dd 100644
--- a/appengine-managed-runtime/pom.xml
+++ b/appengine-managed-runtime/pom.xml
@@ -31,6 +31,7 @@
yyyyMMddHHmm
1.9.49
+ 0.8.2-beta-SNAPSHOT
@@ -86,7 +87,7 @@
org.eclipse.jetty
jetty-server
${jetty.version}
- test
+ provided
org.eclipse.jetty
@@ -95,6 +96,17 @@
test
+
+ com.google.cloud
+ google-cloud-logging
+ ${gcloud.api.version}
+
+
+ javax.servlet
+ servlet-api
+
+
+
diff --git a/appengine-managed-runtime/src/main/java/com/google/apphosting/vmruntime/RequestContextScope.java b/appengine-managed-runtime/src/main/java/com/google/apphosting/vmruntime/RequestContextScope.java
new file mode 100644
index 0000000..296fc8f
--- /dev/null
+++ b/appengine-managed-runtime/src/main/java/com/google/apphosting/vmruntime/RequestContextScope.java
@@ -0,0 +1,82 @@
+package com.google.apphosting.vmruntime;/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * 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.
+ */
+
+import com.google.cloud.logging.GaeFlexLoggingEnhancer;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ContextHandler.Context;
+import org.eclipse.jetty.server.handler.ContextHandler.ContextScopeListener;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A Jetty {@link ContextScopeListener} that is called whenever
+ * a container managed thread enters or exits the scope of a context and/or request.
+ * Used to maintain {@link ThreadLocal} references to the current request and
+ * Google traceID, primarily for logging.
+ */
+public class RequestContextScope implements ContextHandler.ContextScopeListener {
+ static final Logger logger = Logger.getLogger(RequestContextScope.class.getName());
+
+ private static final String X_CLOUD_TRACE = "x-cloud-trace-context";
+ private static final ThreadLocal contextDepth = new ThreadLocal<>();
+
+ @Override
+ public void enterScope(Context context, Request request, Object reason) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("enterScope " + context);
+ }
+ if (request != null) {
+ Integer depth = contextDepth.get();
+ if (depth == null || depth.intValue() == 0) {
+ depth = 1;
+ String traceId = (String) request.getAttribute(X_CLOUD_TRACE);
+ if (traceId == null) {
+ traceId = request.getHeader(X_CLOUD_TRACE);
+ if (traceId != null) {
+ int slash = traceId.indexOf('/');
+ if (slash >= 0) {
+ traceId = traceId.substring(0, slash);
+ }
+ request.setAttribute(X_CLOUD_TRACE, traceId);
+ GaeFlexLoggingEnhancer.setCurrentTraceId(traceId);
+ }
+ } else {
+ depth = depth + 1;
+ }
+ contextDepth.set(depth);
+ }
+ }
+ }
+
+ @Override
+ public void exitScope(Context context, Request request) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("exitScope " + context);
+ }
+ Integer depth = contextDepth.get();
+ if (depth != null) {
+ if (depth > 1) {
+ contextDepth.set(depth - 1);
+ } else {
+ contextDepth.remove();
+ GaeFlexLoggingEnhancer.setCurrentTraceId(null);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/appengine-managed-runtime/src/main/java/com/google/apphosting/vmruntime/VmRuntimeFileLogHandler.java b/appengine-managed-runtime/src/main/java/com/google/apphosting/vmruntime/VmRuntimeFileLogHandler.java
index 2a8d876..39329b3 100644
--- a/appengine-managed-runtime/src/main/java/com/google/apphosting/vmruntime/VmRuntimeFileLogHandler.java
+++ b/appengine-managed-runtime/src/main/java/com/google/apphosting/vmruntime/VmRuntimeFileLogHandler.java
@@ -86,10 +86,12 @@ public static void init() throws IOException {
reloadLoggingProperties(LogManager.getLogManager());
Logger rootLogger = Logger.getLogger("");
for (Handler handler : rootLogger.getHandlers()) {
+ System.out.println("Logging Handler Found: " + handler.getClass().getCanonicalName());
if (handler instanceof VmRuntimeFileLogHandler) {
return; // Already installed.
}
}
+ System.out.println("Adding VmRuntimeFileLogHandler");
rootLogger.addHandler(new VmRuntimeFileLogHandler());
}