Compute Engine での設定

次のどちらかの方法で、Compute Engine アプリケーションから Error Reporting にエラーを送信できます。

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

Compute Engine アプリケーションを Error Reporting に接続するには、例外やその他のエラーを Logging に送信します。その際、エラーログを他のログから区別するために、エラー専用のログ名を使用してください。

例:

  1. Cloud Logging API を有効にします。

    API を有効にする

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

  3. 例外とスタック トレースを 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 --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"
	"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 を有効にする

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

サンプル

ASP.NET

Stackdriver 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 アプリケーションに追加すると、Cloud Console の Error Reporting セクションで Google Cloud に報告されたときに発生する捕捉されなかった例外を表示できます。

C#

次の例は、GoogleCloudPlatform/dotnet-docs-samples リポジトリにあります。これを使用するには、プロジェクトのビルド後に次のようにプロジェクト ID を指定します。

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

必ず、[YOUR_PROJECT_ID] を Cloud Console からの正しい値に置き換えてください。

その後、次のようなコードで例外データを送信します。

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 の設定をご覧ください。