ユースケース

例外はサービス実行中に発生する可能性があります。 一部の例外は再試行などの方法で自動的に復元されますが、復元されない例外もあります。 重大な例外は、顧客の業務を中断することさえあります。 したがって、これらの例外を記録し、特定の条件が満たされたときにアラームをトリガーするシステムが必要です。 従来の方法では、ファイルログを印刷し、特定のシステム、たとえばオープンソースのELK (ElasticSearch、Logstash、Kibana) にログを収集します。これらのオープンソースシステムは、複数の複雑な分散システムから構成されます。 複雑な技術と高いコストのために、独自でメンテナンスするのが難しくなっています。CloudMonitor はイベントモニタリング機能を提供し、これらの問題を効果的に解決します。

次の例で、イベントモニタリング機能の使用方法について説明します。

ケーススタディ

  1. 例外のレポート

    イベントモニタリングは、データレポートのための 2 つの方法、Java SDK と Open API を提供します。 以下は、Java SDK を使用してデータをレポートする方法について説明します。

    1. Maven に依存関係を追加する
      <dependency>
          <groupId>com.aliyun.openservices</groupId>
          <artifactId>aliyun-cms</artifactId>
          <version>0.1.2</version>
      </dependency>
    2. SDK の初期化
      // Here, 118 is the application grouping ID of CloudMonitor. Events can be categorized by applications. You can view group IDs in CloudMonitor application grouping list.
      CMSClientInit.groupId = 118L;
      // The address is the reporting entry of the event system, which is currently the public network address.  AccessKey と Secret / key は個人の身元確認に使用されます。
      CMSClient c = new CMSClient("https://metrichub-cms-cn-hangzhou.aliyuncs.com", accesskey, secretkey);
    3. データを非同期にレポートするかどうかを決定します。

      CloudMonitor イベントモニタリングでは、デフォルトで同期レポートポリシーが提供されます。 長所は、簡単にコードが書け、レポートされたイベントは信頼性があり、データが失われないことです。

      しかし、そのようなポリシーにはいくつか問題もあります。 イベントレポートコードはビジネスコードに埋め込まれており、ネットワークの変動が発生した場合にコードの実行が妨げられ、通常のビジネスに影響を与える可能性があります。 多くのビジネスシナリオでは、100% 信頼できるイベントを必要としないため、単純な非同期レポートのカプセル化で十分です。 イベントを LinkedBlockingQueue に書き込み、ScheduledExecutorService を使用してバックエンドで非同期にバッチレポートを実行します。

      //Initialize queue and Executors:
      private LinkedBlockingQueue<EventEntry> eventQueue = new LinkedBlockingQueue<EventEntry>(10000);
      private ScheduledExecutorService schedule = Executors.newSingleThreadScheduledExecutor();
      // Report event:
      //Every event contains its name and content. The name is for identification and the content contains details of the event, in which the full-text search is supported.
      public void put(String name, String content) {
          EventEntry event = new EventEntry(name, content);
           // When the event queue is full, additional events are discarded directly. You can adjust this policy as needed.
          boolean b = eventQueue.offer(event);
          if (! b) {
              logger.warn("The event queue is full, discard: {}", event);
          }
      
      //Submit events asynchronously. Initialize scheduled tasks. Report events in batch by run every second.  You can adjust the reporting interval as needed.
      schedule.scheduleAtFixedRate(this, 1, 1, TimeUnit.SECONDS);
      public void run() {
          do {
              batchPut();
          } while (this.eventQueue.size() > 500);
      
      private void batchPut() {
          // Extract 99 events from the queue for batch reporting.
          List<CustomEvent> events = new ArrayList<CustomEvent>();
          for (int i = 0; i < 99; i++) {
              EventEntry e = this.eventQueue.poll();
              if (e == null) {
                  break;
              
              events.add(CustomEvent.builder().setContent(e.getContent()).setName(e.getName()).build());
          
          if (events.isEmpty()) {
              return;
          
           // Report events in batch to CloudMonitor. No retry or retry in SDK is added here. If you have high requirement for event reliability, add retry policies.
          try {
              CustomEventUploadRequestBuilder builder = CustomEventUploadRequest.builder();
              builder.setEventList(events);
              CustomEventUploadResponse response = cmsClient.putCustomEvent(builder.build());
              if (!" 200".equals(response.getErrorCode())) {
                  logger.warn("event reporting error: msg: {}, rid: {}", response.getErrorMsg(), response.getRequestId());
              
          } catch (Exception e1) {
               logger.error("event reporting exception", e1);
          
      
    4. イベントレポートのデモ
      • デモ 1: http コントローラーの例外モニタリング

        主な目的は、HTTP リクエストに多数の例外が存在するかどうかをモニターすることです。 1 分あたりの例外数が一定の限度を超えると、アラームがトリガーされます。 実装の原則は、Spring インターセプター、サーブレットフィルタ、その他のテクノロジを使用して HTTP リクエストをインターセプトすることです。 例外が発生した場合はログが作成され、アラームルールを設定することでアラームがトリガーされます。

        以下は、イベントレポートのデモです。
        // Each event should be informative for searching and locating. Here, map is used for organizing events and converted to Json format as event content.  
        Map<String, String> eventContent = new HashMap<String, String>();
        eventContent.put("method", "GET"); // http request method
        eventContent.put("path", "/users"); // http path
        eventContent.put("exception", e.getClass().getName()); //Exception class name for searching
        eventContent.put("error", e.getMessage()); // Error message of exception
        eventContent.put("stack_trace", ExceptionUtils.getStackTrace(e)); // Exception stack for locating
        // Finally submit the events in the preceding asynchronous reporting method. Since no retry is performed in asynchronous reporting, event loss of small probability may happen. However, it is sufficient for alarms of unknown http exceptions.
        put("http_error", JsonUtils.toJson(eventContent));
        image.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/864cf095977cf61bd340dd1461a0247c.png)
      • デモ 2: バックエンドでスケジュールされたタスクのモニタリングとメッセージ処理

        前述の http イベントと同様に、多くの同様のビジネスシナリオではアラームが必要です。 バックエンドタスクやメッセージキュー処理などのビジネスシナリオでは、同様の方法でイベントがレポートされ、効果的なモニタリングが実現できます。 例外が発生したときは、直ちにアラームがトリガーされます。

        //Event organization of the message queue:
        Map<String, String> eventContent = new HashMap<String, String>();
        eventContent.put("cid", consumerId); // Consumer ID
        eventContent.put("mid", msg.getMsgId()); // Message ID
        eventContent.put("topic", msg.getTopic()); // Message topic
        eventContent.put("body", body); // Message body
        eventContent.put("reconsume_times", String.valueOf(msg.getReconsumeTimes())); // The number of retries after message failure
        eventContent.put("exception", e.getClass().getName()); //Exception class name in case of exception
        eventContent.put("error", e.getMessage()); // Exception message
        eventContent.put("stack_trace", ExceptionUtils.getStackTrace(e)); // Exception stack
        // Finally, report the event
        put("metaq_error", JsonUtils.toJson(eventContent));

        レポート後、イベントを確認します。

      • キューメッセージ処理例外のアラームを設定します。

      • デモ 3: 重要なイベントを記録する

        イベントのもう1つのユースケースは、アラームを送信せずに後で確認するための重要なアクションを記録することです。 たとえば、重要な業務、パスワードの変更、注文の変更、リモートログインなどの操作ログなどです。