task-78: 为所有外部调用增加耗时、重试、失败率和 payload 字节指标

新增 ExternalCallMetricsRecorder:通过 RestClient 拦截器统一记录
aiimage.external-call.duration(耗时)、aiimage.external-call.total
(失败率)、aiimage.external-call.payload.bytes(请求字节)与
aiimage.external-call.retry.total(重试次数);Coze/品牌检查/紫鸟
三个外部客户端全部接入,指标注册表缺失时静默降级,不改变调用语义。
This commit is contained in:
2026-08-30 22:01:02 +08:00
parent f1d1fe5c78
commit 4c70ca4101
10 changed files with 569 additions and 33 deletions
@@ -22,7 +22,7 @@ class AppearancePatentCozeClientTest {
new AppearancePatentProperties(),
new ObjectMapper(),
null,
new BrandCheckClient(new BrandCheckProperties())
new BrandCheckClient(new BrandCheckProperties(), null)
);
@Test
@@ -11,7 +11,7 @@ class BrandCheckClientTest {
@Test
void splitTitleTextSupportsCommonSeparatorsAndQuotes() {
BrandCheckClient client = new BrandCheckClient(new BrandCheckProperties());
BrandCheckClient client = new BrandCheckClient(new BrandCheckProperties(), null);
List<String> brands = client.splitTitleText("'阿凡达,任天堂' Disney、LEGO\nSony");
@@ -20,7 +20,7 @@ class BrandCheckClientTest {
@Test
void splitTitleTextDeduplicatesBlankValues() {
BrandCheckClient client = new BrandCheckClient(new BrandCheckProperties());
BrandCheckClient client = new BrandCheckClient(new BrandCheckProperties(), null);
List<String> brands = client.splitTitleText(" 任天堂, ,任天堂,Sony ");
@@ -127,7 +127,7 @@ class SimilarAsinCozeClientLoggingTest {
row.setTitle("T".repeat(5000));
row.setSku("SKU-SECRET");
rows.add(row);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null, null);
Method maskMethod = SimilarAsinCozeClient.class.getDeclaredMethod(
"maskCozeRequestBody", Map.class);
maskMethod.setAccessible(true);
@@ -38,7 +38,7 @@ class SimilarAsinCozeClientTest {
]
""", new TypeReference<>() {
});
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null, null);
Method method = SimilarAsinCozeClient.class.getDeclaredMethod(
"buildParameters", List.class, String.class, String.class, boolean.class);
@@ -71,7 +71,7 @@ class SimilarAsinCozeClientTest {
row.setPrice("8.50");
row.setTitle("Legacy title");
row.setSku("SKU-LEGACY");
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null, null);
Method method = SimilarAsinCozeClient.class.getDeclaredMethod(
"buildParameters", List.class, String.class, String.class, boolean.class);
@@ -102,7 +102,7 @@ class SimilarAsinCozeClientTest {
]
""", new TypeReference<>() {
});
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null, null);
Method method = SimilarAsinCozeClient.class.getDeclaredMethod(
"buildParameters", List.class, String.class, String.class, boolean.class);
@@ -128,7 +128,7 @@ class SimilarAsinCozeClientTest {
row.setUrl("https://m.media-amazon.com/images/I/main.jpg");
row.setUrls(List.of("https://cbu01.alicdn.com/img/ibank/fallback.jpg"));
row.setPrice("");
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null, null);
Method method = SimilarAsinCozeClient.class.getDeclaredMethod(
"buildParameters", List.class, String.class, String.class, boolean.class);
@@ -162,7 +162,7 @@ class SimilarAsinCozeClientTest {
]
""", new TypeReference<>() {
});
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null, null);
Method method = SimilarAsinCozeClient.class.getDeclaredMethod(
"buildParameters", List.class, String.class, String.class, boolean.class);
@@ -188,7 +188,7 @@ class SimilarAsinCozeClientTest {
SimilarAsinResultRowDto row = new SimilarAsinResultRowDto();
row.setAsin("B0CATEGORY1");
row.setTitle("Category test");
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null, null);
Method method = SimilarAsinCozeClient.class.getDeclaredMethod(
"buildParameters", List.class, String.class, String.class, boolean.class, boolean.class);
@@ -201,7 +201,7 @@ class SimilarAsinCozeClientTest {
@Test
void imageOnlyWorkflowOutputIsExtractedAndMergedByAsin() throws Exception {
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null);
SimilarAsinCozeClient client = new SimilarAsinCozeClient(new SimilarAsinProperties(), objectMapper, null, null);
String imageData = """
{"data":[{
"asin":"B0BQNHDP2F",