Compute Engine での設定

Error Reporting を使用すると、Compute Engine アプリケーションのクラッシュを集計し、ランタイム例外を診断できます。エラーデータを送信するには、Cloud Logging にログをストリーミングするか、Error Reporting API を直接呼び出します。Logging を使用する場合、ログエントリは形式の要件に準拠している必要があります。

ロギングを使用してエラーを報告する

Compute Engine アプリケーションを Error Reporting に接続するには、次のいずれかのエージェントを使用して、例外やその他のエラーを Logging に送信します。

Ops エージェント

Ops エージェントを使用するように Error Reporting を設定する手順は次のとおりです。

  1. ご使用の環境に適した Ops エージェントをインストールします。手順については、Ops エージェントのインストールをご覧ください。

  2. アプリケーション ログを収集して適切にフォーマットするように Ops エージェントを構成します。

    • サポートされているサードパーティ アプリケーションの場合: Ops エージェントは、ログエントリを自動的にキャプチャして、Error Reporting が認識する構造化形式に解析する、事前構成済みのロギング レシーバを提供します。サポートされているサードパーティ アプリケーションについては、サードパーティ アプリケーションのモニタリングをご覧ください。

    • カスタム アプリケーションの場合: ロギング レシーバを構成してログファイルの場所を指定し、次のいずれかのプロセッサとペア設定します。

      • アプリが複数行にわたってプレーン テキストのスタック トレースを書き込む場合は、parse_multiline プロセッサを使用します。
      • アプリがログを JSON 文字列として書き込む場合は、parse_json プロセッサを使用します。

      詳しい手順については、Ops エージェントを構成するをご覧ください。

  3. アプリケーションが標準のスタック トレースを生成しない場合は、例外とスタック トレースを Cloud Logging に記録するようにアプリケーションを変更します。

    単一のエラーまたは例外に関する情報は、スタック トレースのすべてのフレームを含め、すべて同じログエントリに格納する必要があります。すべての情報が 1 つにまとめられていないと、Error Reporting でエラーを検出できない可能性があります。ログエントリのペイロードに構造化 JSON 形式を使用すると、各エラーに関するさまざまな情報を含めることができます。

以前の Logging エージェント

以前の Logging エージェントを使用するように Error Reporting を設定する手順は次のとおりです。

  1. ご使用の環境に適した Logging google-fluentd エージェントをインストールします。手順については、Logging エージェントをインストールするをご覧ください。
  2. 例外とスタック トレースを Logging に記録するようにアプリケーションを変更します。

    単一のエラーまたは例外に関する情報は、スタック トレースのすべてのフレームを含め、すべて同じログエントリに格納する必要があります。すべての情報が 1 つにまとめられていないと、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. Error Reporting API を有効にします(有効になっていない場合)。

    API を有効にするために必要なロール

    API を有効にするには、serviceusage.services.enable 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)を通じてこの権限がすでに付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)を通じてこの権限を取得できます。ロールを付与する方法を確認する。

    API の有効化

  2. REST API またはクライアント ライブラリのいずれかを使用して、API にエラーを報告します。

サンプル

ASP.NET

ASP.NET NuGet パッケージにより、捕捉されなかった例外が ASP.NET ウェブ アプリケーションから Error Reporting に報告されます。

NuGet パッケージをインストールする

Stackdriver ASP.NET NuGet パッケージを Visual Studio にインストールするには:

  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 アプリケーションに追加すると、発生した例外で捕捉されなかった例外が 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 に移動

このページは、検索バーを使用して見つけることもできます。