pgAdmin 8.4 adds structured logs and configurable preferences
JSON logging and file-driven preference management make pgAdmin easier to operate as a shared application. Version 8.4 also corrects several boundaries between its interface and PostgreSQL.
A graphical database client also needs configuration that survives deployment and logs that another program can interpret. The March 8 announcement of pgAdmin 4 version 8.4 addresses both requirements. It adds JSON logging and preference customization through a configuration file. These are useful changes for treating the administration tool as an application with its own operating requirements.
The announcement also includes a security correction for unsafe deserialization and authenticated remote code execution, identified as CVE-2024-2044. That makes the release relevant beyond its new configuration options. pgAdmin is a separate application in the PostgreSQL environment, and its update has a different scope from an update to the database server.
I value PostgreSQL's predictable administration model, particularly when a tool exposes the database's behavior clearly. An administration interface should also make its own behavior inspectable. Structured logs and explicit preference management help distinguish what the client is doing from what the server has accepted or rejected.
JSON applies to the application's logging
The configuration shipped with version 8.4 defines a JSON_LOGGER option, which defaults to False. It also defines separate JSON format mappings for console and file output. Each default mapping contains time, message and level, associated with the logging record's timestamp, message and level name.
The setting can be expressed in Python configuration as follows. It selects the new format without changing the log-level settings.
JSON_LOGGER = True
This concerns pgAdmin's own logging. It is not a PostgreSQL server setting and does not convert database query results into JSON. Keeping the scope explicit matters when collecting records from several processes. A database connection failure reported by pgAdmin and a message produced by the database server have different origins even if they reach the same log collection system.
Separate console and file mappings let the application describe those outputs independently. The source also retains the ordinary text format definitions, so JSON is a configurable choice. Existing text-oriented collection has a migration decision to make, while a deployment that expects structured records can select the new representation at the producer.
There is a useful distinction between format and verbosity. In this version, CONSOLE_LOG_LEVEL and FILE_LOG_LEVEL both default to logging.WARNING. Enabling JSON changes the representation of emitted records. It does not, by itself, request informational or debug messages. A collection pipeline that receives no low-level detail should therefore distinguish the format option from the level options.
Preferences can be supplied outside the dialog
The versioned preference documentation describes management through setup.py as well as the Preferences dialog. Its get-prefs command lists available preferences. The set-prefs command associates values with a named user, and --input-file loads values from a JSON file. This gives configuration a representation that can be reviewed outside a sequence of mouse interactions.
The documented JSON structure places preference keys under a preferences object. Keys identify the preference through colon-separated names. For example, the documentation includes the theme and the visibility of system objects.
{
"preferences": {
"browser:display:show_system_objects": true,
"misc:themes:theme": "dark"
}
}
This representation is distinct from the Python logging configuration. The preference file describes client behavior associated with a user. The logging flag belongs to the application's configuration. Combining those concepts into one undifferentiated configuration step would hide which settings affect a particular user and which affect the running application.
The command documentation also supports an authentication-source argument and says that internal authentication is the default when it is omitted. User identity therefore matters when applying preferences. The documentation requires using the Python interpreter normally used to run pgAdmin so that the necessary packages are available. The file is portable configuration data, but the command still runs within pgAdmin's installed environment.
I prefer an explicit representation for settings that affect how database work appears. A checked preference file can show whether system objects are visible or which theme is selected. That does not make every preference an infrastructure policy. It does make the chosen values available for inspection without reconstructing them from the dialog.
The database remains responsible for permissions
One correction in the announcement removes role checks from the dashboard when terminating a session or query. PostgreSQL now takes responsibility for deciding whether that operation is allowed. The change is useful because the server evaluates the actual database request. A client-side role assumption should not become a second, inconsistent interpretation of the server's permissions.
Other fixes concern representations that operators rely on. Nested composite types had missing dependency or dependent information. Schema Diff could generate unusable scripts for a table with a sequence. The release also corrects PasswordExecCommand behavior in server mode and during server import. These are specific ways an administration client can misdescribe or mishandle a database workflow even when the database itself behaves correctly.
The tagged release notes give March 7 as the release date, while the public PostgreSQL announcement is dated March 8. They list support for PostgreSQL 12 through 16 and bundled PostgreSQL utilities at version 16.1. Those separate version statements matter when interpreting an administration operation. The interface, the utility it launches and the server it connects to each have their own version, and this release changes the interface application.