def METHOD_NAME(
    user: User | RpcUser | None,
    api_key: ApiKey | None = None,
    ip_address: str | None = None,
    transaction_id: int | str | None = None,
    logger: Logger | None = None,
    organization: Organization | RpcOrganization | None = None,
    organization_id: int | None = None,
    **kwargs: Any,
) -> AuditLogEntry:
    if organization:
        assert organization_id is None
        organization_id = organization.id
    entry = AuditLogEntry(
        actor_id=user.id if user else None,
        actor_key=api_key,
        ip_address=ip_address,
        organization_id=organization_id,
        **kwargs,
    )
    # Only create a real AuditLogEntry record if we are passing an event type
    # otherwise, we want to still log to our actual logging
    if entry.event is not None:
        log_service.record_audit_log(event=entry.as_event())
    if entry.event == audit_log.get_event_id("ORG_REMOVE"):
        _create_org_delete_log(entry)
    elif entry.event == audit_log.get_event_id(
        "PROJECT_REMOVE"
    ) or entry.event == audit_log.get_event_id("PROJECT_REMOVE_WITH_ORIGIN"):
        _create_project_delete_log(entry)
    elif entry.event == audit_log.get_event_id("TEAM_REMOVE"):
        _create_team_delete_log(entry)
    extra = {
        "ip_address": entry.ip_address,
        "organization_id": entry.organization_id,
        "object_id": entry.target_object,
        "entry_id": entry.id,
        "actor_label": entry.actor_label,
    }
    if entry.actor_id:
        extra["actor_id"] = entry.actor_id
    if entry.actor_key_id:
        extra["actor_key_id"] = entry.actor_key_id
    if transaction_id is not None:
        extra["transaction_id"] = transaction_id
    if logger:
        # Only use the api_name for the logger message when the entry
        # is a real AuditLogEntry record
        if entry.event is not None:
            logger.info(audit_log.get(entry.event).api_name, extra=extra)
        else:
            logger.info(entry, extra=extra)
    return entry