Skip to content

Commit

Permalink
Merge pull request #474 from ynput/preparation-for-user-metrics
Browse files Browse the repository at this point in the history
User activity monitoring
  • Loading branch information
martastain authored Jan 6, 2025
2 parents b3eb838 + f233cb4 commit 4a5788b
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 4 deletions.
5 changes: 5 additions & 0 deletions ayon_server/auth/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,14 @@ async def check(cls, token: str, request: Request | None) -> SessionModel | None
if remaining_ttl < ayonconfig.session_ttl - 120:
session.last_used = time.time()
await Redis.set(cls.ns, token, json_dumps(session.dict()))
await cls.on_extend(session)

return session

@classmethod
async def on_extend(cls, session: SessionModel) -> None:
pass

@classmethod
async def create(
cls,
Expand Down
8 changes: 7 additions & 1 deletion ayon_server/metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from .settings import SettingsOverrides, get_studio_settings_overrides
from .system import SystemMetricsData, system_metrics
from .traffic import TrafficStat, get_traffic_stats
from .users import UserCounts, get_user_counts
from .users import UserCounts, UserStat, get_user_counts, get_user_stats


def docfm(obj) -> str:
Expand Down Expand Up @@ -131,6 +131,7 @@ class Metrics(OPModel):
)

traffic_stats: list[TrafficStat] | None = Field(None, title="Traffic stats")
user_stats: list[UserStat] | None = Field(None, title="User stats")


METRICS_SNAPSHOT = {}
Expand Down Expand Up @@ -182,6 +183,11 @@ class Metrics(OPModel):
"getter": get_traffic_stats,
"ttl": 24,
},
{
"name": "user_stats",
"getter": get_user_stats,
"ttl": 24,
},
]


Expand Down
2 changes: 1 addition & 1 deletion ayon_server/metrics/traffic.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async def get_traffic_stats(
return None

result = []
query = "SELECT * FROM traffic_stats"
query = "SELECT * FROM traffic_stats ORDER BY date DESC limit 65"
async for row in Postgres.iterate(query):
date = row.get("date").strftime("%Y-%m-%d")
service = row.get("service")
Expand Down
32 changes: 32 additions & 0 deletions ayon_server/metrics/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from ayon_server.lib.postgres import Postgres
from ayon_server.types import Field, OPModel
from ayon_server.utils import get_nickname


class UserCounts(OPModel):
Expand All @@ -11,6 +12,11 @@ class UserCounts(OPModel):
managers: Annotated[int, Field(title="Manager users", example=8)] = 0


class UserStat(OPModel):
date: str
users: dict[str, str | None] # map active users to their pools


async def get_user_counts(
saturated: bool = False, system: bool = False
) -> UserCounts | None:
Expand All @@ -37,3 +43,29 @@ async def get_user_counts(
admins=row["admins"] or 0,
managers=row["managers"] or 0,
)


async def get_user_stats(
saturated: bool = False, system: bool = False
) -> list[UserStat] | None:
_ = saturated
if not system:
# Collect traffic stats only when we collect system metrics
return None

result = []
query = "SELECT date, users FROM user_stats ORDER BY date DESC limit 65"

async for row in Postgres.iterate(query):
date = row.get("date").strftime("%Y-%m-%d")
users = row.get("users", {})
if not users:
continue

if not saturated:
users = {get_nickname(u): pdata for u, pdata in users.items()}

stat = UserStat(date=date, users=users)
result.append(stat)

return result or None
5 changes: 3 additions & 2 deletions maintenance/tasks/push_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ async def stats_cleanup():
now = datetime.datetime.now()
begin = now - datetime.timedelta(days=60)

query = "DELETE FROM traffic_stats WHERE date < $1"
await Postgres().execute(query, begin)
for table in ["user_stats", "traffic_stats"]:
query = f"DELETE FROM {table} WHERE date < $1"
await Postgres().execute(query, begin)


class PushMetrics(StudioMaintenanceTask):
Expand Down
5 changes: 5 additions & 0 deletions schemas/schema.public.sql
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ CREATE TABLE IF NOT EXISTS public.traffic_stats(
PRIMARY KEY (date, service)
);

CREATE TABLE IF NOT EXISTS public.user_stats(
date DATE NOT NULL PRIMARY KEY,
users JSONB NOT NULL DEFAULT '{}'::JSONB
);


-- CREATE THE SITE ID
INSERT INTO config VALUES ('instanceId', to_jsonb(gen_random_uuid()::text)) ON CONFLICT DO NOTHING;
Expand Down

0 comments on commit 4a5788b

Please sign in to comment.