Configurer Error Reporting sur Compute Engine

Vous pouvez envoyer des erreurs depuis les applications Compute Engine à Error Reporting à l'aide de l'une des deux méthodes suivantes :

Utiliser Logging pour signaler des erreurs

Pour connecter les applications Compute Engine à Error Reporting, envoyez les exceptions ou autres erreurs à Logging, en utilisant un nom de journal dédié pour que les erreurs soient séparées des autres journaux.

Exemple :

  1. Activez l'API Cloud Logging.

    Activer l'API

  2. Installez l'agent Logging correspondant à votre environnement. Pour obtenir des instructions, consultez la page Installer l'agent Logging google-fluentd.

  3. Modifiez l'application afin qu'elle enregistre les exceptions et leurs traces de pile dans Logging. Choisissez un nom de journal pour les informations d'erreur afin de les séparer des autres informations consignées.

    Vous devez inclure toutes les informations d'une seule erreur ou exception dans la même entrée de journal, y compris toutes les frames d'une trace de pile. Si toutes les informations ne sont pas rassemblées, Error Reporting risque de ne pas les récupérer. Vous pouvez utiliser le format JSON structuré pour les charges utiles d'entrée de journal afin d'inclure différents types d'informations pour chaque erreur.

Java

Ajoutez le code ci-dessous à votre fichier pom.xml :

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

Exécutez ensuite le code suivant pour envoyer les données relatives aux exceptions :

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

Commencez par installer la bibliothèque fluent-logger-python :

sudo pip install fluent-logger

Exécutez ensuite le code suivant pour envoyer les données relatives aux exceptions :

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

Commencez par installer la bibliothèque fluent-logger-node :

npm install --save fluent-logger

Exécutez ensuite le code suivant pour envoyer les données relatives aux exceptions :

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

Commencez par installer le package fluent-logger-golang :

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

Exécutez ensuite le code suivant pour envoyer les données relatives aux erreurs :


package main

import (
	"log"
	"net/http"
	"os"
	"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)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Printf("Listening on port %s", port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatal(err)
	}
}

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

Utiliser l'API Error Reporting pour écrire des erreurs

L'API Error Reporting fournit un point de terminaison report pour écrire les informations d'erreur à destination du service.

  1. Activez l'API Error Reporting.

    Activer l'API

  2. Signalez les erreurs à l'API à l'aide de l'API REST ou d'une bibliothèque cliente.

Exemples

ASP.NET

Le package NuGet ASP.NET Stackdriver signale les exceptions non détectées depuis les applications Web ASP.NET à Error Reporting.

Installer le package NuGet

Pour installer le package NuGet ASP.NET Stackdriver dans Visual Studio :

  1. Cliquez avec le bouton droit sur votre solution et sélectionnez Gérer les packages NuGet pour la solution.
  2. Cochez la case Inclure la version préliminaire.
  3. Recherchez et installez le package nommé Google.Cloud.Diagnostics.AspNet.

Utilisation

Une fois que vous avez installé le package NuGet ASP.NET Stackdriver, ajoutez la déclaration suivante à votre code d'application pour commencer à envoyer des erreurs à Stackdriver :

using Google.Cloud.Diagnostics.AspNet;

Ajoutez le code HttpConfiguration suivant à la méthode Register de l'application Web .NET (en remplaçant your-project-id par votre ID de projet) pour autoriser le signalement des 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));
    // ...
}

Une fois que vous avez ajouté cette méthode à votre application ASP.NET, vous pouvez afficher toutes les exceptions non détectées qui ont été signalées à Google Cloud dans la section Error Reporting de Cloud Console.

C#

L'exemple suivant est disponible dans le dépôt GoogleCloudPlatform/dotnet-docs-samples. Pour l'utiliser après avoir créé le projet, spécifiez votre ID de projet :

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

Veillez à remplacer [YOUR_PROJECT_ID] par la valeur correcte dans Cloud Console.

Ensuite, envoyez les données d'exception avec le code suivant :

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

Consultez la page Configurer Error Reporting pour Go.

Java

Consultez la page Configurer Error Reporting pour Java.

Node.js

Consultez la page Configurer Error Reporting pour Node.js.

Ruby

Consultez la page Configurer Error Reporting pour Ruby.

Python

Consultez la page Configurer Error Reporting pour Python.