I have a Spring Boot application that I am deploying to an App Engine standard environment using Java 8. I cannot seem to get log messages to show in the log viewer in my cloud console. I do have other logs working such as the endpoint being hit.
logging.properties:
.level = FINEST
appengine-web.xml:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<threadsafe>true</threadsafe>
<runtime>java8</runtime>
<service>logging-service</service>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
Spring Controller:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
#RestController
#RequestMapping("/log")
public class LogSubscription {
private static final Logger log = Logger.getLogger(LogSubscription.class.getName());
#RequestMapping(method = GET)
public String logSomething() {
log.log(Level.INFO, "Should see this in the console");
log.log(Level.SEVERE, "This is severe");
log.info("Normal Log Message");
return "Should log successfully";
}
}
Logging to the console works perfectly fine when I run locally. I just can't see the logs in the web console. I can see the GET request but not the logging in it. I am attaching a screenshot of my log.
I was finally able to find a solution. You must add the following to the build.gradle file:
configurations {
compile.exclude group: "org.slf4j", module: "jul-to-slf4j"
}
Related
We deploy our app on Google app engine standard environment. We need to access Memorystore(redis) from our app engine.
Following the document, we create Serverless VPC access connector and configure the app engine:
<vpc-access-connector>
<name>projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR_NAME</name>
</vpc-access-connector>
and set the IAM permissions. But we still can not connect to redis instance at private IP like 10.0.0.4 using jedis:
Jedis jedis = new Jedis("10.0.0.4");
It should work if you deploy it with gcloud beta app deploy target/SNAPSHOT.
I prepared and uploaded a sample in Github.
How I did it in a new project:
Enabled App Engine, selected region us-central (corresponds to us-central1)
Created Memorystore instance, in region us-central1
Created VPC Connector, in region us-central1 (At the moment no other region can be selected, so both App Engine and Memorystore have to be in us-central1)
Added the VPC connector in appengine-web.xml:
<vpc-access-connector>
<name>projects/PROJECT_ID/locations/us-central1/connectors/CONNECTOR_NAME</name>
</vpc-access-connector>
Modified pom.xml, adding the following dependency:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
Modified the servlet.java file:
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import redis.clients.jedis.Jedis;
#WebServlet(
name = "Redis",
description = "Redis: Connect to Redis",
urlPatterns = "/redis"
)
public class RedisServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String s;
try{
Jedis jedis = new Jedis("10.0.0.4");
jedis.set("myKey", "It's alive");
s = "Life test: "+ jedis.get("myKey");
}catch(Exception e){s = "Couldn't connect "; e.printStackTrace();}
resp.getWriter().write(s);
}
}
Ran the following to package and deploy:
mvn package (This will create a "target" folder)
gcloud beta app deploy target/ARTIFACT_ID-1.0-SNAPSHOT
Note that it's still in BETA and it might not work very reliably.
I am using the Google Plugin for Eclipse, and I am writing an App Engine app as a Dynamic Web Module in Eclipse WTP.
I have defined the following Java class to serve as a Cloud Endpoint API:
package mypackage;
import static mypackage.OfyService.ofy;
import java.util.List;
import java.util.logging.Logger;
import mypackage.models.ProbeEntry;
import mypackage.models.ProbeSet;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.config.Named;
import com.googlecode.objectify.ObjectifyService;
#Api(name = "analysisEndpoint",
version = "v1",
namespace = #ApiNamespace(
ownerDomain = "myorg",
ownerName = "myorg",
packagePath = "analysis")
)
public class AnalysisEndpoint {
private static final Logger logger = Logger.getLogger(AnalysisEndpoint.class.getName());
#ApiMethod(name = "getMyProbeEntries", httpMethod = ApiMethod.HttpMethod.GET)
public ProbeSet getMyProbeEntries(#Named("amount") int amount) {
ObjectifyService.begin();
List<ProbeEntry> probeList = ofy().load().type(ProbeEntry.class).limit(amount).list();
return new ProbeSet(probeList);
}
}
I attempt to deploy to the Google App Engine by right-clicking the project -> Google App Engine WTP -> Deploy Project to Remote Server. I see in my console that the project is compiling and uploading, but eventually errors out with:
99% Endpoints configuration not updated. The app returned an error when the Google Cloud Endpoints server attempted to communicate with it.
The error log on the app engine shows the following:
18:31:58.119
javax.servlet.ServletContext log: unavailable
com.google.api.server.spi.config.validation.MissingParameterNameException: analysisEndpoint.myorg.analysis.AnalysisEndpoint.getMyProbeEntries parameter (type int): Missing parameter name. Parameter type (int) is not an entity type and thus should be annotated with #Named.
at
com.google.api.server.spi.config.validation.ApiConfigValidator.validateApiParameter(ApiConfigValidator.java:214)
...
As can be seen in the code, I do have #Named("amount") before the offending parameter. What is going wrong here? Side note: If I simply remove the amount parameter, the project deploys to App Engine without a problem.
Any help would be greatly appreciated.
I need to debug my Google Cloud Endpoint after it is deployed to AppEngine. I am trying to write entries to the log but they never show up in the log viewer on the Google Developers Console. Here is the logging code I created in Android Studio:
import java.util.logging.Logger;
...
public class MyEndpoint {
private static final Logger log = Logger.getLogger(MyEndpoint.class.getName());
...
log.info("message to log");
This code executes in the cloud without error but nothing shows up in the log. What am I doing wrong?
The entry is not showing in the log because the default logging level in app engine is: WARNING. Setting the logging level prior to calling log.info() caused the log entry to show in the console as expected. Here is the revised code with setLevel in context:
import java.util.logging.Logger;
...
public class MyEndpoint {
private static final Logger log =Logger.getLogger(MyEndpoint.class.getName());
...
log.setLevel(Level.INFO);
log.info("message to log");
Instead of servlet mapping in the web.xml, i'm trying to use annotation to map the servlet to urls as follows:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#WebServlet(name = "GuestbookServlet", urlPatterns = "/guestbook")
public class GuestbookServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
}
}
And I have also declared the 3.0 spec for servlet in web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="false">
</web-app>
However, when I run it on my local environment the response returned is 404.
It works however if I just map the servlets in the web.xml. What am I doing wrong? Does GAE still not support 3.0 specs?
Servlet 3.0 spec is not supported by GAE/J
It's still on the roadmap: https://developers.google.com/appengine/docs/features#roadmap_features
You can star this issue to help show your support for this feature: https://code.google.com/p/googleappengine/issues/detail?id=3091
This ticket has been opened a lonnnggg time though.
When I run the following JSP code,
Server info == <%=application.getServerInfo()%><br/>
Major==<%=application.getMajorVersion()%><br/>
Minor==<%=application.getMinorVersion()%><br/>
JSP version is <%= JspFactory.getDefaultFactory().getEngineInfo().getSpecificationVersion()%><br/>
I see
Server info == Google App Engine/Google App Engine/1.8.1
Major==2
Minor==5
JSP version is 2.1
You could run it for yourself.
Servlet 3.1 are now supported on AppEngine.
... In addition to support for an updated JDK and Jetty 9 with Servlet 3.1 specs...
Announcement:
https://cloudplatform.googleblog.com/2017/06/Google-App-Engine-standard-now-supports-Java-8.html
Here is a code example
I am trying to get RPC testing using GWT. I am using the default StockWatcher project that is mentioned here, I download the project, I import it, everything works fine.
I then run junitcreator in the StockWatcher project:
/Users/stephen/Work/gwt/gwt-mac-1.6.4/junitCreator -junit /Users/stephen/Applications/eclipse/plugins/org.junit_3.8.2.v20080602-1318/junit.jar -module stockwatcher -eclipse StockWatcher com.google.gwt.sample.stockwatcher.StockWatcherTest
this creates the StockWatcherTest.java in the appropriate test directory, and gives me some hosted and web mode launch files.
I then also added junit.jar to the classpath for this project.
I then modify StockWatcherTest.java to test whether I am capable of making a asynchronous request to the server. Everything looks fine, but when I try to run StockWatcherTest.java in hosted mode, I get the following error:
Starting HTTP on port 0 HTTP
listening on port 49569
The development shell servlet received a
request for 'greet' in module
'com.google.gwt.sample.stockwatcher.StockWatcher.JUnit.gwt.xml'
[WARN] Resource not found: greet;
(could a file be missing from the
public path or a tag
misconfigured in module
com.google.gwt.sample.stockwatcher.StockWatcher.JUnit.gwt.xml
?)
com.google.gwt.user.client.rpc.StatusCodeException:
Cannot find resource 'greet' in the
public path of module
'com.google.gwt.sample.stockwatcher.StockWatcher.JUnit'
Here is my StockWatcherTest.java class
package com.google.gwt.sample.stockwatcher.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* GWT JUnit tests must extend GWTTestCase.
*/
public class StockWatcherTest extends GWTTestCase {
/**
* Must refer to a valid module that sources this class.
*/
public String getModuleName() {
return "com.google.gwt.sample.stockwatcher.StockWatcher";
}
/**
* Add as many tests as you like.
*/
public void testSimple() {
GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
greetingService.greetServer("Bob",
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
System.out.println(caught);
fail("big time failure");
finishTest();
}
public void onSuccess(String result) {
System.out.println("success, biatch");
assertTrue(true);
}
});
delayTestFinish(1000);
}
}
Here is com/google/gwt/sample/stockwatcher/StockWatcher.gwt.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.2//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.6.2/distro-source/core/src/gwt-module.dtd">
<module rename-to='stockwatcher'>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. You can change -->
<!-- the theme of your GWT application by uncommenting -->
<!-- any one of the following lines. -->
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<!-- Other module inherits -->
<!-- Specify the app entry point class. -->
<entry-point class='com.google.gwt.sample.stockwatcher.client.StockWatcher'/>
</module>
and here is web.xml in my generated war
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>StockWatcher.html</welcome-file>
</welcome-file-list>
<!-- Servlets -->
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>com.google.gwt.sample.stockwatcher.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/stockwatcher/greet</url-pattern>
</servlet-mapping>
</web-app>
So what am I doing wrong? Any help is appreciated. Thank you.
1-you need to add "finishTest();" at the end of the "onSuccess" method.
2-And to resolve the exeption you got : add in your StockWatcher.gwt.xml the path to your servlet greet.
servlet path='/greet' class='com.google.gwt.sample.stockwatcher.server.GreetingServiceImpl'/
Another solution is using GWT SyncProxy (support both sync & async) to test GWT RPC services in JRE
See the post at http://www.gdevelop.com/w/blog/2010/01/10/testing-gwt-rpc-services/ for details
i made some simple tests for the stock watcher. you can see them at: http://tayek.com/StockWatcher.zip