在 Amazon EC2 中设置 Error Reporting

您可以通过下列任一方式将 EC2 应用的错误发送到 Stackdriver Error Reporting:

使用 Logging 报告错误

要将 EC2 应用连接到 Stackdriver Error Reporting,请使用专用日志名称将异常或其他错误发送到 Stackdriver Logging,以使您的错误与其他日志分开。例如:

  1. 启用Stackdriver Logging API。

    启用 API

  2. 在 EC2 实例上安装 Stackdriver Logging 代理 google-fluentd。要将日志发送到 Logging,通常需要在 EC2 实例上使用代理。

  3. 修改您的应用,使其能将异常及其堆栈轨迹记录到 Stackdriver Logging 中。为您的错误信息选择日志名称,使其与其他已记录的信息分开。

    您必须在同一日志条目中添加单个错误或异常的所有信息,包括任何堆栈轨迹的所有帧。如果所有信息没有收集在一起,则 Error Reporting 可能就无法获得这些信息。您可以对日志条目负载使用结构化 JSON 格式,以添加每个错误的不同类型的信息。

Java

将以下内容添加到您的 pom.xml 文件中:

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

然后,使用如下代码发送异常数据:

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

首先,安装 fluent-logger-python

sudo pip install fluent-logger

然后,使用如下代码发送异常数据:

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

首先,安装 fluent-logger-node

npm install --save fluent-logger

然后,使用如下代码发送异常数据:

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

首先,安装 fluent-logger-golang 软件包

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

然后,使用如下代码发送错误数据:

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

使用 Error Reporting API 写入错误

Stackdriver Error Reporting API 提供了可用于将错误信息写入服务的 report 端点。

  1. 启用Stackdriver Error Reporting API。

    启用 API

  2. 使用 REST API 或客户端库向 API 报告错误。

    • REST API

      要了解此 API,请查看参考文档

    • 使用客户端库

      这些库支持部分语言,它们可帮助您从应用中调用 Error Reporting API:

示例

ASP.NET

Stackdriver ASP.NET NuGet 程序包将 ASP.NET 网页应用中未捕获的异常报告给 Stackdriver Error Reporting。

安装 NuGet 程序包

要在 Visual Studio 中安装 Stackdriver ASP.NET NuGet 程序包,请执行以下操作:

  1. 右键点击您的解决方案,然后选择管理解决方案的 NuGet 程序包
  2. 选中包括预发行版复选框。
  3. 搜索并安装名为 Google.Cloud.Diagnostics.AspNet 的软件包。

用法

安装 Stackdriver ASP.NET NuGet 程序包之后,请将下列语句添加到应用代码中,以开始向 Stackdriver 发送错误:

using Google.Cloud.Diagnostics.AspNet;

将下列 HttpConfiguration 代码添加到 .NET 网页应用的 Register 方法中(将 your-project-id 替换为您的实际项目 ID),以启用异常报告:

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

将此方法添加到 ASP.NET 应用之后,即可在 GCP Console 的 Stackdriver Error Reporting 部分中查看向 Google Cloud 报告异常时未捕获的任何异常。

C#

有关以下示例,可查看 GoogleCloudPlatform/dotnet-docs-samples 代码库。要使用该示例,请在构建项目后指定项目 ID

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

确保使用 GCP Console 中正确的值来替换 [YOUR_PROJECT_ID]

然后,使用如下代码发送异常数据:

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

请参阅为 Go 设置 Stackdriver Error Reporting

Java

请参阅为 Java 设置 Stackdriver Error Reporting

Node.js

请参阅为 Node.js 设置 Stackdriver Error Reporting

Ruby

请参阅为 Ruby 设置 Stackdriver Error Reporting

Python

请参阅设置 Python 版 Stackdriver Error Reporting

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Stackdriver Error Reporting
需要帮助?请访问我们的支持页面