简体   繁体   English

用403写入Azure的Log Analytics Data Collector API返回。昨天工作良好

[英]Writes to Azure's Log Analytics Data Collector API return with 403. Worked fine yesterday

The following code uses com.google.code.gson.gson:2.8.5 and org.asynchttpclient.async-http-client:2.5.2 to send JSONs to Azure's Log Analytics. 以下代码使用com.google.code.gson.gson:2.8.5org.asynchttpclient.async-http-client:2.5.2将JSON发送到Azure的Log Analytics。 It worked fine until yesterday midnight, but then suddenly started returning HTTP 403 responses. 直到昨天午夜,它都工作正常,但随后突然开始返回HTTP 403响应。 What went wrong? 什么地方出了错?

public class LogAnalyticsSender {

    private static final Charset    UTF8            = Charset.forName("UTF-8");
    private static final String     HMAC_SHA256_ALG = "HmacSHA256";

    static String createAuthorization(String workspaceId, String key, int contentLength, String rfc1123Date) {
        try {
            // Documentation: https://docs.microsoft.com/en-us/rest/api/loganalytics/create-request
            String signature = String.format("POST\n%d\napplication/json\nx-ms-date:%s\n/api/logs", contentLength, rfc1123Date);
            Mac mac = Mac.getInstance(HMAC_SHA256_ALG);
            mac.init(new SecretKeySpec(DatatypeConverter.parseBase64Binary(key), HMAC_SHA256_ALG));
            String hmac = DatatypeConverter.printBase64Binary(mac.doFinal(signature.getBytes(UTF8)));
            return String.format("SharedKey %s:%s", workspaceId, hmac);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }

    final SslEngineFactory          defaultSslEngineFactory = (configuration, peerHost, peerPort) -> {
                                                                try {
                                                                    SSLContext sslCtx = SSLContext.getDefault();
                                                                    SSLEngine sslEngine = sslCtx.createSSLEngine(peerHost, peerPort);
                                                                    sslEngine.setUseClientMode(true);
                                                                    return sslEngine;
                                                                } catch (NoSuchAlgorithmException e) {
                                                                    throw new RuntimeException(e);
                                                                }
                                                            };
    final String                    key;
    final String                    workspace;
    final Gson                      gson;
    final DefaultAsyncHttpClient    httpClient;

    public LogAnalyticsSender(String workspaceId, String base64Key, int maxConnections) {
        DefaultAsyncHttpClientConfig config = new DefaultAsyncHttpClientConfig.Builder().setMaxConnections(maxConnections)
                .setThreadPoolName("LogAnalyticsSender").setSslEngineFactory(this.defaultSslEngineFactory).build();
        this.key = base64Key;
        this.workspace = workspaceId;
        this.gson = new GsonBuilder().create();
        this.httpClient = new DefaultAsyncHttpClient(config);
    }

    public CompletableFuture<Response> sendPojo(Object o, String logType) {
        String json = this.gson.toJson(o);
        return sendRawJson(json, logType);
    }

    public CompletableFuture<Response> sendPojo(JsonElement element, String logType) {
        String json = this.gson.toJson(element);
        return sendRawJson(json, logType);
    }

    public CompletableFuture<Response> sendRawJson(String rawJson, String logType) {
        int bodyLength = rawJson.getBytes(UTF8).length;
        String nowRfc1123 = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC));
        String createAuthorization = createAuthorization(this.workspace, this.key, bodyLength, nowRfc1123);
        return this.httpClient.preparePost("https://" + this.workspace + ".ods.opinsights.azure.com/api/logs?api-version=2016-04-01").setBody(rawJson)
                .addHeader("Authorization", createAuthorization).addHeader("Content-Type", "application/json").addHeader("Log-Type", logType)
                .addHeader("x-ms-date", nowRfc1123).execute().toCompletableFuture();
    }

    public void shutdown() {
        this.httpClient.close();
    }
}

(answering my own question) (回答我自己的问题)

The issue occurred when the date switched from Jul 31 to Aug 1. It turns out that Java's DateTimeFormatter.RFC_1123_DATE_TIME writes the day-of-month as a single digit, and the Log Analytics API doesn't like that. 当日期从7月31日更改为8月1日时发生了问题。事实证明,Java的DateTimeFormatter.RFC_1123_DATE_TIME将一个月的DateTimeFormatter.RFC_1123_DATE_TIME写为一个数字,而Log Analytics API则不这样。

The solution was to replace the regular RFC 1123 DateTimeFormatter with a pattern that uses two digits: 解决方案是将常规RFC 1123 DateTimeFormatter替换为使用两位数字的模式:

DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss O")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 即使使用错误的 http 代码 403. 404 等,也可以使用 HttpUrlConnection 检索数据 - Retrieve data with HttpUrlConnection even with bad http codes 403. 404, etc Spring Data 使用昨天的日期更新实体 - Spring Data update entity with yesterday's date Azure计费API返回403 - Azure Billing API returning 403 如何在获取403时获取响应正文。Java - How to get a response body while getting 403. Java 使用OAuth2.0客户端凭据对Azure Log Analytics Api进行身份验证 - Authenticate to Azure Log Analytics Api using OAuth2.0 Client credentials 在logback上恢复已删除的日志文件在Windows上运行良好,但在Linux SUSE上无效 - Recovery deleted log files at logback worked fine on Windows but didn't work on Linux SUSE 尝试通过 REST API 访问 Azure 数据湖存储 Gen 2 中的文件系统时出现 403 错误 - 403 error when trying to access file system in Azure data lake storage Gen 2 via REST API HTTP Post 到 API 返回 403 FORBIDDEN - HTTP Post to API return 403 FORBIDDEN KeyListener 根本不起作用,但我的代码在我朋友的计算机上运行良好 - KeyListener doesn't work at all but my code worked fine on my friend's computer GAE部署了“ RemoteIOException:读取超时”,昨天已完成 - GAE deploy “RemoteIOException: Read timed out”, worked yesterday
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM