diff --git a/rcon/models.py b/rcon/models.py index 165529fde..43bf5e264 100644 --- a/rcon/models.py +++ b/rcon/models.py @@ -1,10 +1,11 @@ import logging import os import re +import sys from collections import defaultdict from contextlib import contextmanager from datetime import datetime, timezone -from typing import Any, Generator, List, Literal, Optional, Sequence, overload, TypedDict +from typing import Any, Generator, List, Literal, Optional, Sequence, overload import pydantic from sqlalchemy import TIMESTAMP, Enum, ForeignKey, String, create_engine, select, text, JSON @@ -73,6 +74,30 @@ _ENGINE = None +def _connection_name() -> str: + """ + Identify what application component is using the SQLAlchemy session. This can be helpful when inspecting the connections + in Postgres to identify the purpose of a connection. The connection name will be used as the application_name connection + property and show up in the pg_stat_activity table: + select * from pg_stat_activity; + + :return: str + """ + args = sys.argv + name = 'CRCon Generic' + if "manage.py" not in args[0]: + # stuff like daphne, gunicorn (backend) etc + name = args[0] + elif len(args) > 1 and args[1] != "": + # Take whatever argument we passed to manage.py (for Supervisor services, such as log_loop, etc) + name = args[1] + + name = (os.getenv("SERVER_NUMBER") or "") + name + # in the standard build (which we use in teh default docker setup) the name cannot exceed 63 chars (less than 64), + # see https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-APPLICATION-NAME + return name[:63] + + def get_engine(): global _ENGINE @@ -84,7 +109,7 @@ def get_engine(): logger.error(msg) raise ValueError(msg) - _ENGINE = create_engine(url, echo=False) + _ENGINE = create_engine(url, echo=False, connect_args={"application_name":_connection_name()}) return _ENGINE diff --git a/rconweb/rconweb/settings.py b/rconweb/rconweb/settings.py index e90afb597..71383c816 100644 --- a/rconweb/rconweb/settings.py +++ b/rconweb/rconweb/settings.py @@ -253,6 +253,9 @@ "HOST": db_info["HOST"], "PORT": db_info["PORT"], "NAME": db_info["NAME"], + "OPTIONS": { + "application_name": (os.getenv("SERVER_NUMBER") or "") + "Django", + } } }