Browse Source

HUE-8672 [core] Add Prometheus querying API

Romain Rigaux 7 năm trước cách đây
mục cha
commit
359ad79c09

+ 4 - 0
desktop/conf.dist/hue.ini

@@ -1898,3 +1898,7 @@
 
 
     # If metadata search is enabled, also show the search box in the left assist.
     # If metadata search is enabled, also show the search box in the left assist.
     ## enable_file_search=false
     ## enable_file_search=false
+
+  [[prometheus]]
+    # Configuration options for Prometheus API.
+    ## api_url=http://localhost:9090/api

+ 4 - 0
desktop/conf/pseudo-distributed.ini.tmpl

@@ -1902,3 +1902,7 @@
 
 
     # If metadata search is enabled, also show the search box in the left assist.
     # If metadata search is enabled, also show the search box in the left assist.
     ## enable_file_search=false
     ## enable_file_search=false
+
+  [[prometheus]]
+    # Configuration options for Prometheus API.
+    ## api_url=http://localhost:9090/api

+ 11 - 0
desktop/libs/metadata/src/metadata/conf.py

@@ -374,6 +374,17 @@ MANAGER = ConfigSection(
   # password comes from get_navigator_auth_password()
   # password comes from get_navigator_auth_password()
 )
 )
 
 
+PROMETHEUS = ConfigSection(
+  key='prometheus',
+  help=_t("""Configuration options for Prometheus API"""),
+  members=dict(
+    API_URL=Config(
+      key='api_url',
+      help=_t('Base URL to API.'),
+      default=None),
+  )
+)
+
 
 
 def test_metadata_configurations(user):
 def test_metadata_configurations(user):
   from libsentry.conf import is_enabled
   from libsentry.conf import is_enabled

+ 63 - 0
desktop/libs/metadata/src/metadata/prometheus_api.py

@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# -- coding: utf-8 --
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+
+from django.utils.html import escape
+from django.utils.translation import ugettext as _
+from django.views.decorators.http import require_POST
+
+from desktop.lib.django_util import JsonResponse
+from desktop.lib.i18n import force_unicode
+
+from metadata.prometheus_client import PrometheusApi
+
+
+LOG = logging.getLogger(__name__)
+
+
+def error_handler(view_fn):
+  def decorator(*args, **kwargs):
+    try:
+      return view_fn(*args, **kwargs)
+    except Exception, e:
+      LOG.exception(e)
+      response = {
+        'status': -1,
+        'message': force_unicode(str(e))
+      }
+    return JsonResponse(response, status=500)
+  return decorator
+
+
+@error_handler
+@require_POST
+def query(request):
+  response = {
+    'status': 0
+  }
+  api = PrometheusApi(request.user)
+
+  query = request.POST.get('query')
+
+  if request.POST.get('start'):
+    response['data'] = api.range_query(query, start=request.POST.get('start'), end=request.POST.get('end'), steps=request.POST.get('steps'))
+  else:
+    response['data'] = api.query(query)
+
+  return JsonResponse(response)

+ 83 - 0
desktop/libs/metadata/src/metadata/prometheus_client.py

@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# -- coding: utf-8 --
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+import urllib
+
+from django.core.cache import cache
+from django.utils.translation import ugettext as _
+
+from desktop.lib.rest.http_client import RestException, HttpClient
+from desktop.lib.rest.resource import Resource
+from desktop.lib.i18n import smart_unicode
+
+from metadata.conf import PROMETHEUS
+
+
+LOG = logging.getLogger(__name__)
+VERSION = 'v1'
+
+
+class PrometheusApiException(Exception):
+  def __init__(self, message=None):
+    self.message = message or _('No error message, please check the logs.')
+
+  def __str__(self):
+    return str(self.message)
+
+  def __unicode__(self):
+    return smart_unicode(self.message)
+
+
+class PrometheusApi(object):
+
+  def __init__(self, user=None, security_enabled=False, ssl_cert_ca_verify=False):
+    self._api_url = '%s/%s' % (PROMETHEUS.API_URL.get().strip('/'), VERSION)
+
+    self.user = user
+    self._client = HttpClient(self._api_url, logger=LOG)
+
+    if security_enabled:
+      self._client.set_kerberos_auth()
+    else:
+      self._client.set_basic_auth(self._username, self._password)
+
+    self._client.set_verify(ssl_cert_ca_verify)
+    self._root = Resource(self._client)
+
+
+  def query(self, query):
+    try:
+      return self._root.get('query', {
+        'query': query,
+      })['data']
+    except RestException, e:
+      raise PrometheusApiException(e)
+
+  def range_query(self, query, start, end, steps):
+    # e.g. /api/v1/query_range?query=up&start=2015-07-01T20:10:30.781Z&end=2015-07-01T20:11:00.781Z&step=15s
+    try:
+      return self._root.get('query_range', {
+        'query': query,
+        'start': start,
+        'end': end,
+        'steps': steps
+      })['data']
+    except RestException, e:
+      raise PrometheusApiException(e)