google-cloud-python
google-cloud-python copied to clipboard
Add support for `monitoring.regex.full_match` in the `google-cloud-monitoring`
The google-cloud-monitoring does not support monitoring.regex.full_match.
See https://github.com/googleapis/google-cloud-python/blob/main/packages/google-cloud-monitoring/google/cloud/monitoring_v3/query.py#L622-L637
I need to have a way to pass key=value without escaping to fully use the functionality, e.g. the monitoring.regex.full_match. Now, when I call e.g.
client = monitoring_v3.MetricServiceClient()
project_id = '...'
end_time = datetime.fromisoformat("...")
query = (Query(client, project_id,
metric_type='cloudfunctions.googleapis.com/function/execution_count', end_time=end_time,
days=30,
).select_resources(
function_name="""monitoring.regex.full_match(".*-something-.*")""",
region="europe-west1")
query.to_dataframe()
I get an error, because the filter built from the params is like this:
'metric.type = "cloudfunctions.googleapis.com/function/execution_count" AND resource.label.function_name = "monitoring.regex.full_match(".*-something-.*")" AND resource.label.region = "europe-west1"'
but I need
'metric.type = "cloudfunctions.googleapis.com/function/execution_count" AND resource.label.function_name = monitoring.regex.full_match(".*-something-.*") AND resource.label.region = "europe-west1"'
Here is my fix for that, but I failed to make the tests run on Windows:
from google.cloud import monitoring_v3
from datetime import datetime, timedelta
from google.cloud.monitoring_v3.query import Query
from google.cloud.monitoring_v3.types import Aggregation
from google.cloud.monitoring_v3 import query
import pandas as pd
# I could make a PR, but running the tests there is pain
def fixed_build_label_filter(category, *args, **kwargs):
"""Construct a filter string to filter on metric or resource labels."""
terms = list(args)
for key, value in kwargs.items():
if value is None:
continue
suffix = None
if key.endswith(
(
"_prefix",
"_suffix",
"_greater",
"_greaterequal",
"_less",
"_lessequal",
"_notequal",
"_regex",
)
):
key, suffix = key.rsplit("_", 1)
if category == "resource" and key == "resource_type":
key = "resource.type"
else:
key = ".".join((category, "label", key))
if suffix == "prefix":
term = '{key} = starts_with("{value}")'
elif suffix == "suffix":
term = '{key} = ends_with("{value}")'
elif suffix == "greater":
term = "{key} > {value}"
elif suffix == "greaterequal":
term = "{key} >= {value}"
elif suffix == "less":
term = "{key} < {value}"
elif suffix == "lessequal":
term = "{key} <= {value}"
elif suffix == "notequal":
term = "{key} != {value}"
elif suffix == "regex":
term = '{key} = monitoring.regex.full_match("{value}")'
else:
term = '{key} = "{value}"'
terms.append(term.format(key=key, value=value))
return " AND ".join(sorted(terms))
query._build_label_filter = fixed_build_label_filter