Setting up Error Reporting on Amazon EC2

You can send errors from your EC2 applications to Stackdriver Error Reporting in one of two ways:

Using Logging to report errors

To connect your EC2 applications to Error Reporting, send your exceptions or other errors to Logging, using a dedicated log name to keep your errors separate from your other logs.

For example:

  1. Enable the Stackdriver Logging API.

    Enable the API

  2. Install the Logging agent google-fluentd on your EC2 instance. The agent is generally needed on EC2 instances to send logs to Logging.

  3. Modify your application so that it logs exceptions and their stack traces to Logging. Choose a log name for your error information to keep it separate from other logged information.

    You must include all the information for a single error or exception in the same log entry, including all the frames of any stack trace. If all the information is not together, Error Reporting might not pick up the information. You can use the structured JSON format for your log entry payloads to include different kinds of information for each error.

Java

Add the following to your pom.xml file:

<dependency>
  <groupId>org.fluentd</groupId>
  <artifactId>fluent-logger</artifactId>
  <version>0.3.4</version>
</dependency>

Then use code like the following to send the exception data:

public class ExceptionUtil {
  private static FluentLogger ERRORS = FluentLogger.getLogger("myapp");

  public static void main(String[] args) {
    try {
      throw new Exception("Generic exception for testing Stackdriver");
    } catch (Exception e) {
      report(e);
    }
  }

  public static void report(Throwable ex) {
    StringWriter exceptionWriter = new StringWriter();
    ex.printStackTrace(new PrintWriter(exceptionWriter));
    Map<String, Object> data = new HashMap<>();
    data.put("message", exceptionWriter.toString());
    Map<String,String> serviceContextData = new HashMap<>();
    serviceContextData.put("service", "myapp");
    data.put("serviceContext", serviceContextData);
    // ... add more metadata
    ERRORS.log("errors", data);
  }
}

Python

First, install the fluent-logger-python library:

sudo pip install fluent-logger

Then use code like the following to send the exception data:

import traceback

import fluent.event
import fluent.sender


def simulate_error():
    fluent.sender.setup('myapp', host='localhost', port=24224)

    def report(ex):
        data = {}
        data['message'] = '{0}'.format(ex)
        data['serviceContext'] = {'service': 'myapp'}
        # ... add more metadata
        fluent.event.Event('errors', data)

    # report exception data using:
    try:
        # simulate calling a method that's not defined
        raise NameError
    except Exception:
        report(traceback.format_exc())

Node.js

First, install the fluent-logger-node library:

npm install --save fluent-logger

Then use code like the following to send the exception data:

const structuredLogger = require('fluent-logger').createFluentSender('myapp', {
  host: 'localhost',
  port: 24224,
  timeout: 3.0,
});

const report = (err, req) => {
  const payload = {
    serviceContext: {
      service: 'myapp',
    },
    message: err.stack,
    context: {
      httpRequest: {
        url: req.originalUrl,
        method: req.method,
        referrer: req.header('Referer'),
        userAgent: req.header('User-Agent'),
        remoteIp: req.ip,
        responseStatusCode: 500,
      },
    },
  };
  structuredLogger.emit('errors', payload);
};

// Handle errors (the following uses the Express framework)
// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
  report(err, req);
  res.status(500).send(err.response || 'Something broke!');
});

Go

First, install the fluent-logger-golang package:

go get -u github.com/fluent/fluent-logger-golang/

Then use code like the following to send error data:


package main

import (
	"log"
	"net/http"
	"runtime"

	"github.com/fluent/fluent-logger-golang/fluent"
)

var logger *fluent.Fluent

func main() {
	var err error
	logger, err = fluent.New(fluent.Config{
		FluentHost: "localhost",
		FluentPort: 24224,
	})
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/demo", demoHandler)
	http.ListenAndServe(":8080", nil)
}

func report(stackTrace string, r *http.Request) {
	payload := map[string]interface{}{
		"serviceContext": map[string]interface{}{
			"service": "myapp",
		},
		"message": stackTrace,
		"context": map[string]interface{}{
			"httpRequest": map[string]interface{}{
				"method":    r.Method,
				"url":       r.URL.String(),
				"userAgent": r.UserAgent(),
				"referrer":  r.Referer(),
				"remoteIp":  r.RemoteAddr,
			},
		},
	}
	if err := logger.Post("myapp.errors", payload); err != nil {
		log.Print(err)
	}
}

// Handler for the incoming requests.
func demoHandler(w http.ResponseWriter, r *http.Request) {
	// How to handle a panic.
	defer func() {
		if e := recover(); e != nil {
			stack := make([]byte, 1<<16)
			stackSize := runtime.Stack(stack, true)
			report(string(stack[:stackSize]), r)
		}
	}()

	// Panic is triggered.
	x := 0
	log.Println(100500 / x)
}

Using the Error Reporting API to write errors

The Stackdriver Error Reporting API provides a report endpoint for writing error information to the service.

  1. Enable the Stackdriver Error Reporting API.

    Enable the API

  2. Report errors to the API using either the REST API or a client library.

    • REST API

      See the reference documentation for information about the API.

    • Using client libraries

      Libraries exist in a limited number of languages to help you call the Error Reporting API from your application:

Samples

ASP.NET

The Stackdriver ASP.NET NuGet package reports uncaught exceptions from ASP.NET web applications to Stackdriver Error Reporting.

Install the NuGet package

To install the Stackdriver ASP.NET NuGet package in Visual Studio:

  1. Right-click your solution and select Manage NuGet packages for solution.
  2. Select the Include prerelease checkbox.
  3. Search for and install the package named Google.Cloud.Diagnostics.AspNet.

Usage

Once you've installed the Stackdriver ASP.NET NuGet package, add the following statement to your application code to start sending errors to Stackdriver:

using Google.Cloud.Diagnostics.AspNet;

Add the following HttpConfiguration code to the Register method of your .NET web app (replacing your-project-id with your actual project ID){: class="external" } to enable the reporting of exceptions:

public static void Register(HttpConfiguration config)
{
    string projectId = "YOUR-PROJECT-ID";
    string serviceName = "NAME-OF-YOUR-SERVICE";
    string version = "VERSION-OF-YOUR-SERVCICE";
    // ...
    // Add a catch all for the uncaught exceptions.
    config.Services.Add(typeof(IExceptionLogger),
        ErrorReportingExceptionLogger.Create(projectId, serviceName, version));
    // ...
}

Once you've added this method to your ASP.NET application, you can view any uncaught exceptions that occur as they get reported to Google Cloud in the Stackdriver Error Reporting section of the GCP Console.

C#

The following example can be found in the GoogleCloudPlatform/dotnet-docs-samples repo. To use it, after building the project, specify your project ID:

C:\...\bin\Debug> set GOOGLE_PROJECT_ID=[YOUR_PROJECT_ID]

Make sure to replace [YOUR_PROJECT_ID] with the correct value from the GCP Console.

Then, send exception data with code similar to the following:

public class ErrorReportingSample
{
    public static void Main(string[] args)
    {
        try
        {
            throw new Exception("Generic exception for testing Stackdriver Error Reporting");
        }
        catch (Exception e)
        {
            report(e);
            Console.WriteLine("Stackdriver Error Report Sent");
        }
    }

    /// <summary>
    /// Create the Error Reporting service (<seealso cref="ClouderrorreportingService"/>)
    /// with the Application Default Credentials and the proper scopes.
    /// See: https://developers.google.com/identity/protocols/application-default-credentials.
    /// </summary>
    private static ClouderrorreportingService CreateErrorReportingClient()
    {
        // Get the Application Default Credentials.
        GoogleCredential credential = GoogleCredential.GetApplicationDefaultAsync().Result;

        // Add the needed scope to the credentials.
        credential.CreateScoped(ClouderrorreportingService.Scope.CloudPlatform);

        // Create the Error Reporting Service.
        ClouderrorreportingService service = new ClouderrorreportingService(new BaseClientService.Initializer
        {
            HttpClientInitializer = credential,
        });
        return service;
    }

    /// <summary>
    /// Creates a <seealso cref="ReportRequest"/> from a given exception.
    /// </summary>
    private static ReportRequest CreateReportRequest(Exception e)
    {
        // Create the service.
        ClouderrorreportingService service = CreateErrorReportingClient();

        // Get the project ID from the environement variables.
        string projectId = Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID");

        // Format the project id to the format Error Reporting expects. See:
        // https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events/report
        string formattedProjectId = string.Format("projects/{0}", projectId);

        // Add a service context to the report.  For more details see:
        // https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events#ServiceContext
        ServiceContext serviceContext = new ServiceContext()
        {
            Service = "myapp",
            Version = "8c1917a9eca3475b5a3686d1d44b52908463b989",
        };
        ReportedErrorEvent errorEvent = new ReportedErrorEvent()
        {
            Message = e.ToString(),
            ServiceContext = serviceContext,
        };
        return new ReportRequest(service, errorEvent, formattedProjectId);
    }

    /// <summary>
    /// Report an exception to the Error Reporting service.
    /// </summary>
    private static void report(Exception e)
    {
        // Create the report and execute the request.
        ReportRequest request = CreateReportRequest(e);
        request.Execute();
    }
}

Go

See Setting up Error Reporting for Go.

Java

See Setting up Error Reporting for Java.

Node.js

See Setting up Error Reporting for Node.js.

Ruby

See Setting up Error Reporting for Ruby.

Python

See Setting up Error Reporting for Python.

Var denne side nyttig? Giv os en anmeldelse af den:

Send feedback om...

Stackdriver Error Reporting
Har du brug for hjælp? Besøg vores supportside.