All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.otter.manager.biz.autokeeper.impl.AutoKeeperCollector Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2010-2101 Alibaba Group Holding Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.otter.manager.biz.autokeeper.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;

import com.alibaba.otter.manager.biz.common.exceptions.ManagerException;
import com.alibaba.otter.manager.biz.config.autokeeper.AutoKeeperClusterService;
import com.alibaba.otter.manager.biz.utils.RegexUtils;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperCluster;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperConnectionStat;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperEphemeralStat;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperQuorumType;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperServerStat;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperWatchStat;
import com.alibaba.otter.shared.common.utils.cmd.Exec;
import com.alibaba.otter.shared.common.utils.cmd.Exec.Result;
import com.alibaba.otter.shared.common.utils.thread.NamedThreadFactory;

/**
 * 对应的数据采集器
 * 
 * @author jianghang 2012-9-21 下午03:05:28
 * @version 4.1.0
 */
public class AutoKeeperCollector implements InitializingBean {

    @Resource(name = "autoKeeperClusterService")
    private AutoKeeperClusterService autoKeeperClusterService;

    private static final String      MODE_FOLLOWER            = "Mode: follower";
    private static final String      MODE_LEADERER            = "Mode: leader";
    private static final String      MODE_OBSERVER            = "Mode: observer";
    private static final String      MODE_STANDALONE          = "Mode: standalone";
    private static final String      NODE_COUNT               = "Node count:";
    private static final String      STRING_LATENCY           = "Latency min/avg/max:";
    private static final String      STRING_SENT              = "Sent:";
    private static final String      STRING_RECEIVED          = "Received:";
    private static final String      STRING_OUTSTANDING       = "Outstanding:";
    private static final String      COMMA                    = ",";
    private static final String      BRACKETS                 = ")";
    private static final String      COLON                    = ":";
    private static final String      WRAP                     = "\n";
    private static final String      CMD_STAT                 = "echo stat | nc %s %s";
    private static final String      CMD_CONS                 = "echo cons | nc %s %s";
    private static final String      CMD_DUMP                 = "echo dump | nc %s %s";
    private static final String      CMD_WCHC                 = "echo wchc | nc %s %s";
    private static final long        DEFAULT_COLLECT_INTERVAL = 300;
    private long                     delay                    = 1;
    private int                      singleSize               = 1;
    private long                     collectInterval          = DEFAULT_COLLECT_INTERVAL;

    private AutoKeeperData           autoKeeperData;
    private ScheduledExecutorService collectorExecutor;

    public void collectorConnectionStat(String address) {
        List netAddress = splitAddress(address);
        if (netAddress.isEmpty()) {
            return;
        }
        String ip = netAddress.get(0);
        String port = netAddress.get(1);
        String[] cmd = { "/bin/bash", "-c", String.format(CMD_CONS, ip, port) };
        String cmdresult = collector(cmd);
        String[] result = cmdresult.split(WRAP);
        List summary = new ArrayList();

        for (String line : result) {

            if (StringUtils.isBlank(line)) {
                continue;
            }

            String[] lineArray = line.split(":");
            if (2 != lineArray.length) {
                continue;
            }

            AutoKeeperConnectionStat autoKeeperConnectionStat = new AutoKeeperConnectionStat();
            autoKeeperConnectionStat.setOriginalContent(line);
            String clientIp = StringUtils.trimToEmpty(line.split(":")[0].replace("/", ""));
            String sessionId = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "sid=(?s).*?[,)]")).replace("sid=",
                                                                                                                            StringUtils.EMPTY).replace(COMMA,
                                                                                                                                                       StringUtils.EMPTY).replace(BRACKETS,
                                                                                                                                                                                  StringUtils.EMPTY);
            String queued = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "queued=(?s).*?[,)]")).replace("queued=",
                                                                                                                            StringUtils.EMPTY).replace(COMMA,
                                                                                                                                                       StringUtils.EMPTY).replace(BRACKETS,
                                                                                                                                                                                  StringUtils.EMPTY);
            String receive = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "recved=(?s).*?[,)]")).replace("recved=",
                                                                                                                             StringUtils.EMPTY).replace(COMMA,
                                                                                                                                                        StringUtils.EMPTY).replace(BRACKETS,
                                                                                                                                                                                   StringUtils.EMPTY);
            String sent = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "sent=(?s).*?[,)]")).replace("sent=",
                                                                                                                        StringUtils.EMPTY).replace(COMMA,
                                                                                                                                                   StringUtils.EMPTY).replace(BRACKETS,
                                                                                                                                                                              StringUtils.EMPTY);
            String minlat = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "minlat=(?s).*?[,)]")).replace("minlat=",
                                                                                                                            StringUtils.EMPTY).replace(COMMA,
                                                                                                                                                       StringUtils.EMPTY).replace(BRACKETS,
                                                                                                                                                                                  StringUtils.EMPTY);
            String avglat = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "avglat=(?s).*?[,)]")).replace("avglat=",
                                                                                                                            StringUtils.EMPTY).replace(COMMA,
                                                                                                                                                       StringUtils.EMPTY).replace(BRACKETS,
                                                                                                                                                                                  StringUtils.EMPTY);
            String maxlat = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "maxlat=(?s).*?[,)]")).replace("maxlat=",
                                                                                                                            StringUtils.EMPTY).replace(COMMA,
                                                                                                                                                       StringUtils.EMPTY).replace(BRACKETS,
                                                                                                                                                                                  StringUtils.EMPTY);
            autoKeeperConnectionStat.setServerAddress(ip);
            autoKeeperConnectionStat.setClientAddress(clientIp);
            autoKeeperConnectionStat.setSessionId(sessionId);
            if (StringUtils.isNotEmpty(queued)) {
                autoKeeperConnectionStat.setQueued(Long.parseLong(queued));
            }
            if (StringUtils.isNotEmpty(receive)) {
                autoKeeperConnectionStat.setRecved(Long.parseLong(receive));
            }
            if (StringUtils.isNotEmpty(sent)) {
                autoKeeperConnectionStat.setSent(Long.parseLong(sent));
            }
            if (StringUtils.isNotEmpty(minlat)) {
                autoKeeperConnectionStat.setMinLatency(Long.parseLong(minlat));
            }
            if (StringUtils.isNotEmpty(avglat)) {
                autoKeeperConnectionStat.setAvgLatency(Long.parseLong(avglat));
            }
            if (StringUtils.isNotEmpty(maxlat)) {
                autoKeeperConnectionStat.setMaxLatency(Long.parseLong(maxlat));
            }

            summary.add(autoKeeperConnectionStat);
        }
        autoKeeperData.joinConnection(address, summary);
    }

    public void collectorServerStat(String address) {
        List netAddress = splitAddress(address);
        if (netAddress.isEmpty()) {
            return;
        }
        String ip = netAddress.get(0);
        String port = netAddress.get(1);
        String[] cmd = { "/bin/bash", "-c", String.format(CMD_STAT, ip, port) };
        String cmdresult = collector(cmd);
        String[] result = cmdresult.split(WRAP);
        AutoKeeperServerStat summary = new AutoKeeperServerStat();
        summary.setOriginalContent(cmdresult);
        for (String line : result) {

            if (line.contains(MODE_FOLLOWER)) {
                summary.setQuorumType(AutoKeeperQuorumType.FOLLOWER);
            } else if (line.contains(MODE_LEADERER)) {
                summary.setQuorumType(AutoKeeperQuorumType.LEADER);
            } else if (line.contains(MODE_STANDALONE)) {
                summary.setQuorumType(AutoKeeperQuorumType.STANDALONE);
            } else if (line.contains(MODE_OBSERVER)) {
                summary.setQuorumType(AutoKeeperQuorumType.OBSERVER);
            } else if (line.contains(STRING_LATENCY)) {
                List latency = Arrays.asList(StringUtils.trimToEmpty(line.replace(STRING_LATENCY,
                                                                                          StringUtils.EMPTY)).split("/"));
                summary.setMinLatency(Long.parseLong(latency.get(0)));
                summary.setAvgLatency(Long.parseLong(latency.get(1)));
                summary.setMaxLatency(Long.parseLong(latency.get(2)));
            } else if (line.contains(STRING_OUTSTANDING)) {
                summary.setQueued(Long.parseLong(StringUtils.trimToEmpty(line.replace(STRING_OUTSTANDING,
                                                                                      StringUtils.EMPTY))));
            } else if (line.contains(NODE_COUNT)) {
                summary.setNodeCount(Long.parseLong(StringUtils.trimToEmpty(line.replace(NODE_COUNT, StringUtils.EMPTY))));
            } else if (line.contains(STRING_SENT)) {
                summary.setSent(Long.parseLong(StringUtils.trimToEmpty(line.replace(STRING_SENT, StringUtils.EMPTY))));
            } else if (line.contains(STRING_RECEIVED)) {
                summary.setRecved(Long.parseLong(StringUtils.trimToEmpty(line.replace(STRING_RECEIVED,
                                                                                      StringUtils.EMPTY))));
            }
        }

        autoKeeperData.joinServer(address, summary);
    }

    public void collectorEphemeralStat(String address) {
        List netAddress = splitAddress(address);
        if (netAddress.isEmpty()) {
            return;
        }
        String ip = netAddress.get(0);
        String port = netAddress.get(1);
        String[] cmd = { "/bin/bash", "-c", String.format(CMD_DUMP, ip, port) };
        String cmdresult = collector(cmd);

        Map> pathMap = groupSessionPath(cmdresult);

        List autoKeeperEphemeralStats = new ArrayList();
        for (Map.Entry> entry : pathMap.entrySet()) {
            AutoKeeperEphemeralStat autoKeeperEphemeralStat = new AutoKeeperEphemeralStat();
            autoKeeperEphemeralStat.setSessionId(entry.getKey());
            autoKeeperEphemeralStat.setPaths(entry.getValue());
            autoKeeperEphemeralStats.add(autoKeeperEphemeralStat);
        }

        autoKeeperData.joinEphemeral(address, autoKeeperEphemeralStats);

    }

    public void collectorWatchStat(String address) {
        List netAddress = splitAddress(address);
        if (netAddress.isEmpty()) {
            return;
        }
        String ip = netAddress.get(0);
        String port = netAddress.get(1);
        String[] cmd = { "/bin/bash", "-c", String.format(CMD_WCHC, ip, port) };
        String cmdresult = collector(cmd);

        Map> pathMap = groupSessionPath(cmdresult);

        List autoKeeperWatchStats = new ArrayList();
        for (Map.Entry> entry : pathMap.entrySet()) {
            AutoKeeperWatchStat autoKeeperWatchStat = new AutoKeeperWatchStat();
            autoKeeperWatchStat.setSessionId(entry.getKey());
            autoKeeperWatchStat.setPaths(entry.getValue());
            autoKeeperWatchStats.add(autoKeeperWatchStat);
        }

        autoKeeperData.joinWatch(address, autoKeeperWatchStats);

    }

    public static String collector(String[] command) {
        Result result = null;
        try {
            result = Exec.execute(command);
            if (result.getExitCode() == 0) {
                return result.getStdout();
            } else {
                return result.getStderr();
            }
        } catch (Exception e) {
            throw new ManagerException(e);
        }
    }

    private List splitAddress(String address) {
        List ipPort = Arrays.asList(address.split(":"));
        if (ipPort.size() != 2) {
            return new ArrayList();
        }
        return ipPort;
    }

    /**
     * 
     * key=sessionId
     * value=pathList
     * 
*/ private Map> groupSessionPath(String cmdresult) { String[] result = cmdresult.split(WRAP); Map> pathMap = new HashMap>(); String sessionId = StringUtils.EMPTY; for (String line : result) { line = StringUtils.trimToEmpty(line); if (StringUtils.isBlank(line)) { continue; } if (line.startsWith("0x")) { sessionId = line.replace(COLON, StringUtils.EMPTY); pathMap.put(sessionId, new ArrayList()); } else if (line.startsWith("/")) { List paths = pathMap.get(sessionId); paths.add(line); } } return pathMap; } @Override public void afterPropertiesSet() throws Exception { collectorExecutor = Executors.newScheduledThreadPool(singleSize, new NamedThreadFactory("collector-thread", true)); startCollect(); } private void startCollect() { // 启动定时工作任务 collectorExecutor.scheduleAtFixedRate(new Runnable() { @Override public void run() { List autoKeeperClusters = autoKeeperClusterService.listAutoKeeperClusters(); if (!autoKeeperClusters.isEmpty()) { autoKeeperData.persist(); for (AutoKeeperCluster autoKeeperCluster : autoKeeperClusters) { List servers = autoKeeperCluster.getServerList(); for (String address : servers) { collectorServerStat(address); collectorConnectionStat(address); collectorWatchStat(address); collectorEphemeralStat(address); } } } } }, delay, collectInterval, TimeUnit.SECONDS); } public void setAutoKeeperClusterService(AutoKeeperClusterService autoKeeperClusterService) { this.autoKeeperClusterService = autoKeeperClusterService; } public void setAutoKeeperData(AutoKeeperData autoKeeperData) { this.autoKeeperData = autoKeeperData; } public void setCollectInterval(long collectInterval) { this.collectInterval = collectInterval; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy