Skip to content

Web Metrics

An HTTP request can be performed against some external service to obtain the measurement. This example makes an HTTP GET request to some URL. The webhook response is typically JSON, but plain-text responses are also supported (see Plain text responses below). When the response body is valid JSON, the result of the optional jsonPath expression will be assigned to the result variable that can be referenced in the successCondition and failureCondition expressions. If jsonPath is omitted, the entire response body is used as the result variable.

  metrics:
  - name: webmetric
    successCondition: result == true
    provider:
      web:
        url: "http://my-server.com/api/v1/measurement?service={{ args.service-name }}"
        timeoutSeconds: 20 # defaults to 10 seconds
        headers:
          - key: Authorization
            value: "Bearer {{ args.api-token }}"
        jsonPath: "{$.data.ok}"

In the following example, given the payload, the measurement will be Successful if the data.ok field was true, and the data.successPercent was greater than 0.90

{
  "data": {
    "ok": true,
    "successPercent": 0.95
  }
}
  metrics:
  - name: webmetric
    successCondition: "result.ok && result.successPercent >= 0.90"
    provider:
      web:
        url: "http://my-server.com/api/v1/measurement?service={{ args.service-name }}"
        headers:
          - key: Authorization
            value: "Bearer {{ args.api-token }}"
        jsonPath: "{$.data}"

NOTE: if the result is a string, two convenience functions asInt and asFloat are provided to convert a result value to a numeric type so that mathematical comparison operators can be used (e.g. >, <, >=, <=).

Plain text responses

If the webhook returns a plain-text body (not JSON), omit jsonPath. The raw response body string is assigned to result and successCondition / failureCondition are evaluated against it.

For example, if the webhook returns the plain-text body I am OK, the following AnalysisTemplate marks the measurement as Successful:

  metrics:
  - name: health-check
    successCondition: result == "I am OK"
    provider:
      web:
        url: "http://my-server.com/health"

Similarly, an empty response body assigns an empty string to result, so conditions such as result == "" are evaluated accordingly.

Optional web methods

It is possible to use a POST or PUT requests, by specifying the method and either body or jsonBody fields

  metrics:
  - name: webmetric
    successCondition: result == true
    provider:
      web:
        method: POST # valid values are GET|POST|PUT, defaults to GET
        url: "http://my-server.com/api/v1/measurement?service={{ args.service-name }}"
        timeoutSeconds: 20 # defaults to 10 seconds
        headers:
          - key: Authorization
            value: "Bearer {{ args.api-token }}"
          - key: Content-Type # if body is a json, it is recommended to set the Content-Type
            value: "application/json"
        body: "string value"
        jsonPath: "{$.data.ok}"
!!! tip In order to send in JSON, you can use jsonBody and Content-Type will be automatically set as json. Setting a body or jsonBody field for a GET request will result in an error. Set either body or jsonBody and setting both will result in an error.

  metrics:
  - name: webmetric
    successCondition: result == true
    provider:
      web:
        method: POST # valid values are GET|POST|PUT, defaults to GET
        url: "http://my-server.com/api/v1/measurement?service={{ args.service-name }}"
        timeoutSeconds: 20 # defaults to 10 seconds
        headers:
          - key: Authorization
            value: "Bearer {{ args.api-token }}"
          - key: Content-Type # if body is a json, it is recommended to set the Content-Type
            value: "application/json"
        jsonBody: # If using jsonBody Content-Type header will be automatically set to json
          key1: value_1
          key2:
            nestedObj: nested value
            key3: "{{ args.service-name }}"
        jsonPath: "{$.data.ok}"

Skip TLS verification

You can skip the TLS verification of the web host provided by setting the options insecure: true.

  metrics:
  - name: webmetric
    successCondition: "result.ok && result.successPercent >= 0.90"
    provider:
      web:
        url: "https://my-server.com/api/v1/measurement?service={{ args.service-name }}"
        insecure: true
        headers:
          - key: Authorization
            value: "Bearer {{ args.api-token }}"
        jsonPath: "{$.data}"

Authorization

With OAuth2

You can setup an OAuth2 client credential flow using the following values:

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
  - name: service-name
  # from secret
  - name: oauthSecret  # This is the OAuth2 shared secret
    valueFrom:
      secretKeyRef:
        name: oauth-secret
        key: secret
  metrics:
  - name: webmetric
    successCondition: result == true
    provider:
      web:
        url: "http://my-server.com/api/v1/measurement?service={{ args.service-name }}"
        timeoutSeconds: 20 # defaults to 10 seconds
        authentication:
          oauth2:
            tokenUrl: https://my-oauth2-provider/token
            clientId: my-client-id
            clientSecret: "{{ args.oauthSecret }}"
            scopes: [
              "my-oauth2-scope"
            ]
        headers:
          - key: Content-Type # if body is a json, it is recommended to set the Content-Type
            value: "application/json"
        jsonPath: "{$.data.ok}"

In that case, no need to provide specifically the Authentication header. The AnalysisRun will first get an access token using that information, and provide it as an Authorization: Bearer header for the metric provider call.