Skip to content

Commit

Permalink
Import prometheus client to collect metrics (#64)
Browse files Browse the repository at this point in the history
Signed-off-by: Kaiyuan Hu <[email protected]>
  • Loading branch information
Chiiizzzy authored Aug 28, 2023
1 parent 239d40c commit 2cfbe13
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 8 deletions.
Binary file added .coverage
Binary file not shown.
37 changes: 29 additions & 8 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
import argparse
import os
import argparse
import uuid

import uvicorn
from fastapi import FastAPI, UploadFile
from fastapi.encoders import jsonable_encoder
from fastapi.responses import PlainTextResponse

from config import TEMP_DIR


os.makedirs(TEMP_DIR, exist_ok=True)
os.environ['PROMETHEUS_DISABLE_CREATED_SERIES'] = 'true'

# Specify mode
parser = argparse.ArgumentParser(description='Start service with different modes.')
parser.add_argument('--langchain', action='store_true')
parser.add_argument('--towhee', action='store_true')

parser.add_argument('--moniter', action='store_true')
parser.add_argument('--max_observation', default=1000)
parser.add_argument('--name', default=str(uuid.uuid4()))
args = parser.parse_args()

app = FastAPI()
origins = ['*']

# Apply args
USE_LANGCHAIN = args.langchain
USE_TOWHEE = args.towhee
MAX_OBSERVATION = args.max_observation
ENABLE_MONITER = args.moniter
NAME = args.name

assert (USE_LANGCHAIN and not USE_TOWHEE ) or (USE_TOWHEE and not USE_LANGCHAIN), \
'The service should start with either "--langchain" or "--towhee".'
Expand All @@ -27,19 +38,29 @@
from src_langchain.operations import chat, insert, drop, check, get_history, clear_history, count # pylint: disable=C0413
if USE_TOWHEE:
from src_towhee.operations import chat, insert, drop, check, get_history, clear_history, count # pylint: disable=C0413
if ENABLE_MONITER:
from moniter import enable_moniter # pylint: disable=C0413
from prometheus_client import generate_latest, REGISTRY # pylint: disable=C0413

enable_moniter(app, MAX_OBSERVATION, NAME)

@app.get('/metrics')
async def metrics():
registry = REGISTRY
data = generate_latest(registry)
return PlainTextResponse(content=data, media_type='text/plain')

app = FastAPI()
origins = ['*']

@app.get('/')
def check_api():
return jsonable_encoder({'status': True, 'msg': 'ok'}), 200
res = jsonable_encoder({'status': True, 'msg': 'ok'}), 200
return res


@app.get('/answer')
def do_answer_api(session_id: str, project: str, question: str):
try:
new_question, final_answer = chat(session_id=session_id,
project=project, question=question)
new_question, final_answer = chat(session_id=session_id, project=project, question=question)
assert isinstance(final_answer, str)
return jsonable_encoder({
'status': True,
Expand Down
77 changes: 77 additions & 0 deletions moniter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import os
import time

from starlette.middleware.base import BaseHTTPMiddleware
from prometheus_client import Counter, Histogram, Summary

# Define metrics
latencies = {}
latencies['all'] = []

requests_total = Counter('requests_total', 'Cumulative requests', ['name'])
requests_success_total = Counter('requests_success_total', 'Cumulative successful requests', ['name'])
requests_failed_total = Counter('requests_failed_total', 'Cumulative failed requests', ['name'])

endpoint_requests_total = Counter('endpoint_requests_total', 'Cumulative requests of each endpoint', ['name', 'endpoint'])
endpoint_requests_success_total = Counter('endpoint_requests_success_total', 'Cumulative successful requests of each endpoint', ['name', 'endpoint'])
endpoint_requests_failed_total = Counter('endpoint_requests_failed_total', 'Cumulative failed requests of each endpoint', ['name', 'endpoint'])

latency_seconds_histogram = Histogram('latency_seconds_histogram', 'Request process latency histogram', ['name'])
endpoint_latency_seconds_histogram = Histogram(
'endpoint_latency_seconds_histogram', 'Request process latency histogram of each endpoint', ['name', 'endpoint']
)

latency_seconds_summary = Summary('latency_seconds_summary', 'Request process latency summary', ['name'])
endpoint_latency_seconds_summary = Summary(
'endpoint_latency_seconds_summary', 'Request process latency summary of each endpoint', ['name', 'endpoint']
)


def enable_moniter(app, max_observation, name):

# Define middleware to collect metrics
class RequestMetricsMiddleware(BaseHTTPMiddleware):
"""
Middleware to process requests.
"""
async def dispatch(self, request, call_next):
path = request.scope.get('path')
is_req = path != '/metrics'

if not is_req:
try:
response = await call_next(request)
return response
except Exception as e:
raise e

begin = time.time()
requests_total.labels(name).inc()
endpoint_requests_total.labels(name, path).inc()
try:
response = await call_next(request)
if response.status_code / 100 < 4:
requests_success_total.labels(name).inc()
endpoint_requests_success_total.labels(name, path).inc()
end = time.time()
if path in latencies:
latencies[path].append(end - begin)
latencies[path] = latencies[path][-max_observation:]
else:
latencies[path] = [end - begin]
latencies['all'].append(end - begin)
latencies['all'] = latencies['all'][-max_observation:]
latency_seconds_histogram.labels(name).observe(end - begin)
endpoint_latency_seconds_histogram.labels(name, path).observe(end - begin)
latency_seconds_summary.labels(name).observe(end - begin)
endpoint_latency_seconds_summary.labels(name, path).observe(end - begin)
return response
else:
requests_failed_total.labels(name).inc()
endpoint_requests_failed_total.labels(name, path).inc()
except Exception as e:
requests_failed_total.labels(name).inc()
endpoint_requests_failed_total.labels(name, path).inc()
raise e

app.add_middleware(RequestMetricsMiddleware)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ uvicorn
towhee>=1.1.0
pymilvus
elasticsearch>=8.0.0
prometheus-client

0 comments on commit 2cfbe13

Please sign in to comment.