我想实现一个自定义接收器,在其中创建了一个存根调用函数,该函数仅将接收到的数据记录到任务日志文件中(如下所示)。
package io.name.package;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
public class AlertSink extends RichSinkFunction<Alert> {
Logger LOG = LoggerFactory.getLogger(AlertSink.class);
@Override
public void invoke(Alert alert, Context context) throws Exception {
LOG.info("Invoking sink for alert: ", alert.toString());
}
}
我已经配置了数据流,如下所示。
DataStream<Alert> result = filteredMetrics
.keyBy(
new KeySelector<Tuple7<String, String, String, String, String, String, Object>, Tuple3<String, String, String>>() {
@Override
public Tuple3<String, String, String> getKey(Tuple7<String, String, String, String, String, String, Object> in) throws Exception {
return Tuple3.of(in.f0, in.f1, in.f2);
}
})
.window(SlidingProcessingTimeWindows.of(Time.seconds(10), Time.seconds(5)))
.process(new ThresholdEvaluator());
result.addSink(new AlertSink());
当我检查日志时,我看到接收器已被调用但显示空字符串。 ThresholdEvaluator发出警报,但显示非空字符串。
2020-08-05 19:38:16,638 INFO io.name.package.AlertSink - Invoking sink for alert:
2020-08-05 19:38:16,638 INFO io.name.package.ThresholdEvaluator - Alert: {"thresholdID":"123123123","grouping":"svc-platform-5445135-production-graph-service-account-toke644zm","period":"5m","isActive":true,"status":"new","firstSeen":1596656296638,"lastSeen":1596656296638,"count":1}
2020-08-05 19:38:16,640 INFO io.name.package.AlertSink - Invoking sink for alert:
2020-08-05 19:38:16,640 INFO io.name.package.ThresholdEvaluator - Alert: {"thresholdID":"123123123","grouping":"svc-platform-5445135-staging-input-service-account-token-q57xf","period":"5m","isActive":true,"status":"new","firstSeen":1596656296640,"lastSeen":1596656296640,"count":1}
2020-08-05 19:38:16,643 INFO io.name.package.AlertSink - Invoking sink for alert:
2020-08-05 19:38:16,643 INFO io.name.package.ThresholdEvaluator - Alert: {"thresholdID":"123123123","grouping":"svc-platform-5445135-restructure-repo-cmi-service-account-k76cd","period":"5m","isActive":true,"status":"new","firstSeen":1596656296643,"lastSeen":1596656296643,"count":1}
2020-08-05 19:38:16,646 INFO io.name.package.AlertSink - Invoking sink for alert:
2020-08-05 19:38:16,646 INFO io.name.package.ThresholdEvaluator - Alert: {"thresholdID":"123123123","grouping":"svc-integrations-14361530-demo-slack-token","period":"5m","isActive":true,"status":"new","firstSeen":1596656296645,"lastSeen":1596656296645,"count":1}
我在这里想念东西吗?
我还尝试在ThresholdEvaluator和addSink运算符之间添加映射函数。 MapFunction似乎可以正常接收Alert对象,但不能接收AlertSink。
result.map(new MapFunction<Alert, Alert>() {
@Override
public Alert map(Alert value) {
LOG.info(value.toString());
return value;
}
}).addSink(new AlertSink());
(使用其他日志更新)
答案 0 :(得分:1)
原因是日志输出没有用于插入值的占位符-正确的语法是
LOG.info("Invoking sink for alert: {}", alert.toString());
此与
之间的区别LOG.info("Invoking sink for alert: " + alert.toString());
是在后一种情况下,无论日志级别如何,字符串连接都会每次发生;在第一种情况下,如果仅日志级别至少为INFO
,它将对值进行插值。