2

我正在构建一个 Dataflow 管道来处理 Stackdriver 日志,从 Pub/Sub 读取数据并将结果写入 BigQuery。当我从 Pub/Sub 读取时,我得到LogEntry对象的 JSON 字符串,但我真正感兴趣的是protoPayload.line包含用户日志消息的记录。为了得到那些我需要解析LogEntryJSON 对象,我发现了一个两年前的谷歌示例如何做到这一点:

import com.google.api.client.json.JsonParser;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.logging.model.LogEntry;

try {
    JsonParser parser = new JacksonFactory().createJsonParser(entry);
    LogEntry logEntry = parser.parse(LogEntry.class);
    logString = logEntry.getTextPayload();
}
catch (IOException e) {
    LOG.error("IOException parsing entry: " + e.getMessage());
}
catch(NullPointerException e) {
    LOG.error("NullPointerException parsing entry: " + e.getMessage());
}

不幸的是,这对我不起作用,logEntry.getTextPayload()回报null。我什至不确定它是否应该工作,因为com.google.api.services.logging谷歌云文档中没有提到任何库,当前的日志库似乎是google-cloud-logging

那么,如果有人能提出解析LogEntry对象的正确或最简单的方法是什么?

4

1 回答 1

1

我最终LogEntry使用 gson 库手动解析 JSON,特别是使用树遍历方法。这是一个小片段:

static class ProcessLogMessages extends DoFn<String, String> {
    @ProcessElement
    public void processElement(ProcessContext c) {
        String entry = c.element();

        JsonParser parser = new JsonParser();
        JsonElement element = parser.parse(entry);
        if (element.isJsonNull()) {
            return;
        }
        JsonObject root = element.getAsJsonObject();
        JsonArray lines = root.get("protoPayload").getAsJsonObject().get("line").getAsJsonArray();
        for (int i = 0; i < lines.size(); i++) {
            JsonObject line = lines.get(i).getAsJsonObject();
            String logMessage = line.get("logMessage").getAsString();

            // Do what you need with the logMessage here
            c.output(logMessage);
        }
    }
}

这很简单,对我来说效果很好,因为我protoPayload.line.logMessage只对对象感兴趣。LogEntry但我想如果您需要使用许多属性,这不是解析对象的理想方式。

于 2017-10-12T10:31:25.613 回答