【问题标题】:POST custom metric with curl to cloudwatch使用 curl 将自定义指标发布到 cloudwatch
【发布时间】:2019-03-25 12:35:20
【问题描述】:

我想记录对云手表的 api 调用结果。 我想要做的是将消费指标发布到云手表。 我的架构设计为坐在弹性豆茎上,所以我更喜欢在上面安装尽可能少的东西。

我想了解是否可以使用简单的 CURL POST 发布云手表。

我有这个tutorial

我不太明白这个例子。 我可以邮寄吗? (看起来像 get 方法)。 端点是什么?

当我尝试时: curl -X POST https://monitoring.&api-domain;/doc/2010-08-01/?Action=PutMetricData&Version=2010-08-01&Namespace=TestNamespace&MetricData.member.1.MetricName=buffers&MetricData.member.1.Unit=Bytes&&MetricData.member.1.Dimensions.member.1.Name=InstanceType&MetricData.member.1.Dimensions.member.1.Value=m1.small&AUTHPARAMS

我收到了这个错误: 'api-domain' is not recognized as an internal or external command, operable program or batch file. 'Version' is not recognized as an internal or external command, operable program or batch file. 'Namespace' is not recognized as an internal or external command, operable program or batch file. 'MetricData.member.1.MetricName' is not recognized as an internal or external command, operable program or batch file. 'MetricData.member.1.Unit' is not recognized as an internal or external command, operable program or batch file. 'MetricData.member.1.Dimensions.member.1.Value' is not recognized as an internal or external command, operable program or batch file. 'AUTHPARAMS' is not recognized as an internal or external command, operable program or batch file.

请不要告诉我使用 aws cli。 我知道我可以使用它。我想尽量不用。

【问题讨论】:

    标签: amazon-web-services curl metrics amazon-cloudwatch


    【解决方案1】:

    这里是解释如何发出 POST 请求的文档:https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/making-api-requests.html#CloudWatch-API-requests-using-post-method

    这里是每个区域的端点列表:https://docs.aws.amazon.com/general/latest/gr/rande.html#cw_region

    产生的卷曲看起来像这样:

    curl -X POST \
      https://monitoring.us-east-1.amazonaws.com \
      -H 'Accept: application/json' \
      -H 'Authorization: AWS4-HMAC-SHA256 Credential=YOUR_ACCESS_KEY_GOES_HERE/20190326/us-east-1/monitoring/aws4_request, SignedHeaders=accept;content-encoding;content-length;content-type;host;x-amz-date;x-amz-target, Signature=SIGV4_SIGNATURE_GOES_HERE' \
      -H 'Content-Encoding: amz-1.0' \
      -H 'Content-Length: 141' \
      -H 'Content-Type: application/json' \
      -H 'X-Amz-Date: 20190326T071934Z' \
      -H 'X-Amz-Target: GraniteServiceVersion20100801.PutMetricData' \
      -H 'host: monitoring.us-east-1.amazonaws.com' \
      -d '{
        "Namespace": "StackOverflow",
        "MetricData": [
            {
                "MetricName": "TestMetric",
                "Value": 123.0
            }
        ]
    }'
    

    请注意,上例中的 Authorization 标头有两个占位符,YOUR_ACCESS_KEY_GOES_HERESIGV4_SIGNATURE_GOES_HERE。这些是您将用于对请求进行签名的凭据中的访问密钥,以及您必须使用此算法构建的签名:https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html,这是推荐使用 CLI 或 SDK 的原因之一提出请求。

    【讨论】:

      【解决方案2】:

      这是一个只需要 curl 和 openssl 的纯 bash 示例。它的灵感来自:https://github.com/riboseinc/aws-authenticating-secgroup-scripts

      #!/bin/bash
      
      set -o errexit
      set -o pipefail
      set -o nounset
      
      function sha256Hash() {
        printf "$1" | openssl dgst -sha256 -binary -hex | sed 's/^.* //'
      }
      
      function log() {
        local message="$1"
        local details="$2"
      
        printf "${message}\n" >&2
        printf "${details}\n\n" | sed 's/^/    /' >&2
      }
      
      function to_hex() {
        printf "$1" | od -A n -t x1 | tr -d [:space:]
      }
      
      function hmac_sha256() {
        printf "$2" | \
          openssl dgst -binary -hex -sha256 -mac HMAC -macopt hexkey:"$1" | \
          sed 's/^.* //'
      }
      
      ## http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
      function sig4_create_canonical_request() {
        local http_request_method="$1"
        local canonical_uri="/${api_uri}"
        local canonical_query=""
        local header_host="host:${api_host}"
        local canonical_headers="${header_host}\n${header_x_amz_date}"
        local request_payload=$(sha256Hash "$metricjson")
        local canonical_request="${http_request_method}\n${canonical_uri}\n${canonical_query}\n${canonical_headers}\n\n${signed_headers}\n${request_payload}"
      
        printf "$(sha256Hash ${canonical_request})"
      }
      
      ## http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
      function sigv4_create_string_to_sign() {
        local hashed_canonical_request="$1"
        local sts="${algorithm}\n${timestamp}\n${credential_scope}\n${hashed_canonical_request}"
      
        printf "${sts}"
      }
      
      ## http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
      function sigv4_calculate_signature() {
        local secret=$(to_hex "AWS4${aws_secret_key}")
        local k_date=$(hmac_sha256 "${secret}" "${today}")
        local k_region=$(hmac_sha256 "${k_date}" "${aws_region}")
        local k_service=$(hmac_sha256 "${k_region}" "${aws_service}")
        local k_signing=$(hmac_sha256 "${k_service}" "aws4_request")
        local string_to_sign="$1"
        local signature=$(hmac_sha256 "${k_signing}" "${string_to_sign}" | sed 's/^.* //')
      
        printf "${signature}"
      }
      
      ## http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html#sigv4-add-signature-auth-header
      function sigv4_add_signature_to_request() {
        local credential="Credential=${aws_access_key}/${credential_scope}"
        local s_headers="SignedHeaders=${signed_headers}"
        local signature="Signature=$1"
        local authorization_header="Authorization: ${algorithm} ${credential}, ${s_headers}, ${signature}"
      
        printf "${authorization_header}"
      }
      
      # https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
      function sign_it() {
        local method="$1"
        local hashed_canonical_request=$(sig4_create_canonical_request "${method}")
        local string_to_sign=$(sigv4_create_string_to_sign "${hashed_canonical_request}")
        local signature=$(sigv4_calculate_signature "${string_to_sign}")
        local authorization_header=$(sigv4_add_signature_to_request "${signature}")
      
        printf "${authorization_header}"
      }
      
      ## https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/making-api-requests.html#CloudWatch-API-requests-using-post-method
      function put_metric_data() {
        local http_method="$1"
        local authorization_header=$(sign_it "${http_method}")
        local content_length=$(echo -n "$metricjson"|wc -m)
      
        printf "> ${http_method}-ing ${api_url}\n"
      
        curl -i -X ${http_method} "${api_url}" \
          -H 'Accept: application/json' \
          -H 'Content-Encoding: amz-1.0' \
          -H 'Content-Type: application/json' \
          -H 'X-Amz-Target: GraniteServiceVersion20100801.PutMetricData' \
          -H "${authorization_header}" \
          -H "${header_x_amz_date}" \
          -H "Content-Length: ${content_length}" \
          -d "$metricjson"
      }
      
      function main() {
        while [ -n "${1-}" ]; do
          case "$1" in
            -credentials) credentials="$2"; shift ;;
            -url)         url="$2";         shift ;;
            -metricjson)  metricjson="$2";  shift ;;
            *)            echo "Option $1 not recognized"; exit 1 ;;
          esac
          shift
        done
      
        if [ -z "${credentials}" ] || [ -z "${url}" ] || [ -z "${metricjson}" ] ; then
          log "sample usage:" "<script> -metricjson <metricjson> -credentials <aws_access_key>:<aws_secret_key> -url <c_url>"
          exit 1
        fi
      
        local method="POST"
        local aws_access_key=$(cut -d':' -f1 <<<"${credentials}")
        local aws_secret_key=$(cut -d':' -f2 <<<"${credentials}")
        local api_url="${url}"
        local timestamp=${timestamp-$(date -u +"%Y%m%dT%H%M%SZ")} # 20171226T112335Z
        local today=${today-$(date -u +"%Y%m%d")}                 # 20171226
        local api_host=$(printf ${api_url} | awk -F/ '{print $3}')
        local api_uri=$(printf ${api_url} | grep / | cut -d/ -f4-)
        local aws_region=$(cut -d'.' -f2 <<<"${api_host}")
        local aws_service=$(cut -d'.' -f1 <<<"${api_host}")
        local algorithm="AWS4-HMAC-SHA256"
        local credential_scope="${today}/${aws_region}/${aws_service}/aws4_request"
        local signed_headers="host;x-amz-date"
        local header_x_amz_date="x-amz-date:${timestamp}"
      
        put_metric_data "${method}"
      }
      
      main "$@"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-17
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        • 2023-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多