自定義回收metrics的source,及增加一個心跳heartbeat收集
#source主要配置
#自定義的類名
a1.sources.HeartBeat.type = org.apache.flume.source.MonitorCollectSource
#心跳採集間隔
a1.sources.HeartBeat.intervalMs = 60000
#ture採集監控數據,false不採集
a1.sources.HeartBeat.monitorStatus = true
#monitor回傳的地址,這裏需要與啓動agent時指定的端口相同
a1.sources.HeartBeat.monitorUrl = http://localhost:8080/metrics
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.flume.*;
import org.apache.flume.conf.Configurable;
import org.apache.flume.event.EventBuilder;
import org.apache.flume.instrumentation.SourceCounter;
import org.apache.flume.source.AbstractPollableSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MonitorCollectSource extends AbstractPollableSource implements
Configurable {
private static final Logger logger = LoggerFactory
.getLogger(org.apache.flume.source.MonitorCollectSource.class);
private static final long DEFAULTINTERVALMS = 60000L;
private SourceCounter sourceCounter;
private long intervalMs;
private long currentTs;
private long eventsSendTs = 0L;
//url根據配置的monitor端口變化。
private static final String DEAULTMONITORURL = "";
private String monitorUrl;
private static final boolean DEFAULTMONITORSTATUS = false;
private boolean monitorStatus;
@Override
protected void doConfigure(Context context) throws FlumeException {
intervalMs = context.getLong("intervalMs", DEFAULTINTERVALMS);
monitorUrl = context.getString("monitorUrl", DEAULTMONITORURL);
monitorStatus = context.getBoolean("monitorStatus", DEFAULTMONITORSTATUS);
if (sourceCounter == null) {
sourceCounter = new SourceCounter(getName());
}
}
@Override
protected Status doProcess() throws EventDeliveryException {
Status status = Status.READY;
currentTs = System.currentTimeMillis();
Map<String, Object> mapData = new HashMap<String, Object>();
try {
if ((eventsSendTs + intervalMs) < currentTs) {
//這裏控制,是否收集monitor數據。
if (monitorStatus) {
JSONObject monitorData = JSONObject.parseObject(getMonitor(monitorUrl));
mapData.put("monitorData", monitorData);
}
mapData.put("heart_ts", currentTs);
JSONObject jsonBody = (JSONObject) JSONObject.toJSON(mapData);
getChannelProcessor().processEvent(
EventBuilder.withBody(jsonBody.toString().getBytes()));
sourceCounter.incrementEventAcceptedCount();
eventsSendTs = currentTs;
} else {
status = Status.BACKOFF;
}
} catch (ChannelException ex) {
eventsSendts = 0L;
logger.error(getName() + " source could not write to channel.", ex);
}
return status;
}
@Override
protected void doStart() throws FlumeException {
logger.info("HeartBeat generator source do starting");
sourceCounter.start();
}
@Override
protected void doStop() throws FlumeException {
logger.info("HeartBeat generator source do stopping");
sourceCounter.stop();
logger.info("HeartBeat generator source do stopped. Metrics:{}", getName(), sourceCounter);
}
public static String getMonitor(String url) {
/*
獲取monitor數據
*/
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get()
.build();
Call call = okHttpClient.newCall(request);
Response response = null;
String monitorData = null;
try {
response = call.execute();
monitorData = response.body().string();
if (monitorData.isEmpty()) {
logger.warn("flume monitor data is empty !");
return monitorData;
}
} catch (IOException e) {
e.printStackTrace();
}
return monitorData;
}
}