在 Amazon EC2 上設定 Error Reporting

您可以使用下方其中一種方式,從 EC2 應用程式傳送錯誤至 Error Reporting:

使用 Logging 回報錯誤

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

例如:

  1. 將 Amazon Web Services (AWS) 系統連線至 Google Cloud。詳情請參閱「在個別 VM 中安裝 Logging 代理程式」。
  2. 根據環境安裝適當的記錄 google-fluentd 代理程式。如需操作說明,請參閱「安裝記錄代理程式」。
  3. 修改應用程式,讓應用程式將例外狀況和其堆疊追蹤記錄到 Logging。

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

  4. 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.

      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 程式碼 (請使用實際的專案 ID 取代 your-project-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」頁面:

    前往「錯誤回報

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