Skip to content

Commit

Permalink
Add bad_statuses and state
Browse files Browse the repository at this point in the history
  • Loading branch information
sergioasantiago committed Aug 22, 2023
1 parent e60a363 commit f2cfdf7
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ jobs:
ref: 'main'
fetch-depth: 0
- name: Generate Changelog
uses: sergioasantiago/generate-changelog-action@main
uses: pfandie/generate-changelog-action@v1
id: changelog
with:
output_file: CHANGELOG.md
Expand Down
6 changes: 6 additions & 0 deletions samples/config.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ tableau_server_management:
username: <admin>
password: <password>
sleep_interval_seconds: <30>
bad_statuses:
- Unlicensed
- Degraded
- Error
- Stopped
- Status Unavailable

metrics:
port: <8000>
66 changes: 36 additions & 30 deletions src/tableau_prometheus_exporter/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,47 @@
"service_name",
"instance_id",
"status",
"state",
],
)


def parse(status: Dict) -> None:
"""
Parse Tableau Server Management Status and export as Prometheus Gauge
:return: None
"""

GAUGE_TABLEAU_SERVICE_STATUS.clear()

for node in status.get("clusterStatus", {}).get("nodes", []):
for service in node.get("services", []):
for instance in service.get("instances", []):
GAUGE_TABLEAU_SERVICE_STATUS.labels(
node.get("nodeId", ""),
service.get("serviceName", ""),
instance.get("instanceId", ""),
instance.get("processStatus", ""),
).set(1)


class Server:
def __init__(self, config: Dict):
self.config = config
self.tsm_config = config["tableau_server_management"]
self.metrics_port = config["metrics"].get("metrics_port", DEFAULT_METRICS_PORT)
self.sleep_interval = self.tsm_config.get(
"sleep_interval_seconds", DEFAULT_SLEEP_INTERVAL_SECONDS
)
self.bad_statuses = self.tsm_config.get("bad_statuses", [])

RUNNING = True

def parse(self, status: Dict) -> None:
"""
Parse Tableau Server Management Status and export as Prometheus Gauge
:return: None
"""

GAUGE_TABLEAU_SERVICE_STATUS.clear()

for node in status.get("clusterStatus", {}).get("nodes", []):
for service in node.get("services", []):
for instance in service.get("instances", []):
value = (
0
if instance.get("processStatus", "") in self.bad_statuses
else 1
)
GAUGE_TABLEAU_SERVICE_STATUS.labels(
node.get("nodeId", ""),
service.get("serviceName", ""),
instance.get("instanceId", ""),
instance.get("processStatus", ""),
instance.get("currentDeploymentState", ""),
).set(value)

def start_and_run_forever(self) -> None:
"""
Start up the server to expose the metrics.
Expand All @@ -60,15 +71,10 @@ def start_and_run_forever(self) -> None:
"""
_logger.info("Starting Metrics Server...")

metrics_port = self.config["metrics"].get("metrics_port", DEFAULT_METRICS_PORT)
sleep_interval = self.config["tableau_server_management"].get(
"sleep_interval_seconds", DEFAULT_SLEEP_INTERVAL_SECONDS
)

start_http_server(port=metrics_port)
start_http_server(port=self.metrics_port)
while self.RUNNING:
with TableauSession(self.config) as session:
with TableauSession(self.tsm_config) as session:
status = session.status()
parse(status)
self.parse(status)

time.sleep(sleep_interval)
time.sleep(self.sleep_interval)
35 changes: 26 additions & 9 deletions tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@
from unittest.mock import PropertyMock

import tableau_prometheus_exporter
from tableau_prometheus_exporter.server import (
DEFAULT_SLEEP_INTERVAL_SECONDS,
Server,
parse,
)
from tableau_prometheus_exporter.server import DEFAULT_SLEEP_INTERVAL_SECONDS, Server

MOCK_CONFIG = {
"metrics": {"port": 1234},
"tableau_server_management": {
"host": "http://test.local",
"username": "test",
"password": "test",
"bad_statuses": ["error"],
},
}

Expand All @@ -26,7 +23,16 @@
{
"serviceName": "service1",
"instances": [
{"instanceId": "instance1", "processStatus": "running"}
{
"instanceId": "instance1",
"processStatus": "running",
"currentDeploymentState": "enabled",
},
{
"instanceId": "instance2",
"processStatus": "error",
"currentDeploymentState": "enabled",
},
],
}
],
Expand All @@ -44,7 +50,6 @@ def test_start_and_run_forever(mocker):
mock_manager.status.return_value = {}
mocker.patch("requests.Session", return_value=mocker.MagicMock())
mocker.patch("tableau_prometheus_exporter.server.start_http_server")
mocker.patch("tableau_prometheus_exporter.server.parse")
mocker.patch("time.sleep")

server = Server(MOCK_CONFIG)
Expand All @@ -60,12 +65,11 @@ def test_start_and_run_forever(mocker):
tableau_prometheus_exporter.server.start_http_server.assert_called_once()
mock_tableau_session.assert_called_once_with(MOCK_CONFIG)
mock_manager.status.assert_called_once()
tableau_prometheus_exporter.server.parse.assert_called_once()
time.sleep.assert_called_with(DEFAULT_SLEEP_INTERVAL_SECONDS)


def test_parse_method():
parse(MOCK_STATUS)
Server(MOCK_CONFIG).parse(MOCK_STATUS)

metric_samples = list(
tableau_prometheus_exporter.server.GAUGE_TABLEAU_SERVICE_STATUS.collect()
Expand All @@ -80,5 +84,18 @@ def test_parse_method():
"service_name": "service1",
"instance_id": "instance1",
"status": "running",
"state": "enabled",
}
assert sample.value == 1.0

sample = metric_samples[1]

assert sample.name == "tableau_service_status"
assert sample.labels == {
"node_id": "node1",
"service_name": "service1",
"instance_id": "instance2",
"status": "error",
"state": "enabled",
}
assert sample.value == 0.0

0 comments on commit f2cfdf7

Please sign in to comment.