Skip to content

Audit log: more ergonomic audit log call #8819

@david-crespo

Description

@david-crespo

Followup to #7339. Related to #8811.

Right now the audit log calls are a bit verbose and error-prone because they require two manual calls, and they coexist in a rather noisy way with the latency-tracking function call. This is the cleanest-looking one:

async fn project_create(
rqctx: RequestContext<ApiContext>,
new_project: TypedBody<params::ProjectCreate>,
) -> Result<HttpResponseCreated<Project>, HttpError> {
let apictx = rqctx.context();
let handler = async {
let opctx =
crate::context::op_context_for_external_api(&rqctx).await?;
let nexus = &apictx.context.nexus;
let audit = nexus.audit_log_entry_init(&opctx, &rqctx).await?;
let result = async {
let project = nexus
.project_create(&opctx, &new_project.into_inner())
.await?;
Ok(HttpResponseCreated(project.into()))
}
.await;
let _ =
nexus.audit_log_entry_complete(&opctx, &audit, &result).await;
result
};
apictx
.context
.external_latencies
.instrument_dropshot_handler(&rqctx, handler)
.await
}

Dropshot deliberately does not support middleware, which would let us do this kind of thing automatically outside of the handlers. Finding a more ergonomic and less noisy way of doing the audit logging and latency logging might require a declarative macro. Or maybe not.

Ideally we would be able to do both the audit log call and the latency tracking call in a single function that takes our inner handler function, and it uses trait constraints on the result type to extract an ID from it if it is present.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions