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

日志场景下如何将动态参数作为独立字符串传入String格式化器?

动态请求参数日志格式化问题

我想用String格式化器打印动态变化的请求参数日志,Request Id和Url是所有请求的公共参数,其他参数随请求变化。当前代码在传递参数时出现格式化错误,因为动态参数被作为数组整体传入,而非独立的字符串元素。

现有代码

MailService.java

static final LinkedHashMap<String , String> logMap = new LinkedHashMap<String , String>();

logMap.put("mailType", mailType);
logMap.put("projectId", projectId);

LogUtility.getDownstreamReqLog(LOGGER,jwtTokenProvider,url,logMap);

LogUtility.java

public static void getDownstreamReqLog(Logger log, JwtTokenProvider jwtTokenProvider, URI url,LinkedHashMap<String,String> logMap) {

    String message = " {" + BffConstants.REQUEST_ID_KEY + " = %s }" + " {" + BffConstants.REQUEST_URL + " = %s }";

    List<String> values = new ArrayList<>();

    String mapKeys = "";
    for (String key : logMap.keySet()) {
        mapKeys = mapKeys + " {" + key + " =%s }";
        values.add(logMap.get(key));
    }

    message = message + mapKeys;

    LogUtility.info(log, message,jwtTokenProvider.getRequestId(),url,values.toArray(new
   String[0]));
}

public static void info(Logger log, String message, Object... args) {
    log.info(getFormattedMessage(message, args));
}

private static String getFormattedMessage(String message, Object... args) {
    String formattedMessage = message;
    if (args != null && args.length > 0) {
        formattedMessage = String.format(message, args);
    }
    return formattedMessage;
}

当前问题

调用LogUtility.info时,传入的args数组结构错误:

[0] = "requestId"
[1] = "url"
[2] = String[2]  // 动态参数被作为单个数组元素传入,导致String.format匹配失败

期望的参数结构

[0] = "requestId"
[1] = "url"
[2] = "value1"
[3] = "value2"
// 动态参数逐个展开为独立元素

解决方案

不需要修改getFormattedMessage方法,只需在getDownstreamReqLog中把公共参数和动态参数合并成一个完整的数组再传入即可:

修改后的getDownstreamReqLog代码:

public static void getDownstreamReqLog(Logger log, JwtTokenProvider jwtTokenProvider, URI url, LinkedHashMap<String,String> logMap) {

    String message = " {" + BffConstants.REQUEST_ID_KEY + " = %s }" + " {" + BffConstants.REQUEST_URL + " = %s }";

    List<Object> allArgs = new ArrayList<>();
    // 添加公共参数到列表
    allArgs.add(jwtTokenProvider.getRequestId());
    allArgs.add(url);

    String mapKeys = "";
    for (String key : logMap.keySet()) {
        mapKeys = mapKeys + " {" + key + " =%s }";
        // 将动态参数值逐个加入列表
        allArgs.add(logMap.get(key));
    }

    message = message + mapKeys;

    // 将合并后的列表转为数组传入info方法
    LogUtility.info(log, message, allArgs.toArray(new Object[0]));
}

说明

  • 用ArrayList<Object>统一存放公共参数和动态参数,避免数组嵌套的问题
  • 最终通过toArray(new Object[0])将列表转为Object数组,完全匹配info方法的可变参数要求
  • 这样String.format就能正确将每个%s与对应的参数一一匹配,不会出现格式化错误

内容的提问来源于stack exchange,提问作者Sachin HR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 07:06:33