blob: 794ddb3b3ae984b8b94aedaf22a470aaf6098a63 [file] [log] [blame]
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import time
import functools
# Not all apps enable endpoints. If the import fails, the app will not
# use @instrument_endpoint() decorator, so it is safe to ignore it.
try:
import endpoints
except ImportError: # pragma: no cover
pass
from infra_libs.ts_mon import exporter
from infra_libs.ts_mon.common import http_metrics
def instrument(time_fn=time.time):
"""Decorator to instrument Cloud Endpoint methods."""
def decorator(fn):
method_name = fn.__name__
assert method_name
@functools.wraps(fn)
def decorated(service, *args, **kwargs):
service_name = service.__class__.__name__
endpoint_name = '/_ah/spi/%s.%s' % (service_name, method_name)
start_time = time_fn()
response_status = 0
time_now = time_fn()
try:
with exporter.parallel_flush(time_now):
ret = fn(service, *args, **kwargs)
response_status = 200
return ret
except endpoints.ServiceException as e:
response_status = e.http_status
raise
except Exception:
response_status = 500
raise
finally:
elapsed_ms = int((time_fn() - start_time) * 1000)
http_metrics.update_http_server_metrics(endpoint_name, response_status,
elapsed_ms)
return decorated
return decorator