IBM / apiconnect-trawler

API Connect metrics exporter
MIT License
5 stars 10 forks source link

Add datapower gateway peering status #21

Closed perryan-coder closed 2 years ago

perryan-coder commented 3 years ago

Gather the gateway peering status data so that it can be viewed, specifically the Primary node for a peer group.

The CLI command is show gateway-peering-status and the equivalent REST call is /mgmt/status/{domain}/GatewayPeeringStatus

The returned JSON format is

{
    "_links": {
      "self": {
        "href": "/mgmt/status/apiconnect/GatewayPeeringStatus"
      },
      "doc": {
        "href": "/mgmt/docs/status/GatewayPeeringStatus"
      }
    },
    "GatewayPeeringStatus": [
      {
        "Address": "IP Node 1",
        "Name": "gwd",
        "PendingUpdates": 0,
        "ReplicationOffset": 5881225785,
        "LinkStatus": "ok",
        "Primary": "no"
      },
      ....
      {
        "Address": "IP Node 2",
        "Name": "gwd",
        "PendingUpdates": 0,
        "ReplicationOffset": 5881225785,
        "LinkStatus": "ok",
        "Primary": "no"
      },
      ....
      {
        "Address": "IP Node 3",
        "Name": "gwd",
        "PendingUpdates": 0,
        "ReplicationOffset": 5881225785,
        "LinkStatus": "ok",
        "Primary": "yes"
      },
      ...
    ]
}

The output format needs to be determined, probably with a naming standard like https://prometheus.io/docs/practices/naming/

rickymoorhouse commented 3 years ago

Maybe something like

datapower_gateway_peering_primary_info{peer_group="gwd",pod_name="gateway-0"} =1
datapower_gateway_peering_offset{peer_group="gwd",pod_name="gateway-0"}=5881225785

Maybe for the linkstatus it's more like: datapower_gateway_peeringlink{peer_group="gwd",pod_name="gateway-0",remote_ip="IP Node 3"}=1

perryan-coder commented 2 years ago

Ricky, I am not clear on the trawler.set_gauge function and how that manifests in Prometheus. Would the following be correct?

#      { 
#        "Address": "172.30.131.201",
#        "Name": "rate-limit",
#        "PendingUpdates": 0, 
#        "ReplicationOffset": 170111082,
#        "LinkStatus": "ok",
#        "Primary": "yes"
#      },

# datapower_gateway_peering_primary_info{peer_group="gwd",pod_name="gateway-0"} =1
# datapower_gateway_peering_offset{peer_group="gwd",pod_name="gateway-0"}=5881225785
# datapower_gateway_peering_link_{peer_group="gwd",pod_name="gateway-0",remote_ip="IP Node 3"}=1

# https://localhost:5554/mgmt/status/apiconnect/GatewayPeeringStatus
    def gateway_peering_status(self):
        logger.info("Processing status provider GatewayPeeringStatus")
        url = "https://{}:{}/mgmt/status/{}/GatewayPeeringStatus".format(
            self.ip,
            self.port, 
            self.domain)
        status = requests.get(url,
                              auth=(self.username, self.password),
                              verify=False, timeout=1).json()
        logger.debug(status)

        for entry in status["GatewayPeeringStatus"]:
            if self.ip == entry["Address"]:
                labels = {}
                labels["peer_group"] = entry["Name"]
                pvalue = 0
                lvalue = 0
                if entry["Primary"] == "yes":
                    pvalue = 1
                if entry["LinkStatus"] == "ok":
                    lvalue = 1
                self.trawler.set_gauge('datapower', "gateway_peering_primary_info", pvalue, pod_name=self.name, labels)
                self.trawler.set_gauge('datapower', "gateway_peering_primary_link", lvalue, pod_name=self.name, labels)
                self.trawler.set_gauge('datapower', "gateway_peering_primary_offset", entry["ReplicationOffset"], pod_name=self.name, labels)

I was basing the idea that as each pod has the data it would only write the data relating to it's IP. I could add the Address field and do it for all entries.

I wasn't sure in the comment above what remote_ip relates to.

rickymoorhouse commented 2 years ago

That code looks right

Just the data relating to it's IP makes sense - I'd originally gone down the rabbit hole of each pod knowing the full state and that state covers the IP for each - but it's cleaner if we're just monitoring that pods view of itself