Skip to content

feat(db): label postgres connections and log audit readiness#1008

Open
pjb157 wants to merge 2 commits into
mainfrom
imparando/69eaab5e-a36f-4c43-aaa7-8adb2adb8310
Open

feat(db): label postgres connections and log audit readiness#1008
pjb157 wants to merge 2 commits into
mainfrom
imparando/69eaab5e-a36f-4c43-aaa7-8adb2adb8310

Conversation

@pjb157
Copy link
Copy Markdown
Contributor

@pjb157 pjb157 commented Apr 21, 2026

No description provided.

Copilot AI review requested due to automatic review settings April 21, 2026 14:47
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 21, 2026

Deploying control-layer with  Cloudflare Pages  Cloudflare Pages

Latest commit: d8ee035
Status: ✅  Deploy successful!
Preview URL: https://6fafefa0.control-layer.pages.dev
Branch Preview URL: https://imparando-69eaab5e-a36f-4c43.control-layer.pages.dev

View logs

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR labels PostgreSQL connections with a consistent application_name per component and adds startup logging to report whether PostgreSQL audit-related settings (pgAudit + connection logging) appear to be configured.

Changes:

  • Apply application_name to main, replica, and schema-scoped pools (main/fusillade/outlet).
  • Add a new db::audit module to encapsulate application-name constants and audit-readiness logging.
  • Log audit-readiness status for the main DB and for dedicated fusillade/outlet databases.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
dwctl/src/lib.rs Sets application_name on connect options for each pool and logs audit-readiness after migrations.
dwctl/src/db/mod.rs Exposes the new audit module.
dwctl/src/db/audit.rs Adds helpers/constants for labeling connections and inspecting/logging audit configuration.

Comment thread dwctl/src/db/mod.rs
//! dwctl::migrator().run(&pool).await?;
//! ```

pub mod audit;
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new audit module is exported publicly, but the module-level rustdoc above still lists only handlers/models/errors/embedded. Please update the "Modules" section to mention audit (or explain why it’s intentionally omitted) so the documentation matches the actual public API surface.

Copilot uses AI. Check for mistakes.
Comment thread dwctl/src/db/audit.rs
Comment on lines +3 to +11
pub const MAIN_APPLICATION_NAME: &str = "control-layer";
pub const FUSILLADE_APPLICATION_NAME: &str = "control-layer/fusillade";
pub const OUTLET_APPLICATION_NAME: &str = "control-layer/outlet";

pub fn with_application_name(options: PgConnectOptions, application_name: &str) -> PgConnectOptions {
options.application_name(application_name)
}

pub async fn log_postgres_audit_status(component: &str, pool: &PgPool) {
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dwctl::db::audit and its items are declared pub, but these constants/functions appear to be used only within this crate. Consider reducing visibility to pub(crate) (and/or adding rustdoc if the intent is to support external callers) to avoid unintentionally expanding the crate’s public API.

Suggested change
pub const MAIN_APPLICATION_NAME: &str = "control-layer";
pub const FUSILLADE_APPLICATION_NAME: &str = "control-layer/fusillade";
pub const OUTLET_APPLICATION_NAME: &str = "control-layer/outlet";
pub fn with_application_name(options: PgConnectOptions, application_name: &str) -> PgConnectOptions {
options.application_name(application_name)
}
pub async fn log_postgres_audit_status(component: &str, pool: &PgPool) {
pub(crate) const MAIN_APPLICATION_NAME: &str = "control-layer";
pub(crate) const FUSILLADE_APPLICATION_NAME: &str = "control-layer/fusillade";
pub(crate) const OUTLET_APPLICATION_NAME: &str = "control-layer/outlet";
pub(crate) fn with_application_name(options: PgConnectOptions, application_name: &str) -> PgConnectOptions {
options.application_name(application_name)
}
pub(crate) async fn log_postgres_audit_status(component: &str, pool: &PgPool) {

Copilot uses AI. Check for mistakes.
Comment thread dwctl/src/db/audit.rs
Comment on lines +11 to +66
pub async fn log_postgres_audit_status(component: &str, pool: &PgPool) {
let database_name: String = match sqlx::query_scalar("SELECT current_database()").fetch_one(pool).await {
Ok(name) => name,
Err(error) => {
tracing::warn!(component, error = %error, "Failed to inspect PostgreSQL audit settings");
return;
}
};

let extension_installed: bool = match sqlx::query_scalar("SELECT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pgaudit')")
.fetch_one(pool)
.await
{
Ok(installed) => installed,
Err(error) => {
tracing::warn!(
component,
database = %database_name,
error = %error,
"Failed to check whether pgAudit is installed"
);
return;
}
};

let shared_preload_libraries: Option<String> = match sqlx::query_scalar("SELECT current_setting('shared_preload_libraries', true)")
.fetch_one(pool)
.await
{
Ok(value) => value,
Err(error) => {
tracing::warn!(
component,
database = %database_name,
error = %error,
"Failed to read shared_preload_libraries"
);
return;
}
};
let pgaudit_log: Option<String> = match sqlx::query_scalar("SELECT current_setting('pgaudit.log', true)")
.fetch_one(pool)
.await
{
Ok(value) => value,
Err(error) => {
tracing::warn!(
component,
database = %database_name,
error = %error,
"Failed to read pgaudit.log"
);
return;
}
};
let log_connections: Option<String> = match sqlx::query_scalar("SELECT current_setting('log_connections', true)")
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log_postgres_audit_status performs multiple sequential round-trips (current_database + 4 current_setting/extension checks). Since this runs during startup, consider collapsing these into a single SELECT (e.g., selecting all settings/EXISTS in one query) to reduce latency and connection churn.

Copilot uses AI. Check for mistakes.
Comment thread dwctl/src/lib.rs
Comment on lines +807 to +813
db::audit::log_postgres_audit_status("control-layer", db_pools.write()).await;
match config.database.fusillade() {
config::ComponentDb::Schema { .. } => {
info!("Fusillade uses the main PostgreSQL database in schema mode; audit settings are inherited");
}
config::ComponentDb::Dedicated { .. } => {
db::audit::log_postgres_audit_status("control-layer/fusillade", fusillade_pools.write()).await;
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These component string literals duplicate the application-name constants in db::audit (e.g. MAIN_APPLICATION_NAME / FUSILLADE_APPLICATION_NAME). Using the constants here would avoid drift if the names change and keep labeling consistent.

Suggested change
db::audit::log_postgres_audit_status("control-layer", db_pools.write()).await;
match config.database.fusillade() {
config::ComponentDb::Schema { .. } => {
info!("Fusillade uses the main PostgreSQL database in schema mode; audit settings are inherited");
}
config::ComponentDb::Dedicated { .. } => {
db::audit::log_postgres_audit_status("control-layer/fusillade", fusillade_pools.write()).await;
db::audit::log_postgres_audit_status(db::audit::MAIN_APPLICATION_NAME, db_pools.write()).await;
match config.database.fusillade() {
config::ComponentDb::Schema { .. } => {
info!("Fusillade uses the main PostgreSQL database in schema mode; audit settings are inherited");
}
config::ComponentDb::Dedicated { .. } => {
db::audit::log_postgres_audit_status(
db::audit::FUSILLADE_APPLICATION_NAME,
fusillade_pools.write(),
)
.await;

Copilot uses AI. Check for mistakes.
Comment thread dwctl/src/lib.rs
info!("Outlet uses the main PostgreSQL database in schema mode; audit settings are inherited");
}
config::ComponentDb::Dedicated { .. } => {
db::audit::log_postgres_audit_status("control-layer/outlet", pools.write()).await;
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses a hard-coded component label ("control-layer/outlet") even though db::audit::OUTLET_APPLICATION_NAME already defines the same string. Prefer reusing the constant to avoid future mismatches.

Suggested change
db::audit::log_postgres_audit_status("control-layer/outlet", pools.write()).await;
db::audit::log_postgres_audit_status(db::audit::OUTLET_APPLICATION_NAME, pools.write()).await;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants