自定義一個flume監控回收source

自定義回收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;
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章