You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在tracing宏中记录带追踪的错误且不设置err字段?

问题:在tracing中记录错误但不设置索引用的err字段?

我在处理函数里有验证API密钥的步骤,密钥无效时原本会记录错误,导致Datadog里有大量错误噪音。我想把认证失败只标记为警告而非错误,所以手动处理了认证错误用warn!宏,还从instrument过程宏里移除了err字段。

现在认证失败在Datadog里显示正常的绿色,但名称有效性检查这类真正应该失败的场景虽然显示红色,却没有错误日志。看起来移除err字段后,所有错误都不会被记录了。

有没有办法在tracing宏里记录错误,但不设置用于索引的err字段?

我的代码:

#[instrument(
    name = "ControlPlane.global.create",
    fields(index_name, project, environment),
    skip_all
)]
async fn create(
    state: State<GlobalAppState>,
    api_key: APIKey,
    headers: HeaderMap,
    index: LoggingJson<GlobalCreateIndexRequest>,
) -> Result<(StatusCode, Json<GlobalIndexMetadata>), ServerError> {
    let project_id = match authenticate(state.clone(), &api_key).await {
        Ok(id) => id,
        Err(e) => {
            let log_message = format!(
                "Authentication error in ControlPlane.global.create: code={:?}, message={:?}",
                e.error.code, e.error.message
            );
            if e.error.code == ErrorCode::Unauthenticated {
                warn!(log_message);
            } else {
                error!(log_message);
            }
            return Err(e);
        }
    };

    let name = index.0.name.as_str();

    if let Err(e) = is_valid_resource_name(name) {
        let error_message = format!("Invalid index name: {:?}", e);
        error!(error_message);
        
        record!(
            "error" => &format!("{:?}", e)
        );
        return Err(e.into());
    }

<other parts of the handler>

解决方案

可以通过两种方式实现需求,避开Datadog对err字段的索引逻辑,同时保留必要的错误日志:

1. 自定义错误字段名,不使用默认的err

直接在error!宏里用自定义字段记录错误详情,避开err这个被Datadog用作索引的字段名,比如用error_details:

if let Err(e) = is_valid_resource_name(name) {
    let error_msg = format!("Invalid index name: {:?}", e);
    // 用自定义字段记录错误,不触发Datadog的err索引逻辑
    error!(message = %error_msg, error_details = ?e);
    return Err(e.into());
}

这样既会输出完整的错误日志,又不会让Datadog把这类错误归类到索引的错误统计里,同时能保留错误的具体信息。

2. 保留instrument的err字段,仅清除认证失败的字段值

如果想继续用instrument的自动错误注入,只需要在认证失败时手动清除err字段,其他错误正常保留:

#[instrument(
    name = "ControlPlane.global.create",
    fields(index_name, project, environment, err), // 重新添加err字段
    skip_all
)]
async fn create(...) -> Result<...> {
    let project_id = match authenticate(state.clone(), &api_key).await {
        Ok(id) => id,
        Err(e) => {
            let log_message = format!(
                "Authentication error in ControlPlane.global.create: code={:?}, message={:?}",
                e.error.code, e.error.message
            );
            if e.error.code == ErrorCode::Unauthenticated {
                warn!(log_message);
                // 手动清空err字段,避免被Datadog索引
                tracing::field::Empty.record(&tracing::info_span!("err"), &());
            } else {
                error!(log_message);
            }
            return Err(e);
        }
    };

    // 名称验证错误无需额外处理,instrument会自动填充err字段
    if let Err(e) = is_valid_resource_name(name) {
        error!("Invalid index name: {:?}", e);
        return Err(e.into());
    }
    // ...其他逻辑
}

这种方式下,只有非认证类的错误会被Datadog索引统计,认证失败的警告不会产生错误噪音。

关键提示

  • tracing的instrument宏默认会在函数返回Err时自动填充err字段,移除该字段后就不会自动记录错误信息,必须手动在error!宏里补充详情。
  • 核心是避开err这个字段名,或者在不需要索引的场景下手动清空它,就能实现“记录错误但不触发索引”的效果。

内容的提问来源于stack exchange,提问作者Aviral Srivastava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:47:28