[SEBA-284] Pusblishing prometheus counter for gRPC endpoints
Change-Id: I7143b301227b9961363754e83d7ff9826aae6920
diff --git a/.gitignore b/.gitignore
index 7da3feb..23ed2a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,7 @@
lib/xos-config/cover/
lib/xos-genx/cover/
.vscode
+
+lib/xos-kafka/build/
+lib/xos-kafka/dist/
+lib/xos-kafka/xoskafka.egg-info/
\ No newline at end of file
diff --git a/VERSION b/VERSION
index d302656..f316ecb 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.1.18
+2.1.19
diff --git a/containers/xos/Dockerfile.client b/containers/xos/Dockerfile.client
index 3b29b0d..19d6163 100644
--- a/containers/xos/Dockerfile.client
+++ b/containers/xos/Dockerfile.client
@@ -13,7 +13,7 @@
# limitations under the License.
# xosproject/xos-client
-FROM xosproject/xos-libraries:2.1.18
+FROM xosproject/xos-libraries:2.1.19
# Install XOS client
COPY xos/xos_client /tmp/xos_client
diff --git a/containers/xos/Dockerfile.libraries b/containers/xos/Dockerfile.libraries
index 364f44a..d3808f1 100644
--- a/containers/xos/Dockerfile.libraries
+++ b/containers/xos/Dockerfile.libraries
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-FROM xosproject/xos-base:2.1.18
+# xosproject/xos-libraries
+FROM xosproject/xos-base:2.1.19
# Add libraries
COPY lib /opt/xos/lib
diff --git a/containers/xos/Dockerfile.synchronizer-base b/containers/xos/Dockerfile.synchronizer-base
index 9f4a785..7caf211 100644
--- a/containers/xos/Dockerfile.synchronizer-base
+++ b/containers/xos/Dockerfile.synchronizer-base
@@ -13,7 +13,7 @@
# limitations under the License.
# xosproject/xos-synchronizer-base
-FROM xosproject/xos-client:2.1.18
+FROM xosproject/xos-client:2.1.19
COPY xos/synchronizers/new_base /opt/xos/synchronizers/new_base
COPY xos/xos/logger.py /opt/xos/xos/logger.py
diff --git a/containers/xos/Dockerfile.xos-core b/containers/xos/Dockerfile.xos-core
index f9c8ae3..0edef02 100644
--- a/containers/xos/Dockerfile.xos-core
+++ b/containers/xos/Dockerfile.xos-core
@@ -13,7 +13,7 @@
# limitations under the License.
# xosproject/xos-core
-FROM xosproject/xos-libraries:2.1.18
+FROM xosproject/xos-libraries:2.1.19
# Install XOS
ADD xos /opt/xos
diff --git a/containers/xos/Makefile b/containers/xos/Makefile
new file mode 100644
index 0000000..9b893b7
--- /dev/null
+++ b/containers/xos/Makefile
@@ -0,0 +1,53 @@
+# Copyright 2017 the original author or authors.
+#
+# Licensed 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.
+
+
+# Container are build via the `make build` commands.
+
+# Optional parameters are:
+# `REGISTRY=192.168.99.100:3000/ REPOSITORY=xosproject/ DOCKER_BUILD_ARGS="--no-cache" TAG=dev make build`
+
+ifeq ($(TAG),)
+TAG := candidate
+endif
+
+ifeq ($(REPOSITORY),)
+REPOSITORY := xosproject/
+endif
+
+summary:
+ @echo Building images with:
+ @echo " Build args: $(DOCKER_BUILD_ARGS)"
+ @echo " Registry: ${REGISTRY}"
+ @echo " Repository: ${REPOSITORY}"
+ @echo " Tag: ${TAG}"
+
+build: summary xos-base xos-libraries xos-client xos-core xos-synchronizer-base
+
+xos-base:
+ docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}xos-base:${TAG} -f Dockerfile.base .
+
+xos-libraries:
+ docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}xos-libraries:${TAG} -f Dockerfile.libraries ../..
+
+xos-client:
+ rm -rf tmp.chameleon
+ cp -R ../../../../component/chameleon tmp.chameleon
+ docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}xos-client:${TAG} -f Dockerfile.client ../..
+
+xos-core:
+ docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}xos-core:${TAG} -f Dockerfile.xos-core ../..
+
+xos-synchronizer-base:
+ docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}xos-synchronizer-base:${TAG} -f Dockerfile.synchronizer-base ../..
diff --git a/containers/xos/pip_requested.txt b/containers/xos/pip_requested.txt
index 60b06b0..a4a7825 100644
--- a/containers/xos/pip_requested.txt
+++ b/containers/xos/pip_requested.txt
@@ -30,6 +30,7 @@
ply==3.11
plyxproto==3.1.0
protobuf==3.5.2
+prometheus_client==0.4.0
# Avoids a warning, see http://initd.org/psycopg/docs/faq.html#faq-compile
psycopg2==2.7.4 --no-binary psycopg2
pyOpenSSL==17.5.0
diff --git a/containers/xos/pip_requirements.txt b/containers/xos/pip_requirements.txt
index dce794e..49cc324 100644
--- a/containers/xos/pip_requirements.txt
+++ b/containers/xos/pip_requirements.txt
@@ -88,6 +88,7 @@
ply==3.11
plyxproto==3.1.0
prettytable==0.7.2
+prometheus-client==0.4.0
protobuf==3.5.2
# Avoids a warning, see http://initd.org/psycopg/docs/faq.html#faq-compile
psycopg2==2.7.4 --no-binary psycopg2
diff --git a/lib/xos-genx/xosgenx/targets/grpc_api.xtarget b/lib/xos-genx/xosgenx/targets/grpc_api.xtarget
index dffc347..4abf3dc 100644
--- a/lib/xos-genx/xosgenx/targets/grpc_api.xtarget
+++ b/lib/xos-genx/xosgenx/targets/grpc_api.xtarget
@@ -2,10 +2,12 @@
import time
from protos import xos_pb2, xos_pb2_grpc
from google.protobuf.empty_pb2 import Empty
+from apistats import track_request_time, REQUEST_COUNT
from django.contrib.auth import authenticate as django_authenticate
from xos.exceptions import *
from apihelper import XOSAPIHelperMixin, translate_exceptions
+import grpc
class XosService(xos_pb2_grpc.xosServicer, XOSAPIHelperMixin):
def __init__(self, thread_pool):
@@ -17,41 +19,59 @@
{% for object in proto.messages | sort(attribute='name') %}
{%- if object.name!='XOSBase' %}
- @translate_exceptions
+ @translate_exceptions("{{ object.name }}", "List{{ object.name }}")
+ @track_request_time("{{ object.name }}", "List{{ object.name }}")
def List{{ object.name }}(self, request, context):
user=self.authenticate(context)
model=self.get_model("{{ object.name }}")
- return self.list(model, user)
+ res = self.list(model, user)
+ REQUEST_COUNT.labels('xos-core', "{{ object.name }}", "List{{ object.name }}", grpc.StatusCode.OK).inc()
+ return res
- @translate_exceptions
+ @translate_exceptions("{{ object.name }}", "Filter{{ object.name }}")
+ @track_request_time("{{ object.name }}", "Filter{{ object.name }}")
def Filter{{ object.name }}(self, request, context):
user=self.authenticate(context)
model=self.get_model("{{ object.name }}")
- return self.filter(model, user, request)
+ res = self.filter(model, user, request)
+ REQUEST_COUNT.labels('xos-core', "{{ object.name }}", "List{{ object.name }}", grpc.StatusCode.OK).inc()
+ return res
- @translate_exceptions
+ @translate_exceptions("{{ object.name }}", "Get{{ object.name }}")
+ @track_request_time("{{ object.name }}", "Get{{ object.name }}")
def Get{{ object.name }}(self, request, context):
user=self.authenticate(context)
model=self.get_model("{{ object.name }}")
- return self.get(model, user, request.id)
+ res = self.get(model, user, request.id)
+ REQUEST_COUNT.labels('xos-core', "{{ object.name }}", "List{{ object.name }}", grpc.StatusCode.OK).inc()
+ return res
- @translate_exceptions
+ @translate_exceptions("{{ object.name }}", "Create{{ object.name }}")
+ @track_request_time("{{ object.name }}", "Create{{ object.name }}")
def Create{{ object.name }}(self, request, context):
user=self.authenticate(context)
model=self.get_model("{{ object.name }}")
- return self.create(model, user, request)
+ res = self.create(model, user, request)
+ REQUEST_COUNT.labels('xos-core', "{{ object.name }}", "List{{ object.name }}", grpc.StatusCode.OK).inc()
+ return res
- @translate_exceptions
+ @translate_exceptions("{{ object.name }}", "Delete{{ object.name }}")
+ @track_request_time("{{ object.name }}", "Delete{{ object.name }}")
def Delete{{ object.name }}(self, request, context):
user=self.authenticate(context)
model=self.get_model("{{ object.name }}")
- return self.delete(model, user, request.id)
+ res = self.delete(model, user, request.id)
+ REQUEST_COUNT.labels('xos-core', "{{ object.name }}", "List{{ object.name }}", grpc.StatusCode.OK).inc()
+ return res
- @translate_exceptions
+ @translate_exceptions("{{ object.name }}", "Update{{ object.name }}")
+ @track_request_time("{{ object.name }}", "Update{{ object.name }}")
def Update{{ object.name }}(self, request, context):
user=self.authenticate(context)
model=self.get_model("{{ object.name }}")
- return self.update(model, user, request.id, request, context)
+ res = self.update(model, user, request.id, request, context)
+ REQUEST_COUNT.labels('xos-core', "{{ object.name }}", "List{{ object.name }}", grpc.StatusCode.OK).inc()
+ return res
{%- endif %}
{% endfor %}
diff --git a/xos/coreapi/apihelper.py b/xos/coreapi/apihelper.py
index c394fc8..fb47e5d 100644
--- a/xos/coreapi/apihelper.py
+++ b/xos/coreapi/apihelper.py
@@ -23,9 +23,7 @@
from protos import xos_pb2
from google.protobuf.empty_pb2 import Empty
import grpc
-import json
-from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import authenticate as django_authenticate
from django.db.models import F, Q
from core.models import *
@@ -37,7 +35,7 @@
from xosconfig import Config
from multistructlog import create_logger
log = create_logger(Config().get('logging'))
-
+from apistats import REQUEST_COUNT
class XOSDefaultSecurityContext(object):
grant_access = True
@@ -61,39 +59,45 @@
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
-
-def translate_exceptions(function):
+def translate_exceptions(model, method):
""" this decorator translates XOS exceptions to grpc status codes """
- def wrapper(*args, **kwargs):
- try:
- return function(*args, **kwargs)
- except Exception as e:
- import traceback
- tb = traceback.format_exc()
- print tb
- # TODO can we propagate it over the APIs?
+ def decorator(function):
+ def wrapper(*args, **kwargs):
+ try:
+ return function(*args, **kwargs)
+ except Exception as e:
- if "context" in kwargs:
- context = kwargs["context"]
- else:
- context = args[2]
+ import traceback
+ tb = traceback.format_exc()
+ print tb
+ # TODO can we propagate it over the APIs?
- if hasattr(e, 'json_detail'):
- context.set_details(e.json_detail)
- elif hasattr(e, 'detail'):
- context.set_details(e.detail)
+ if "context" in kwargs:
+ context = kwargs["context"]
+ else:
+ context = args[2]
- if (isinstance(e, XOSPermissionDenied)):
- context.set_code(grpc.StatusCode.PERMISSION_DENIED)
- elif (isinstance(e, XOSValidationError)):
- context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
- elif (isinstance(e, XOSNotAuthenticated)):
- context.set_code(grpc.StatusCode.UNAUTHENTICATED)
- elif (isinstance(e, XOSNotFound)):
- context.set_code(grpc.StatusCode.NOT_FOUND)
- raise
- return wrapper
+ if hasattr(e, 'json_detail'):
+ context.set_details(e.json_detail)
+ elif hasattr(e, 'detail'):
+ context.set_details(e.detail)
+
+ if (isinstance(e, XOSPermissionDenied)):
+ REQUEST_COUNT.labels('xos-core', model, method, grpc.StatusCode.PERMISSION_DENIED).inc()
+ context.set_code(grpc.StatusCode.PERMISSION_DENIED)
+ elif (isinstance(e, XOSValidationError)):
+ REQUEST_COUNT.labels('xos-core', model, method, grpc.StatusCode.INVALID_ARGUMENT).inc()
+ context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
+ elif (isinstance(e, XOSNotAuthenticated)):
+ REQUEST_COUNT.labels('xos-core', model, method, grpc.StatusCode.UNAUTHENTICATED).inc()
+ context.set_code(grpc.StatusCode.UNAUTHENTICATED)
+ elif (isinstance(e, XOSNotFound)):
+ REQUEST_COUNT.labels('xos-core', model, method, grpc.StatusCode.NOT_FOUND).inc()
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ raise
+ return wrapper
+ return decorator
bench_tStart = time.time()
@@ -477,7 +481,8 @@
self.handle_m2m(new_obj, request, [])
- return self.objToProto(new_obj)
+ response = self.objToProto(new_obj)
+ return response
except:
log.exception("Exception in apihelper.create")
raise
@@ -521,7 +526,8 @@
if not obj.deleted:
self.handle_m2m(obj, message, m2m_update_fields)
- return self.objToProto(obj)
+ response = self.objToProto(obj)
+ return response
except:
log.exception("Exception in apihelper.update")
raise
@@ -577,7 +583,8 @@
# FIXME: Implement auditing here
# logging.info("User requested x objects, y objects were filtered out by policy z")
- return self.querysetToProto(djangoClass, filtered_queryset)
+ response = self.querysetToProto(djangoClass, filtered_queryset)
+ return response
except:
log.exception("Exception in apihelper.list")
raise
@@ -615,7 +622,8 @@
# FIXME: Implement auditing here
# logging.info("User requested x objects, y objects were filtered out by policy z")
- return self.querysetToProto(djangoClass, filtered_queryset)
+ response = self.querysetToProto(djangoClass, filtered_queryset)
+ return response
except:
log.exception("Exception in apihelper.filter")
raise
diff --git a/xos/coreapi/apistats.py b/xos/coreapi/apistats.py
new file mode 100644
index 0000000..a209e78
--- /dev/null
+++ b/xos/coreapi/apistats.py
@@ -0,0 +1,48 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed 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.
+
+from prometheus_client import Counter, Histogram
+import time
+
+REQUEST_COUNT = Counter(
+ 'grpc_request_count', 'GRPC Request Count',
+ ['app_name', 'model_name', 'endpoint', 'status']
+)
+
+# TODO (teone) add caller as label for the counter (eg: GUI, TOSCA, SYNCHRONIZER)
+# TODO (teone) add user informations as label for the counter
+
+REQUEST_LATENCY = Histogram(
+ 'grpc_request_latency_seconds', 'GRPC Request latency',
+ ['app_name', 'model_name', 'endpoint']
+)
+
+def track_request_time(model, method):
+ """
+ This decorator register the request time of a request
+ """
+
+ def decorator(function):
+
+ def wrapper(*args, **kwargs):
+
+ start_time = time.time()
+ res = function(*args, **kwargs)
+ resp_time = time.time() - start_time
+ REQUEST_LATENCY.labels('xos-core', model, method).observe(resp_time)
+ return res
+
+ return wrapper
+
+ return decorator
\ No newline at end of file
diff --git a/xos/coreapi/core_main.py b/xos/coreapi/core_main.py
index c4553c1..948ebd1 100644
--- a/xos/coreapi/core_main.py
+++ b/xos/coreapi/core_main.py
@@ -30,6 +30,8 @@
from xoskafka import XOSKafkaProducer
XOSKafkaProducer.init()
+import prometheus_client
+
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("--model_status", dest="model_status", type=int, default=0, help="status of model prep")
@@ -57,6 +59,10 @@
if __name__ == '__main__':
args = parse_args()
+ # start the prometheus server
+ # TODO (teone) consider moving this in a separate process so that it won't die when we load services
+ prometheus_client.start_http_server(8000)
+
server = XOSGrpcServer(model_status = args.model_status,
model_output = args.model_output)
server.start()
diff --git a/xos/coreapi/xos_dynamicload_api.py b/xos/coreapi/xos_dynamicload_api.py
index 30ef79b..1f9cd48 100644
--- a/xos/coreapi/xos_dynamicload_api.py
+++ b/xos/coreapi/xos_dynamicload_api.py
@@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
import base64
import fnmatch
import os
@@ -28,8 +27,8 @@
from xosutil.autodiscover_version import autodiscover_version_of_main
from dynamicbuild import DynamicBuilder
-# NOTE/FIXME this file is loaded before Django, we can't import apihelper
-# from apihelper import XOSAPIHelperMixin, translate_exceptions
+from apistats import REQUEST_COUNT, track_request_time
+import grpc
class DynamicLoadService(dynamicload_pb2_grpc.dynamicloadServicer):
def __init__(self, thread_pool, server):
@@ -47,6 +46,7 @@
"""
self.django_apps = django_apps
+ @track_request_time("DynamicLoad", "LoadModels")
def LoadModels(self, request, context):
try:
builder = DynamicBuilder()
@@ -57,12 +57,14 @@
response = dynamicload_pb2.LoadModelsReply()
response.status = response.SUCCESS
-
+ REQUEST_COUNT.labels('xos-core', "DynamicLoad", "LoadModels", grpc.StatusCode.OK).inc()
return response
except Exception, e:
import traceback; traceback.print_exc()
+ REQUEST_COUNT.labels('xos-core', "DynamicLoad", "LoadModels", grpc.StatusCode.INTERNAL).inc()
raise e
+ @track_request_time("DynamicLoad", "UnloadModels")
def UnloadModels(self, request, context):
try:
builder = DynamicBuilder()
@@ -73,12 +75,14 @@
response = dynamicload_pb2.LoadModelsReply()
response.status = response.SUCCESS
-
+ REQUEST_COUNT.labels('xos-core', "DynamicLoad", "UnloadModels", grpc.StatusCode.OK).inc()
return response
except Exception, e:
import traceback; traceback.print_exc()
+ REQUEST_COUNT.labels('xos-core', "DynamicLoad", "UnloadModels", grpc.StatusCode.INTERNAL).inc()
raise e
+ @track_request_time("DynamicLoad", "GetLoadStatus")
def GetLoadStatus(self, request, context):
django_apps_by_name = {}
if self.django_apps:
@@ -112,12 +116,14 @@
item.state = "present"
else:
item.state = "load"
-
+ REQUEST_COUNT.labels('xos-core', "DynamicLoad", "GetLoadStatus", grpc.StatusCode.OK).inc()
return response
except Exception, e:
import traceback; traceback.print_exc()
+ REQUEST_COUNT.labels('xos-core', "DynamicLoad", "GetLoadStatus", grpc.StatusCode.INTERNAL).inc()
raise e
+ @track_request_time("DynamicLoad", "GetConvenienceMethods")
def GetConvenienceMethods(self, request, context):
# self.authenticate(context, required=True)
try:
@@ -131,10 +137,12 @@
item = response.convenience_methods.add()
item.filename = cm["filename"]
item.contents = open(cm["path"]).read()
+ REQUEST_COUNT.labels('xos-core', "DynamicLoad", "GetConvenienceMethods", grpc.StatusCode.OK).inc()
return response
except Exception, e:
import traceback; traceback.print_exc()
+ REQUEST_COUNT.labels('xos-core', "DynamicLoad", "GetConvenienceMethods", grpc.StatusCode.INTERNAL).inc()
raise e
diff --git a/xos/coreapi/xos_modeldefs_api.py b/xos/coreapi/xos_modeldefs_api.py
index fb79281..5a03b6d 100644
--- a/xos/coreapi/xos_modeldefs_api.py
+++ b/xos/coreapi/xos_modeldefs_api.py
@@ -13,15 +13,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
-import base64
-import time
import yaml
from protos import modeldefs_pb2, modeldefs_pb2_grpc
-from google.protobuf.empty_pb2 import Empty
-
+import grpc
from xos.exceptions import *
from apihelper import XOSAPIHelperMixin
+from apistats import REQUEST_COUNT, track_request_time
def yaml_to_grpc(yaml_repr, grpc_container, yaml_key = None, grpc_parent = None):
if isinstance(yaml_repr, dict):
@@ -42,6 +39,7 @@
def stop(self):
pass
+ @track_request_time("Modeldefs", "ListModelDefs")
def ListModelDefs(self, request, context):
ystr = open('protos/modeldefs.yaml').read()
yaml_repr = yaml.load(ystr)
@@ -50,6 +48,7 @@
yaml_to_grpc(yaml_repr, modeldefs)
+ REQUEST_COUNT.labels('xos-core', "Modeldefs", "ListModelDefs", grpc.StatusCode.OK).inc()
return modeldefs
diff --git a/xos/coreapi/xos_utility_api.py b/xos/coreapi/xos_utility_api.py
index cddf861..d48ad4e 100644
--- a/xos/coreapi/xos_utility_api.py
+++ b/xos/coreapi/xos_utility_api.py
@@ -32,6 +32,8 @@
from core.models import *
from xos.exceptions import *
from apihelper import XOSAPIHelperMixin, translate_exceptions
+import grpc
+from apistats import REQUEST_COUNT, track_request_time
# The Tosca engine expects to be run from /opt/xos/tosca/ or equivalent. It
# needs some sys.path fixing up.
@@ -68,7 +70,8 @@
def stop(self):
pass
- @translate_exceptions
+ @translate_exceptions("Utilities", "Login")
+ @track_request_time("Utilities", "Login")
def Login(self, request, context):
if not request.username:
raise XOSNotAuthenticated("No username")
@@ -87,9 +90,11 @@
response = utility_pb2.LoginResponse()
response.sessionid = session.session_key
+ REQUEST_COUNT.labels('xos-core', "Utilities", "Login", grpc.StatusCode.OK).inc()
return response
- @translate_exceptions
+ @translate_exceptions("Utilities", "Logout")
+ @track_request_time("Utilities", "Logout")
def Logout(self, request, context):
for (k, v) in context.invocation_metadata():
if (k.lower()=="x-xossession"):
@@ -97,9 +102,12 @@
if "_auth_user_id" in s:
del s["_auth_user_id"]
s.save()
+ REQUEST_COUNT.labels('xos-core', "Utilities", "Login", grpc.StatusCode.OK).inc()
return Empty()
- @translate_exceptions
+ # FIXME are we still using these?
+ @translate_exceptions("Utilities", "RunTosca")
+ @track_request_time("Utilities", "RunTosca")
def RunTosca(self, request, context):
user=self.authenticate(context, required=True)
@@ -123,7 +131,8 @@
return response
- @translate_exceptions
+ @translate_exceptions("Utilities", "DestryTosca")
+ @track_request_time("Utilities", "DestryTosca")
def DestroyTosca(self, request, context):
user=self.authenticate(context, required=True)
@@ -146,17 +155,23 @@
response.messages = "\n".join(xt.log_msgs)
return response
+ # end FIXME
- @translate_exceptions
+ @translate_exceptions("Utilities", "NoOp")
+ @track_request_time("Utilities", "NoOp")
def NoOp(self, request, context):
+ REQUEST_COUNT.labels('xos-core', "Utilities", "NoOp", grpc.StatusCode.OK).inc()
return Empty()
- @translate_exceptions
+ @translate_exceptions("Utilities", "AuthenticatedNoOp")
+ @track_request_time("Utilities", "AuthenticatedNoOp")
def AuthenticatedNoOp(self, request, context):
self.authenticate(context, required=True)
+ REQUEST_COUNT.labels('xos-core', "Utilities", "AuthenticatedNoOp", grpc.StatusCode.OK).inc()
return Empty()
- @translate_exceptions
+ @translate_exceptions("Utilities", "ListDirtyModels")
+ @track_request_time("Utilities", "ListDirtyModels")
def ListDirtyModels(self, request, context):
dirty_models = utility_pb2.ModelList()
@@ -175,9 +190,11 @@
item.class_name = model.__name__
item.id = obj.id
+ REQUEST_COUNT.labels('xos-core', "Utilities", "ListDirtyModels", grpc.StatusCode.OK).inc()
return dirty_models
- @translate_exceptions
+ @translate_exceptions("Utilities", "SetDirtyModels")
+ @track_request_time("Utilities", "SetDirtyModels")
def SetDirtyModels(self, request, context):
user=self.authenticate(context, required=True)
@@ -206,9 +223,11 @@
item.id = obj.id
item.info = str(e)
+ REQUEST_COUNT.labels('xos-core', "Utilities", "SetDirtyModels", grpc.StatusCode.OK).inc()
return dirty_models
- @translate_exceptions
+ @translate_exceptions("Utilities", "GetXproto")
+ @track_request_time("Utilities", "GetXproto")
def GetXproto(self, request, context):
res = utility_pb2.XProtos()
@@ -231,9 +250,11 @@
xproto += content
res.xproto = xproto
+ REQUEST_COUNT.labels('xos-core', "Utilities", "GetXproto", grpc.StatusCode.OK).inc()
return res
- @translate_exceptions
+ @translate_exceptions("Utilities", "GetPopulatedServiceInstances")
+ @track_request_time("Utilities", "GetPopulatedServiceInstances")
def GetPopulatedServiceInstances(self, request, context):
"""
Return a service instance with provider and subsciber service instance ids
@@ -268,4 +289,5 @@
elif l.subscriber_network:
response.subscribed_network.append(l.subscriber_network.id)
+ REQUEST_COUNT.labels('xos-core', "Utilities", "GetPopulatedServiceInstances", grpc.StatusCode.OK).inc()
return response