用PHP自带的webserver调试程序

背景

最近研究cloudwatch实现邮件告警,流程是 cloudwatch --> sns --> email,但是存在一个问题,邮件只在告警被触发的时候发一次,于是想到给现有的监控系统加一个回调,让sns通过post把告警内容发到监控系统,由监控系统来告警,回头一看监控系统是php写的,那就接着用php往上补吧。

PHP内置webserver

测试个小功能,php内置的webserver已经可以满足要求了,省去了安装nginx或apache的步骤

编写index.php文件

public function sns(){
    try{
        $data = json_decode(file_get_contents('php://input'), true);
    }catch (Exception $e){
        $res['retCode'] = 255;
        $res['message'] = $e->getMessage();
        echo json_encode($res);
        exit();
    }
    # The first time to configure sns http url, confirm the subscription is needed.
    if (array_key_exists('Type',$data) && $data['Type'] == 'SubscriptionConfirmation'){
        $content = file_get_contents($data["SubscribeURL"]);
        exit();
    }
    $alarm = array();
    $alarm['space_uuid'] = 'uuid';
    $alarm['token'] = 'token';
    $alarm['category'] = 'category';
    $alarm['checktime'] = time();
    # Cloudwatch has no severity settings, so set it to critical default, if event recovery, set status 0.
    if ($data['NewStateValue'] == 'OK'){
        $alarm['status'] = '0';
    }else{
        $alarm['status'] = '2';
    }
    $alarm['service'] = $data['Trigger']['MetricName'];
    $account = $data['AWSAccountId'];
    $region = split(':',$data['AlarmArn'])[3];
    $namespace = $data['Trigger']['Namespace'];
    $NewStateReason = $data['NewStateReason'];
    $Dimensions = '';
    foreach ($data["Trigger"]["Dimensions"] as $v) {
        $dimension = implode('-',$v);
        $Dimensions = $Dimensions . ' ' . $dimension;
    }

    $alarm['tags'] = sprintf("%s_%s_%s", $account, $region, $namespace);
    $alarm['message'] = sprintf("AlertReason:%s. Info:%s", $NewStateReason, $Dimensions);

    try{
        $ret = $this->postData($this->dutyApi, $alarm);
        $ret = json_decode($ret, true);
        $status = $ret['status'];
        $message = $ret['message'];
    }catch (Exception $e){
        $res['retCode'] = 255;
        $res['message'] = $e->getMessage();
        echo json_encode($res);
        exit();
    }

    if($status == 1){
        $res['retCode'] = 0;
        $res['message'] = $message;
    }else{
        $res['retCode'] = 255;
        $res['message'] = $message;
    }
    echo json_encode($res);
}

启动服务

[root@alex stoneguo1993]# php -S 0.0.0.0:80
PHP 5.4.16 Development Server started at Thu Sep 24 10:32:10 2020
Listening on http://0.0.0.0:80
Document root is /home/stoneguo1993
Press Ctrl-C to quit.

post数据并测试结果

curl -X POST http://34.96.xx.xx -d '{"AlarmName":"awsec2-i-0934fxxxxxx-GreaterThanOrEqualToThreshold-CPUUtilization","AlarmDescription":"Created from EC2 Console","AWSAccountId":"13143xxxxxx","NewStateValue":"ALARM","NewStateReason":"Threshold Crossed: 1 out of the last 1 datapoints [7.48624681823933 (23/09/20 09:02:00)] was greater than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition).","StateChangeTime":"2020-09-23T09:07:54.973+0000","Region":"US West (Oregon)","AlarmArn":"arn:aws:cloudwatch:us-west-2:1314xxxxxx:alarm:awsec2-i-0934faxxxxxx-GreaterThanOrEqualToThreshold-CPUUtilization","OldStateValue":"OK","Trigger":{"MetricName":"CPUUtilization","Namespace":"AWS/EC2","StatisticType":"Statistic","Statistic":"AVERAGE","Unit":null,"Dimensions":[{"value":"i-0934fa2xxx","name":"InstanceId"}, {"value":"prod","name":"env"}],"Period":300,"EvaluationPeriods":1,"ComparisonOperator":"GreaterThanOrEqualToThreshold","Threshold":1.0,"TreatMissingData":"","EvaluateLowSampleCountPercentile":""}}'

返回值符合预期

Array
(
    [space_uuid] => this is uid
    [token] => this is token
    [category] => this is category
    [checktime] => 1600943640
    [status] => 2
    [service] => CPUUtilization
    [tags] => 1314xxxxx_us-west-2_AWS/EC2
    [message] => AlertReason:Threshold Crossed: 1 out of the last 1 datapoints [7.48624681823933 (23/09/20 09:02:00)] was greater than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition).. Info: i-0934faxxxxxx-InstanceId prod-env
)

拓展

用python获取sns发过来的数据

import json
from flask import Flask
from flask import request
app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def parse_request():
    data = json.loads(request.data)
    print(data)
    return data
posted @ 2020-09-24 18:43  AlexGuoMe  阅读(224)  评论(0编辑  收藏  举报