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()); }