Configurar o Error Reporting no Amazon EC2

Envie os erros dos seus aplicativos do EC2 para o Error Reporting de duas maneiras:

Usar o Logging para relatar erros

Para conectar seus aplicativos do EC2 ao Error Reporting, envie exceções ou outros erros para o Logging.

Exemplo:

  1. Conecte o sistema da Amazon Web Services (AWS) ao Google Cloud. Para mais informações, consulte Como instalar o agente do Logging em VMs individuais.
  2. Instale o agente do Logging google-fluentd adequado para seu ambiente. Para instruções, consulte Como instalar o agente do Logging.
  3. Modifique seu aplicativo para que ele registre exceções e stack traces no Logging.

    É preciso incluir todas as informações de um único erro ou exceção na mesma entrada de registro, incluindo todos os frames de qualquer stack trace. Caso contrário, o Error Reporting poderá não detectar o erro. É possível usar o formato JSON estruturado nos seus payloads de entrada de registro para incluir diferentes tipos de informações de cada erro.

  4. Java

    Adicione a instrução a seguir ao seu arquivo pom.xml:

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

    Depois, use o código como o demonstrado a seguir para enviar os dados da exceção:

    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

    Primeiro, instale a biblioteca fluent-logger-python (em inglês):

    sudo pip install fluent-logger
    

    Depois, use o código como o demonstrado a seguir para enviar os dados da exceção:

    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

    Primeiro, instale a biblioteca fluent-logger-node (em inglês):

    npm install --save fluent-logger
    

    Depois, use o código como o demonstrado a seguir para enviar os dados da exceção:

    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

    Primeiro, instale o pacote fluent-logger-golang (em inglês):

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

    Depois, use o código como o demonstrado a seguir para enviar dados do erro:

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

    Usar a API Error Reporting para gravar erros

    A API Error Reporting fornece um endpoint report para gravar informações de erro no serviço.

    1. Enable the Error Reporting API.

      Enable the API

    2. Informe erros na API usando a API REST ou uma biblioteca de cliente.

    Amostras

    ASP.NET

    O pacote NuGet do ASP.NET relata exceções não identificadas de aplicativos da Web do ASP.NET ao Error Reporting.

    Instalar o pacote NuGet

    Para instalar o pacote NuGet para ASP.NET do Stackdriver no Visual Studio:

    1. Clique com o botão direito do mouse em sua solução e selecione Gerenciar pacotes NuGet para solução.
    2. Marque a caixa de seleção Incluir pré-lançamento.
    3. Pesquise e instale o pacote Google.Cloud.Diagnostics.AspNet.

    Uso

    Após instalar o pacote NuGet para ASP.NET do Stackdriver, adicione o comando a seguir ao código do seu aplicativo para começar a enviar os erros ao Stackdriver:

    using Google.Cloud.Diagnostics.AspNet;
    

    Adicione o seguinte código HttpConfiguration ao método Register do seu app da Web .NET, substituindo your-project-id pelo ID do projeto atual para ativar a geração de relatórios de exceções:

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

    Depois de adicionar esse método ao aplicativo ASP.NET, é possível visualizar as exceções não identificadas assim que elas forem registradas no Google Cloud na seção Error Reporting do console do Google Cloud.

    C#

    O exemplo a seguir está localizado no repositório GoogleCloudPlatform/dotnet-docs-samples. Para usá-lo após a criação do projeto, especifique seu código do projeto:

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

    Substitua [YOUR_PROJECT_ID] pelo valor correto do console do Google Cloud.

    Em seguida, envie os dados da exceção com um código semelhante a este:

    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

    Consulte Como configurar o Error Reporting para Go.

    Java

    Consulte Como configurar o Error Reporting para Java.

    Node.js

    Consulte Como configurar o Error Reporting para Node.js.

    Ruby

    Consulte Como configurar o Error Reporting para Ruby.

    Python

    Consulte Como configurar o Error Reporting para Python.

    PHP

    Veja Como configurar o Error Reporting para PHP.

    Acessar grupos de erros

    No console do Google Cloud, acesse a página Error Reporting:

    Acessar o Error Reporting

    Também é possível encontrar essa página usando a barra de pesquisa.