info()

Returns a snapshot of the pool connection statistics. Internally delegates to SyncPoolClient.connection_stats() / AsyncPoolClient.connection_stats().

Each entry of the returned list describes one live pool connection with

  • target server (hostname/port)

  • auto-fetched server_info metadata (product version, platform, …) — populated right after login via krn.GetServerInfoEx

  • observability data: connected_at, last_call_at, call_count

  • stable connection UUID (connection_id) for logging and correlation

Multiple connections to the same host appear as separate entries. This is by design — you see per socket how often it was used and when last. Aggregation by (hostname, port) or product_version is up to the caller.

1. Signature

  • Sync

  • Async

ecm.system.info() -> list[ConnectionStats]
ecm.system.info() -> list[ConnectionStats]

Note: the async client exposes the method as synchronous — the data lives in the pool process-locally, no network I/O is performed.

2. Parameters

None.

3. Return value

A list of ConnectionStats copies. The list is empty until the pool has created its first connection (which happens lazily on the first execute() call).

The entries are independent snapshots — mutating them does not affect the pool’s internal state.

3.1. Fields of ConnectionStats

Field Type Description

connection_id

uuid.UUID

Stable identity of the connection, assigned at creation and kept until invalidation.

hostname

str

Target server hostname.

port

int

Target server TCP port.

server_info

RpcServerInfo | None

Snapshot of server metadata taken when the connection was created. None if the auto-fetch failed.

connected_at

datetime

Timestamp when the login completed and the connection joined the pool.

last_call_at

datetime | None

Timestamp of the most recent user-initiated execute() call. None until the first call.

call_count

int

Number of user-initiated execute() calls on this connection. Session-setup calls (SessionAttach, SessionPropertiesSet, SessionLogin, GetServerInfoEx) are not counted.

4. Examples

  • Sync

  • Async

stats = ecm.system.info()
for s in stats:
    version = s.server_info.product_version if s.server_info else "?"
    print(
        f"{s.hostname}:{s.port} v={version} "
        f"calls={s.call_count} last={s.last_call_at} id={s.connection_id}"
    )
stats = ecm.system.info()   # no await — process-local data
for s in stats:
    version = s.server_info.product_version if s.server_info else "?"
    print(
        f"{s.hostname}:{s.port} v={version} "
        f"calls={s.call_count} last={s.last_call_at} id={s.connection_id}"
    )

4.2. Aggregate by host

from collections import defaultdict

calls_by_host: dict[tuple[str, int], int] = defaultdict(int)
versions_by_host: dict[tuple[str, int], set[str]] = defaultdict(set)

for s in ecm.system.info():
    key = (s.hostname, s.port)
    calls_by_host[key] += s.call_count
    if s.server_info:
        versions_by_host[key].add(s.server_info.product_version)

for host, port in calls_by_host:
    print(f"{host}:{port} calls={calls_by_host[(host, port)]} versions={versions_by_host[(host, port)]}")

4.3. Assert a minimum server version across all hosts

required_major = 12
outdated = [
    (s.hostname, s.port, s.server_info.product_version)
    for s in ecm.system.info()
    if s.server_info and s.server_info.product_version_major < required_major
]
if outdated:
    raise RuntimeError(f"Found servers below v{required_major}.0: {outdated}")

5. Important notes

  • info() performs no RPC call. All data is already available process-locally on the pool. The method is cheap and safe to poll from dashboards or health checks.

  • Entries disappear automatically when a connection is invalidated (e.g. after a network error). A connection no longer listed here was dropped by the pool.

  • info() is synchronous on the async client — no await required. This is intentional.

6. See also