Configura Error Reporting en Amazon EC2

Puedes enviar errores desde tus aplicaciones de EC2 a Error Reporting de una de estas dos maneras:

Usa Logging para informar sobre errores

Para conectar tus aplicaciones EC2 a Error Reporting, envía tus excepciones, o bien otros errores, a Logging.

Por ejemplo:

  1. Conecta el sistema de Amazon Web Services (AWS) a Google Cloud. Para obtener más información, consulta Instala el agente de Logging en VMs individuales.
  2. Instala el agente google-fluentd de Logging que sea adecuado para tu entorno. Para obtener instrucciones, consulta Instala el agente de Logging.
  3. Modifica tu aplicación para que registre las excepciones y los seguimientos de pila en Logging.

    Debes incluir toda la información de un solo error o excepción en la misma entrada de registro, incluidos todos los marcos de cualquier seguimiento de pila. Si toda la información no está junta, es posible que Error Reporting no detecte el error. Puedes usar el formato JSON estructurado para que las cargas útiles de tu entrada de registro incluyan diferentes tipos de datos para cada error.

  4. Java

    Agrega lo siguiente a tu archivo pom.xml:

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

    Luego, usa un código como el siguiente para enviar los datos de excepción:

    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

    Primero, instala la biblioteca fluent-logger-python:

    sudo pip install fluent-logger
    

    Luego, usa un código como el siguiente para enviar los datos de excepción:

    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

    Primero, instala la biblioteca fluent-logger-node:

    npm install --save fluent-logger
    

    Luego, usa un código como el siguiente para enviar los datos de excepción:

    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

    Primero, instala el paquete fluent-logger-golang:

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

    Luego, usa un código como el siguiente para enviar datos de errores:

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

    Usa la API de Error Reporting para escribir errores

    La API de Error Reporting proporciona un extremo report para escribir información de error en el servicio.

    1. Enable the Error Reporting API.

      Enable the API

    2. Informa errores a la API con la API de REST o una biblioteca cliente.

    Ejemplos

    ASP.NET

    El paquete ASP.NET NuGet informa sobre excepciones no detectadas de las aplicaciones web de ASP.NET a Error Reporting.

    Instala el paquete NuGet

    Para instalar el paquete Stackdriver ASP.NET NuGet en Visual Studio, haz lo siguiente:

    1. Haz clic derecho en la solución y selecciona Administrar paquetes NuGet para la solución.
    2. Selecciona la casilla de verificación Incluir lanzamiento anticipado.
    3. Busca y, luego, instala el paquete llamado Google.Cloud.Diagnostics.AspNet.

    Uso

    Una vez que hayas instalado el paquete Stackdriver ASP.NET NuGet, agrega la siguiente declaración al código de tu aplicación para comenzar a enviar errores a Stackdriver:

    using Google.Cloud.Diagnostics.AspNet;
    

    Agrega el siguiente código HttpConfiguration al método Register de tu aplicación web .NET (reemplaza your-project-id por tu ID del proyecto real) para habilitar el informe de excepciones:

    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));
        // ...
    }
    

    Una vez que hayas agregado este método a tu aplicación ASP.NET, podrás ver las excepciones no detectadas que se produzcan a medida que se informen a Google Cloud en la sección Error Reporting de la consola de Google Cloud.

    C#

    El siguiente ejemplo se puede encontrar en el repositorio GoogleCloudPlatform/dotnet-docs-samples. Para usarlo, luego de compilar el proyecto, especifica el ID del proyecto:

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

    Asegúrate de reemplazar [YOUR_PROJECT_ID] por el valor correcto de la consola de Google Cloud.

    Luego, envía datos de excepciones con un código similar al siguiente:

    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

    Consulta Configura Error Reporting para Go.

    Java

    Consulta Configura Error Reporting para Java.

    Node.js

    Consulta Configura Error Reporting para Node.js.

    Ruby

    Consulta Configura Error Reporting para Ruby.

    Python

    Consulta Configura Error Reporting para Python.

    PHP

    Consulta Configura Error Reporting para PHP.

    Cómo ver los grupos de errores

    En la consola de Google Cloud, ve a la página Error Reporting.

    Ir a Error Reporting

    También puedes usar la barra de búsqueda para encontrar esta página.