Java HTTP 集成
Telemetry 不发布本机 Java SDK。当 Java 或 JVM 服务需要结构化事件摄取或 SQL 查询时,通过一个应用程序拥有的 java.net.http.HttpClient 使用 HTTP API。
此边界将连接重用、超时、重试、序列化和故障策略保持在服务的控制之下。
创建一个共享客户端
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
HttpClient telemetryHttp = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(2))
.build();
在应用程序启动期间创建一次客户端。使用仅摄取 API 密钥进行摄取,使用单独的读取范围的密钥进行报告或查询自动化。
发送一个结构化事件
使用应用程序已批准的 JSON 库。此示例假设 eventJson 是从白名单对象序列化的,而不是从请求正文组装的:
只在应用结果已确定后发送。使用实际的规范化 routeTemplate、requestMethod、数值 statusCode 和 latencyMs,不要在生产环境复制虚构的成功状态。Map.of 的所有值必须非空。下面的尽力发送有超时限制,会捕获传输和序列化失败,并保留线程中断状态;不会重试,也不保证数据已存储。本地诊断不包含密钥、响应正文或异常文本。
诊断输出中的非受检异常也会被捕获。发送仍然同步执行,可能增加应用路径的延迟。
java.util.function.Consumer<String> deliveryDiagnostic = message -> {
try {
System.err.println(message);
} catch (RuntimeException diagnosticFailure) {
// Diagnostics must not replace the application outcome.
}
};
try {
String eventJson = objectMapper.writeValueAsString(Map.of(
"table", "api_request_completed",
"data", Map.of(
"event_id", eventId,
"route_template", routeTemplate,
"method", requestMethod,
"status_code", statusCode,
"status", statusCode >= 500 ? "failed" : "success",
"latency_ms", latencyMs,
"request_id", requestId,
"release", release
)
));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.telemetry.sh/log"))
.timeout(Duration.ofSeconds(3))
.header("Authorization", telemetryApiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(eventJson))
.build();
HttpResponse<Void> response = telemetryHttp.send(
request,
HttpResponse.BodyHandlers.discarding()
);
if (response.statusCode() < 200 || response.statusCode() >= 300) {
deliveryDiagnostic.accept("Telemetry delivery failed (non-2xx response).");
}
} catch (InterruptedException error) {
Thread.currentThread().interrupt();
deliveryDiagnostic.accept("Telemetry delivery interrupted.");
} catch (java.io.IOException | RuntimeException error) {
deliveryDiagnostic.accept("Telemetry delivery failed (transport, serialization or configuration error).");
}
使用路由模板和受控错误类别。请勿序列化标头、cookie、凭据、请求正文、SQL 参数、堆栈跟踪、提示、生成的内容或不受限制的异常消息。
运行SQL
使用读取范围的密钥将包含 query 的 JSON 正文发布到 https://api.telemetry.sh/query:
String queryJson = objectMapper.writeValueAsString(Map.of(
"query", """
SELECT route_template, COUNT(*) AS requests
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY route_template
ORDER BY requests DESC
"""
));
HttpRequest queryRequest = HttpRequest.newBuilder()
.uri(URI.create("https://api.telemetry.sh/query"))
.timeout(Duration.ofSeconds(15))
.header("Authorization", telemetryReadApiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(queryJson))
.build();
检查HTTP状态以及响应status、data和key_order字段。将空结果视为有效状态而不是解析失败。
失败和重试策略
仅重试有限的瞬时故障,例如连接错误、429、502、503 和 504。使用带有抖动的指数退避,限制运行时间,并在尝试中保留相同的 event_id。请勿重试未更改的 400、401 或 403 响应。
对于普通的产品分析,遥测失败不应取代完整的客户响应。如果计费或批准的审计事件必须持久,请在与业务状态相同的事务中写入发件箱记录,并从工作人员处交付。
验证集成
发送受控的成功、失败、重试和超时装置,然后检查最近的行:
SELECT timestamp_utc, event_id, route_template, status, latency_ms
FROM api_request_completed
ORDER BY timestamp_utc DESC
LIMIT 20;
确认事件粒度、表名称、字段类型、单位、UTC 时间和隐私边界。在将交付置于高流量路径上之前,测试 Telemetry 超时和进程关闭。
继续使用 Spring Boot 集成、日志API、速率限制和错误 和 事件传递和幂等性。