Skip to content

Commit 5ba40a7

Browse files
leo-naekaAdrian Turjak
authored and
Adrian Turjak
committed
Add incoming/indexer/storage information to V1 API's status endpoint
1 parent 5eeb3f0 commit 5ba40a7

24 files changed

+354
-35
lines changed

gnocchi/common/ceph.py

+21
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15+
from collections import OrderedDict
1516
import errno
17+
import six
1618

1719
import daiquiri
1820

@@ -97,3 +99,22 @@ def errno_to_exception(ret):
9799
raise rados.Error("Unhandled error '%s'" % ret)
98100
else:
99101
raise getattr(rados, name)
102+
103+
104+
def get_ceph_health_status(driver):
105+
"""Return ceph status.
106+
107+
Include ceph stats.
108+
"""
109+
response = OrderedDict([
110+
('name', driver.__class__.__name__)
111+
])
112+
try:
113+
stats = driver.rados.get_cluster_stats()
114+
except Exception as e:
115+
response['is_available'] = False
116+
response['error'] = six.text_type(e)
117+
else:
118+
response['is_available'] = True
119+
response['stats'] = stats
120+
return response

gnocchi/common/file.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# -*- coding:Utf-8 -*-
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
from __future__ import unicode_literals
15+
16+
from collections import OrderedDict
17+
18+
19+
def get_file_health_status(driver):
20+
"""Return file status."""
21+
return OrderedDict([
22+
('name', driver.__class__.__name__),
23+
('is_available', True)
24+
])

gnocchi/common/redis.py

+20
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
from __future__ import absolute_import
1818

19+
from collections import OrderedDict
1920
from oslo_config import cfg
2021
import six
2122
from six.moves.urllib import parse
@@ -167,3 +168,22 @@ def get_client(conf, scripts=None):
167168
}
168169

169170
return client, scripts
171+
172+
173+
def get_redis_health_status(driver):
174+
"""Return redis status.
175+
176+
Include redis info.
177+
"""
178+
response = OrderedDict([
179+
('name', driver.__class__.__name__)
180+
])
181+
try:
182+
info = driver._client.info()
183+
except Exception as e:
184+
response['is_available'] = False
185+
response['error'] = six.text_type(e)
186+
else:
187+
response['is_available'] = True
188+
response['info'] = info
189+
return response

gnocchi/common/s3.py

+19
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1414
# License for the specific language governing permissions and limitations
1515
# under the License.
16+
17+
from collections import OrderedDict
18+
import six
19+
1620
import daiquiri
1721

1822
import tenacity
@@ -82,3 +86,18 @@ def bulk_delete(conn, bucket, objects):
8286
deleted += len(response['Deleted'])
8387
LOG.debug('%s objects deleted, %s objects skipped',
8488
deleted, len(objects) - deleted)
89+
90+
91+
def get_s3_health_status(driver):
92+
"""Return s3 status."""
93+
response = OrderedDict([
94+
('name', driver.__class__.__name__)
95+
])
96+
try:
97+
driver.s3.head_bucket(Bucket=driver._bucket_name)
98+
except Exception as e:
99+
response['is_available'] = False
100+
response['error'] = six.text_type(e)
101+
else:
102+
response['is_available'] = True
103+
return response

gnocchi/common/sqlalchemy.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# -*- coding:Utf-8 -*-
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
from __future__ import unicode_literals
15+
16+
from collections import OrderedDict
17+
import six
18+
19+
20+
def get_sqlalchemy_health_status(driver):
21+
"""Return sqlalchemy status."""
22+
response = OrderedDict([
23+
('name', driver.__class__.__name__)
24+
])
25+
try:
26+
with driver.facade.independent_reader() as session:
27+
session.execute('SELECT 1')
28+
except Exception as e:
29+
response['is_available'] = False
30+
response['error'] = six.text_type(e)
31+
else:
32+
response['is_available'] = True
33+
return response

gnocchi/common/status.py

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# -*- coding:Utf-8 -*-
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
from __future__ import unicode_literals
15+
16+
from collections import OrderedDict
17+
import six
18+
19+
20+
def get_ceph_health_status(driver):
21+
"""Return ceph status.
22+
23+
Include ceph stats.
24+
"""
25+
response = OrderedDict([
26+
('name', driver.__class__.__name__)
27+
])
28+
try:
29+
stats = driver.rados.get_cluster_stats()
30+
except Exception as e:
31+
response['is_available'] = False
32+
response['error'] = six.text_type(e)
33+
else:
34+
response['is_available'] = True
35+
response['stats'] = stats
36+
return response
37+
38+
39+
def get_file_health_status(driver):
40+
"""Return file status."""
41+
return OrderedDict([
42+
('name', driver.__class__.__name__),
43+
('is_available', True)
44+
])
45+
46+
47+
def get_redis_health_status(driver):
48+
"""Return redis status.
49+
50+
Include redis info.
51+
"""
52+
response = OrderedDict([
53+
('name', driver.__class__.__name__)
54+
])
55+
try:
56+
info = driver._client.info()
57+
except Exception as e:
58+
response['is_available'] = False
59+
response['error'] = six.text_type(e)
60+
else:
61+
response['is_available'] = True
62+
response['info'] = info
63+
return response
64+
65+
66+
def get_s3_health_status(driver):
67+
"""Return s3 status."""
68+
response = OrderedDict([
69+
('name', driver.__class__.__name__)
70+
])
71+
try:
72+
driver.s3.head_bucket(Bucket=driver._bucket_name)
73+
except Exception as e:
74+
response['is_available'] = False
75+
response['error'] = six.text_type(e)
76+
else:
77+
response['is_available'] = True
78+
return response
79+
80+
81+
def get_sqlalchemy_health_status(driver):
82+
"""Return sqlalchemy status."""
83+
response = OrderedDict([
84+
('name', driver.__class__.__name__)
85+
])
86+
try:
87+
with driver.facade.independent_reader() as session:
88+
session.execute('SELECT 1')
89+
except Exception as e:
90+
response['is_available'] = False
91+
response['error'] = six.text_type(e)
92+
else:
93+
response['is_available'] = True
94+
return response
95+
96+
97+
def get_swift_health_status(driver):
98+
"""Return swift status.
99+
100+
Include swift account info.
101+
"""
102+
response = OrderedDict([
103+
('name', driver.__class__.__name__)
104+
])
105+
try:
106+
info = driver.swift.head_account()
107+
except Exception as e:
108+
response['is_available'] = False
109+
response['error'] = six.text_type(e)
110+
else:
111+
response['is_available'] = True
112+
response['info'] = info
113+
return response

gnocchi/common/swift.py

+24-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
14-
import daiquiri
14+
15+
from collections import OrderedDict
16+
import six
1517
from six.moves.urllib.parse import quote
1618

19+
import daiquiri
20+
1721
try:
1822
from swiftclient import client as swclient
1923
from swiftclient import utils as swift_utils
@@ -71,3 +75,22 @@ def bulk_delete(conn, container, objects):
7175
resp = swift_utils.parse_api_response(headers, body)
7276
LOG.debug('# of objects deleted: %s, # of objects skipped: %s',
7377
resp['Number Deleted'], resp['Number Not Found'])
78+
79+
80+
def get_swift_health_status(driver):
81+
"""Return swift status.
82+
83+
Include swift account info.
84+
"""
85+
response = OrderedDict([
86+
('name', driver.__class__.__name__)
87+
])
88+
try:
89+
info = driver.swift.head_account()
90+
except Exception as e:
91+
response['is_available'] = False
92+
response['error'] = six.text_type(e)
93+
else:
94+
response['is_available'] = True
95+
response['info'] = info
96+
return response

gnocchi/incoming/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ def finish_sack_processing(sack):
257257
"""Mark sack processing has finished."""
258258
pass
259259

260+
@staticmethod
261+
def get_health_status():
262+
raise exceptions.NotImplementedError
263+
260264

261265
@utils.retry_on_exception_and_log("Unable to initialize incoming driver")
262266
def get_driver(conf):

gnocchi/incoming/ceph.py

+2
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,5 @@ def process_measures_for_sack(self, sack):
232232
self.ioctx.remove_omap_keys(op, tuple(processed_keys))
233233
self.ioctx.operate_write_op(op, str(sack),
234234
flags=self.OMAP_WRITE_FLAGS)
235+
236+
get_health_status = ceph.get_ceph_health_status

gnocchi/incoming/file.py

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import numpy
2525
import six
2626

27+
from gnocchi.common.status import get_file_health_status
2728
from gnocchi import incoming
2829
from gnocchi import utils
2930

@@ -206,3 +207,5 @@ def process_measures_for_sack(self, sack):
206207

207208
for metric_id, files in six.iteritems(processed_files):
208209
self._delete_measures_files_for_metric(metric_id, files)
210+
211+
get_health_status = get_file_health_status

gnocchi/incoming/redis.py

+2
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,5 @@ def finish_sack_processing(self, sack):
193193
# Delete the sack key which handles no data but is used to get a SET
194194
# notification in iter_on_sacks_to_process
195195
self._client.delete(str(sack))
196+
197+
get_health_status = redis.get_redis_health_status

0 commit comments

Comments
 (0)