칸시를 멈추지 마라! 【GCP】Stackdriver Logging 및 Cloud Functions에서 hostError를 자동 게시

그레인지 Advent Calendar 2018 7일째 담당 s.1na9ak1입니다.

개요



개요가 길기 때문에 3줄로



개요가 길어져 버렸으므로, 정리했습니다.
  • 가끔 호스트 오류가 발생함
  • 설문 조사가 억명
  • 자동 게시

  • 이하, 개요가 길기 때문에, 내용까지 읽어 날려도 괜찮습니다.

    인스턴스가 다시 시작! 원인은 무엇입니까?



    우리 서비스 "포콜론 던전"를 GCP로 이전 한 초기에는 인스턴스를 재부팅하는 것이 매우 드뭅니다.

    호스트 오류는 무엇입니까?



    Google Compute Engine FAQ에 설명되어 있습니다.
    가상 시스템에서 호스트 오류가 발생하여 다시 시작되었습니다. 무슨 일이야?

    호스트 오류는 가상 시스템을 호스팅하는 물리적 시스템에서 가상 시스템이 충돌하는 하드웨어 또는 소프트웨어 문제가 발생했음을 의미합니다. Compute Engine에서 이러한 이벤트를 감지하면 작업 로그에 compute.instances.hostError라는 항목이 추가됩니다. 가상 머신이 자동으로 재부팅되도록 설정된 경우(기본 설정), 다른 물리적 머신에서 가상 머신이 재시작됩니다.

    호스트 오류가 발생했습니까?



    호스트 오류를 ​​조사하는 경우,
  • gcloud command
  • gcloud compute operations list --filter "hostError" --project [プロジェクト名]
  • Stackdriver Logging
  • compute.instances.hostError 항목에서 검색

    두 가지가있었습니다.

    자동 게시



    상기의 조사 방법의 경우, 과거(1개월 정도는 참조할 수 있다)에 거슬러 조사를 실시할 수 없다고 하는 것과,
    무엇보다 가끔 일어날 때 조사하는 번거로움이 듭니다.
    따라서 호스트 오류가 발생하면 ChatworkDatadog에 자동 게시합니다.

    내용



    놀랍게도 호스트 오류 항목이 Stackdriver Logging에 출력됩니다! 그러면 내보내고 Cloud Functions에서 자동 게시할 수 있습니다! 라는 내용입니다.

    Stackdriver Logging 내보내기 생성



    Google Cloud Platfrom 콘솔에서
    Logging > 내보내기 > 내보내기 만들기로 이동합니다.
  • 필터 설정
  • jsonPayload.event_subtype에서 compute.instances.automaticRestart 또는 compute.instances.hostError 필터를 설정합니다.

    hostError의 경우 compute.instances.hostError자동 재부팅의 경우 compute.instances.automaticRestart
    다음 필터를 설정합니다.
    resource.type="gce_instance"
    jsonPayload.event_subtype=("compute.instances.automaticRestart" OR "compute.instances.hostError")
    
  • 싱크 서비스 설정

  • 내보내기 대상으로 Cloud Pub/Sub를 설정합니다.
  • 싱크 내보내기 대상 만들기

  • 새 Cloud Pub/Sub 주제를 만듭니다.



    Cloud Functions 만들기



    Chatwork 게시물과 Datadog에 메트릭을 보냅니다.
    다음 코드를 준비합니다. Node.js로 작성하고 있습니다.

    Chatwork 투고는, Chatwork API .
    Datadog의 메트릭 전송에 dogapi을 사용합니다.

    index.js
    var async = require('async');
    var dogapi = require('dogapi');
    var postChatworkMessage = require('post-chatwork-message');
    var _ = require('underscore');
    var dateformat = require('dateformat');
    var moment = require('moment-timezone');
    
    // https://app.datadoghq.com/account/settings#api
    var options = {
        api_key: '*****************************',
    };
    
    dogapi.initialize(options);
    
    // ID:******************@grenge.co.jp
    const CHATWORK_API_KEY = '*****************************';
    // chat work room id
    const RID = '*********';
    
    const POST_TITLE_PREFIX = '[GCE_OPERATION]';
    
    /**
     * Background Cloud Function to be triggered by Pub/Sub. 
     *
     * @param {object} event The Cloud Functions event.
     * @param {function} callback The callback function.
     */
    exports.triggerTopicComputeOperationsHostError = (event, callback) => {
        var pubsubMessage = event.data;
        var data = pubsubMessage.data ? Buffer.from(pubsubMessage.data, 'base64').toString() : null;
    
        if (!data) {
            console.log('ERROR: data is null.')
            callback();
            return;
        }
    
        var obj = JSON.parse(data);
        var chatwork_post_message = '[info][title]' + POST_TITLE_PREFIX + ' ' + obj.jsonPayload.event_subtype + '[/title]';
        chatwork_post_message += moment(Number(obj.jsonPayload.event_timestamp_us/1000)).tz("Asia/Tokyo").format("YYYY-MM-DD HH:mm:ssZ") + ' ' + obj.resource.labels.project_id + ' ' + obj.resource.labels.zone + ' ' + obj.jsonPayload.resource.name;
        chatwork_post_message += '[/info]';
        chatwork_post_message += 'https://console.cloud.google.com/logs/viewer?project=' + obj.resource.labels.project_id + '&resource=gce_instance%2Finstance_id%2F' + obj.resource.labels.instance_id;
    
        // post
        postChatworkMessage(CHATWORK_API_KEY, RID, chatwork_post_message);
    
        // Datadog post event
        dogapi.event.create(POST_TITLE_PREFIX, data, {
            host: obj.jsonPayload.resource.name,
            alert_type: 'error',
            tags: ['project:' + obj.resource.labels.project_id, 'event_subtype:' + obj.jsonPayload.event_subtype, 'env:' + obj.resource.labels.project_id.replace('popolo-', '')]
        }, callback);
    };
    

    Cloud Functions 배포



    gcloud functions deploy 명령으로 배포를 수행합니다.

    다음은 배치 명령입니다.
    특히 중요한 점은 두 가지입니다.
  • --trigger-resource

  • Stackdriver Logging에서 작성한 내보내기 대상 주제를 지정합니다.
  • --trigger-event

  • Cloud Pub/Sub를 사용하므로 google.pubsub.topic.publish를 지정합니다.
    gcloud beta functions deploy triggerTopicComputeOperationsHostError --trigger-resource topic-compute_operations_host_error --trigger-event google.pubsub.topic.publish --project [プロジェクト名]
    

    배포가 완료되고 호스트 오류의 자동 게시가 완료되었습니다.

    이런 느낌입니다.


  • Chatwork
  • Datadog

  • 마지막으로



    이를 구현한 후 호스트 오류가 크게 줄어들었습니다. (하지만 가끔 자동 게시되므로 개인적으로 편리합니다.)
    거기 있군요.
    카메라 칸시도 멈추지 않고 노력하자!

    고마워요.

    좋은 웹페이지 즐겨찾기