diff --git a/flexible/errorreporting/README.md b/flexible/errorreporting/README.md
new file mode 100644
index 00000000000..089cbfb8fb3
--- /dev/null
+++ b/flexible/errorreporting/README.md
@@ -0,0 +1,52 @@
+# Error reporting sample for Google App Engine Flexible
+
+[Stackdriver Error Reporting][error-reporting] Stackdriver Error Reporting counts, analyzes and aggregates the crashes in your running cloud services.
+A [centralized error management interface](https://console.cloud.google.com/errors) displays the results with sorting and filtering capabilities.
+
+This sample Java application demonstrates how errors are automatically sent to Error reporting in applications running in [App Engine Flex environment][ae-flex].
+It also demonstrates how to send custom error events using the Error Reporting API.
+
+[error-reporting]: https://cloud.google.com/error-reporting/
+[ae-flex]: https://cloud.google.com/appengine/docs/flexible/java
+[google-cloud-java]: https://github.com/GoogleCloudPlatform/google-cloud-java
+
+## Setup
+
+1. Install [Maven](http://maven.apache.org/).
+1. Install and initialize [GCloud SDK](https://cloud.google.com/sdk/downloads).
+1. [Enable](https://console.cloud.google.com/apis/api/clouderrorreporting.googleapis.com/overview) Stack Driver Error Reporting API.
+(Note : only required for logging custom events using the Error Reporting API)
+
+## Build
+Build your project with:
+```
+ mvn clean package
+```
+
+## Local testing
+1. Authorize the local environment
+```
+ gcloud auth application-default login
+```
+For local testing, we will be using the [Jetty Maven plugin](http://www.eclipse.org/jetty/documentation/9.4.x/jetty-maven-plugin.html).
+Run:
+```
+ mvn jetty:run
+```
+Access [http://localhost:8080/error](http://localhost:8080/error) endpoint.
+
+After accessing the `/error` endpoint, check the [error reporting console](https://console.cloud.google.com/errors).
+Confirm that you see the custom error reported using the error reporting API.
+
+## Deploy
+Run:
+```
+ mvn appengine:deploy
+```
+Access [https://YOUR_PROJECT_ID.appspot.com/error] endpoint.
+
+After accessing the `/error` endpoint, check the [error reporting console](https://console.cloud.google.com/errors).
+Confirm that you see:
+1. IllegalArgumentException logged via the standard logging framework.
+1. Custom error reported using the error reporting API.
+1. Runtime exception.
diff --git a/flexible/errorreporting/pom.xml b/flexible/errorreporting/pom.xml
new file mode 100644
index 00000000000..05599c4a521
--- /dev/null
+++ b/flexible/errorreporting/pom.xml
@@ -0,0 +1,90 @@
+
+
+
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.
+ */
+package com.example.flexible.errorreporting;
+
+import com.google.cloud.ServiceOptions;
+import com.google.cloud.errorreporting.v1beta1.ReportErrorsServiceClient;
+import com.google.devtools.clouderrorreporting.v1beta1.ProjectName;
+import com.google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+// [START flex_error_reporting]
+@WebServlet(name = "Error reporting", value = "/error")
+public class ErrorReportingExample extends HttpServlet {
+
+ private Logger logger = Logger.getLogger(ErrorReportingExample.class.getName());
+
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws IOException, ServletException {
+
+ // errors logged to stderr / Cloud logging with exceptions are automatically reported.
+ logger.log(Level.SEVERE, "exception using log framework", new IllegalArgumentException());
+
+ // use the error-reporting client library to log custom error events
+ logCustomErrorEvent();
+
+ // runtime exceptions are also automatically picked up by error reporting.
+ throw new RuntimeException("this is a runtime exception");
+ }
+
+ private void logCustomErrorEvent() {
+ try (ReportErrorsServiceClient reportErrorsServiceClient = ReportErrorsServiceClient.create()) {
+ // custom exception logged using the API
+ Exception e = new Exception("custom event reported using the API");
+ // Events reported using the API must contain a stack trace message
+ StringWriter stackTrace = new StringWriter();
+ e.printStackTrace(new PrintWriter(stackTrace));
+ ReportedErrorEvent errorEvent =
+ ReportedErrorEvent.getDefaultInstance()
+ .toBuilder()
+ .setMessage(stackTrace.toString())
+ .build();
+ // default project id
+ ProjectName projectName = ProjectName.create(ServiceOptions.getDefaultProjectId());
+ reportErrorsServiceClient.reportErrorEvent(projectName, errorEvent);
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, "Exception encountered logging custom event", e);
+ }
+ }
+}
+// [END flex_error_reporting]
diff --git a/pom.xml b/pom.xml
index 465b313e4d9..749ab2282c1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,6 +57,7 @@