Add dedicated class for metrics. Count logins and new chats

This commit is contained in:
nojaf 2025-05-15 11:30:58 +02:00
parent 6d93afc405
commit d0973ab060
No known key found for this signature in database
GPG Key ID: 0D4F7C9647A97904
4 changed files with 38 additions and 16 deletions

View File

@ -31,6 +31,7 @@ from open_webui.env import (
WEBUI_AUTH_SIGNOUT_REDIRECT_URL, WEBUI_AUTH_SIGNOUT_REDIRECT_URL,
SRC_LOG_LEVELS, SRC_LOG_LEVELS,
) )
from open_webui.utils.telemetry import metrics
from fastapi import APIRouter, Depends, HTTPException, Request, status from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi.responses import RedirectResponse, Response from fastapi.responses import RedirectResponse, Response
from open_webui.config import OPENID_PROVIDER_URL, ENABLE_OAUTH_SIGNUP, ENABLE_LDAP from open_webui.config import OPENID_PROVIDER_URL, ENABLE_OAUTH_SIGNUP, ENABLE_LDAP
@ -300,6 +301,9 @@ async def ldap_auth(request: Request, response: Response, form_data: LdapForm):
user = Auths.authenticate_user_by_trusted_header(email) user = Auths.authenticate_user_by_trusted_header(email)
if user: if user:
if metrics.telemetry_metrics is not None:
metrics.telemetry_metrics.track_user_login(user.id, user.email)
expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN) expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN)
expires_at = None expires_at = None
if expires_delta: if expires_delta:
@ -397,8 +401,8 @@ async def signin(request: Request, response: Response, form_data: SigninForm):
user = Auths.authenticate_user(form_data.email.lower(), form_data.password) user = Auths.authenticate_user(form_data.email.lower(), form_data.password)
if user: if user:
if setup.login_counter is not None: if metrics.telemetry_metrics is not None:
setup.login_counter.add(1, {"method": "regular"}) metrics.telemetry_metrics.track_user_login(user.id, user.email)
expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN) expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN)
expires_at = None expires_at = None

View File

@ -23,6 +23,7 @@ from pydantic import BaseModel
from open_webui.utils.auth import get_admin_user, get_verified_user from open_webui.utils.auth import get_admin_user, get_verified_user
from open_webui.utils.access_control import has_permission from open_webui.utils.access_control import has_permission
from open_webui.utils.telemetry import metrics
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["MODELS"]) log.setLevel(SRC_LOG_LEVELS["MODELS"])
@ -99,6 +100,8 @@ async def get_user_chat_list_by_user_id(
async def create_new_chat(form_data: ChatForm, user=Depends(get_verified_user)): async def create_new_chat(form_data: ChatForm, user=Depends(get_verified_user)):
try: try:
chat = Chats.insert_new_chat(user.id, form_data) chat = Chats.insert_new_chat(user.id, form_data)
if metrics.telemetry_metrics is not None:
metrics.telemetry_metrics.track_user_request(user.id)
return ChatResponse(**chat.model_dump()) return ChatResponse(**chat.model_dump())
except Exception as e: except Exception as e:
log.exception(e) log.exception(e)

View File

@ -0,0 +1,27 @@
from typing import Optional
class TelemetryMetrics:
def __init__(self, meter):
self.login_counter = meter.create_counter(
"user_login_total", description="Total number of user logins"
)
self.user_request_counter = meter.create_counter(
"user_request_total", description="Total number of user requests"
)
def track_user_login(self, user_id: str, email: str):
self.login_counter.add(
1, {"method": "regular", "user_id": user_id, "email": email}
)
def track_user_request(self, user_id: str):
self.user_request_counter.add(1, {"user_id": user_id})
telemetry_metrics: Optional[TelemetryMetrics] = None
def initialize_telemetry_metrics(meter):
global telemetry_metrics
telemetry_metrics = TelemetryMetrics(meter)

View File

@ -1,4 +1,5 @@
from fastapi import FastAPI from fastapi import FastAPI
from open_webui.utils.telemetry.metrics import initialize_telemetry_metrics
from opentelemetry import trace, metrics from opentelemetry import trace, metrics
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
@ -14,10 +15,6 @@ from open_webui.utils.telemetry.exporters import LazyBatchSpanProcessor
from open_webui.utils.telemetry.instrumentors import Instrumentor from open_webui.utils.telemetry.instrumentors import Instrumentor
from open_webui.env import OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT from open_webui.env import OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT
meter = None
login_counter = None
active_sessions_gauge = None
def setup(app: FastAPI, db_engine: Engine): def setup(app: FastAPI, db_engine: Engine):
resource = Resource.create(attributes={SERVICE_NAME: OTEL_SERVICE_NAME}) resource = Resource.create(attributes={SERVICE_NAME: OTEL_SERVICE_NAME})
@ -41,14 +38,5 @@ def setup(app: FastAPI, db_engine: Engine):
) )
meter_provider = MeterProvider(resource=resource, metric_readers=[reader]) meter_provider = MeterProvider(resource=resource, metric_readers=[reader])
metrics.set_meter_provider(meter_provider) metrics.set_meter_provider(meter_provider)
global meter, login_counter, active_sessions_gauge
meter = metrics.get_meter(OTEL_SERVICE_NAME) meter = metrics.get_meter(OTEL_SERVICE_NAME)
initialize_telemetry_metrics(meter)
login_counter = meter.create_counter(
"user_login_total", description="Total number of user logins"
)
active_sessions_gauge = meter.create_gauge(
"active.sessions", description="Number of currently active user sessions"
)