在 Compute Engine 上設定

您可以透過下列任一方式,從 Compute Engine 應用程式傳送錯誤至 Error Reporting:

使用 Logging 回報錯誤

如要將 Compute Engine 應用程式連線至 Error Reporting,請將例外狀況或其他錯誤傳送到 Logging。

例如:

  1. 視環境需要安裝 Logging google-fluentd 代理程式。如需操作說明,請參閱安裝 Logging 代理程式
  2. 修改應用程式,讓應用程式將例外狀況和其堆疊追蹤記錄到 Logging。

    您必須將單一錯誤或例外狀況的所有資訊放在同一個記錄項目中,包括任何堆疊追蹤的所有框架。若未將所有資訊放在一起,Error Reporting 就可能無法偵測到錯誤。您可以在記錄項目酬載使用結構化 JSON 格式,納入每個錯誤的各種資訊。

Java

請將以下內容新增到您的 pom.xml 檔案中:

<dependency>
  <groupId>org.fluentd</groupId>
  <artifactId>fluent-logger</artifactId>
  <version>0.3.4</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 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 github.com/fluent/fluent-logger-golang/

然後使用下方程式碼傳送錯誤資料:


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

使用 Error Reporting API 寫入錯誤

Error Reporting API 提供 report 端點,可將錯誤資訊寫入服務。

  1. Enable the Error Reporting API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  2. 使用 REST API 或用戶端程式庫將錯誤回報至 API。

範例

ASP.NET

ASP.NET NuGet 套件會將 ASP.NET 網頁應用程式中未捕捉到的例外狀況回報給 Error Reporting。

安裝 NuGet 套件

如要在 Visual Studio 中安裝 Stackdriver ASP.NET NuGet 套件:

  1. 以滑鼠右鍵按一下您的解決方案,然後選取 [管理解決方案的 NuGet 套件]
  2. 選取 [Include prerelease] (包括搶鮮版) 核取方塊。
  3. 搜尋並安裝名為 Google.Cloud.Diagnostics.AspNet 的套件。

用量

Stackdriver ASP.NET NuGet 套件安裝完成後,請新增下列陳述式至應用程式程式庫,以便開始傳送錯誤至 Stackdriver:

using Google.Cloud.Diagnostics.AspNet;

在 .NET 網頁應用程式的 Register 方法中加入下列 HttpConfiguration 程式碼,並將 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 應用程式後,您就可以在 Google Cloud 控制台的「Error Reporting」部分中,查看所有未處理的例外狀況 (系統會將這些例外狀況回報給 Google Cloud)。

C#

您可以在 GoogleCloudPlatform/dotnet-docs-samples 存放區中找到下列範例。如要使用,請在建構專案後指定專案 ID

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

請務必將 [YOUR_PROJECT_ID] 替換為Google Cloud 控制台中的正確值。

然後,使用與下列相似的程式碼傳送例外狀況資料:

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 適用的 Error Reporting」。

Java

請參閱「設定 Java 適用的 Error Reporting」。

Node.js

請參閱「設定 Node.js 適用的 Error Reporting」。

Ruby

請參閱「設定 Ruby 適用的 Error Reporting」。

Python

請參閱「設定 Python 適用的 Error Reporting」。

PHP

請參閱「設定 PHP 適用的 Error Reporting」。

查看錯誤群組

前往 Google Cloud 控制台的「Error Reporting」頁面:

前往 Error Reporting

您也可以透過搜尋列找到這個頁面。