expected google.protobuf.Duration got str

I’m trying to create an alert with Cloud Functions. I have the following test alert json directly inserted into my code:

alert_policy = {"conditions":[{"condition_absent":{"duration":900s,"filter":"metric.label.state="blocked" AND metric.type="agent.googleapis.com/processes/count_by_state"  AND resource.type="gce_instance""},"displayName":"Test_two"}],"displayName":"test","combiner":"OR"}

I’m not able to make my function work because of the duration value. I’ve tried to pass as a string, an interger, a string with s and I always have an error:

TypeError: Parameter to MergeFrom() must be instance of same class: expected google.protobuf.Duration got str. or TypeError: Parameter to MergeFrom() must be instance of same class: expected google.protobuf.Duration got int.

How should I pass this value?

Answer

See: MetricAbsence

It needs to be a string "900s" (probably).

Google’s (increasingly?) exposing underlying Protobuf types in its APIs and these can be confusing to grok. In this case, the underlying type Duration, is one of Google’s so-called Well-Known Types. Ironically named because they’re often not that well-known 😉

Google’s APIs Explorer is an excellent tool for this type of diagnosis. It is exhaustive and current:

Example

In this case, I start with a Python dictionary, json.dumps to convert it to a string and then from_json it to create a monitoring_v3.AlertPolicy that’s needed by create_alert_policy

import json
import os

from google.cloud import monitoring_v3


PROJECT = os.environ["PROJECT"]

client = monitoring_v3.AlertPolicyServiceClient()

name = "projects/{project}".format(project=PROJECT)

filter = "..."

j = {
    "displayName": "test",
    "conditions": [{
        "displayName": "test",
        "condition_absent": {
            "filter": filter,
            "duration": "900s",
        },
    }],
    "combiner": "OR"
}

policy = monitoring_v3.AlertPolicy.from_json(json.dumps(j))

resp = client.create_alert_policy(name=name,alert_policy=policy)

print(resp)

Then:

gcloud alpha monitoring policies list 
--project=${PROJECT} 
--format="value(displayName)"

test