10. CAT-报表视图

10.01 说明

数据从客户端采集,上报到服务端,进行各种不同类型报表的汇总统计与分析,最终以报表的展示形式展示在用户的面前,用户非常直观的发现自己在客户端埋点的信息,很快的发现和推断问题。

10.02 报表

Cat平台中提供了很多的报表,其中,最关键的几个如下

  • 报警统计
  • 性能分析
  • 调用链分析
  • 报警配置

10.03 示例说明报表构建与展示

以报警统计说明报表的构建

10.03.01 维度要求

告警的类型很多,包含日常系统维护的很多方面。这里以最为关注的 `异常报警` 进行说明。

告警类型

public enum AlertType {

    Business("Business"),

    Network("Network"),

    DataBase("Database"),

    System("System"),

    Exception("Exception"),

    HeartBeat("Heartbeat"),

    ThirdParty("ThirdParty"),

    FrontEndException("FrontEnd"),

    App("App"),

    Web("Web"),

    Transaction("Transaction"),

    Event("Event"),

    STORAGE_SQL("SQL"),

    STORAGE_CACHE("Cache");

异常告警文件目录

异常统计维度

    public class AlertException {

        private String m_name;

        private String m_type;

        private double m_count;

        public AlertException(String name, String type, double count) {
            m_name = name;
            m_type = type;
            m_count = count;
        }

        public String getName() {
            return m_name;
        }

        public String getType() {
            return m_type;
        }

        @Override
        public String toString() {
            return "[ 异常名称: " + m_name + " 异常数量:" + m_count + " ]";
        }
    }

10.03.02 数据统计构建

CatHomeModule

@Named(type = Module.class, value = CatHomeModule.ID)
public class CatHomeModule extends AbstractModule {
    public static final String ID = "cat-home";
    if (serverConfigManager.isAlertMachine()) {
            .....
            FrontEndExceptionAlert frontEndExceptionAlert = ctx.lookup(FrontEndExceptionAlert.class);
            .....
            Threads.forGroup("cat").start(frontEndExceptionAlert);

FrontEndExceptionAlert

public class FrontEndExceptionAlert extends ExceptionAlert {
   
   ......
    
   private void handleExceptions(List<Item> itemList) {
        Map<String, List<AlertException>> alertExceptions = m_alertBuilder.buildAlertExceptions(itemList);

        for (Entry<String, List<AlertException>> entry : alertExceptions.entrySet()) {
            try {
                String domain = entry.getKey();
                List<AlertException> exceptions = entry.getValue();

                for (AlertException exception : exceptions) {
                    String metricName = exception.getName();
                    AlertEntity entity = new AlertEntity();

                    entity.setDate(new Date()).setContent(exception.toString()).setLevel(exception.getType());
                    entity.setMetric(metricName).setType(getName()).setGroup(domain);
                    m_sendManager.addAlert(entity);
                }
            } catch (Exception e) {
                Cat.logError(e);
            }
        }
    }
    
   @Override
    public void run() {
        boolean active = TimeHelper.sleepToNextMinute();

        while (active) {
            long current = System.currentTimeMillis();
            Transaction t = Cat.newTransaction("AlertFrontEnd", TimeHelper.getMinuteStr());

            try {
                TopMetric topMetric = buildTopMetric(new Date(current - TimeHelper.ONE_MINUTE * 2));
                                Collection<List<Item>> itemLists = topMetric.getError().getResult().values();
                List<Item> itemList = new ArrayList<Item>();

                if (!itemLists.isEmpty()) {
                    itemList = itemLists.iterator().next();
                }
                List<Item> items = new ArrayList<Item>();

                for (Item item : itemList) {
                    if (!Constants.FRONT_END.equals(item.getDomain())) {
                        items.add(item);
                    }
                }
                handleExceptions(items);
public class AlertExceptionBuilder {

    @Inject
    private ExceptionRuleConfigManager m_exceptionConfigManager;

    @Inject
    private AggregationConfigManager m_aggregationConfigManager;

    public Map<String, List<AlertException>> buildAlertExceptions(List<Item> items) {
        Map<String, List<AlertException>> alertExceptions = new LinkedHashMap<String, List<AlertException>>();

        for (Item item : items) {
            List<AlertException> domainAlertExceptions = buildDomainAlertExceptions(item);

            if (!domainAlertExceptions.isEmpty()) {
                alertExceptions.put(item.getDomain(), domainAlertExceptions);
            }
        }
        return alertExceptions;
    }

10.03.03 性能说明

在上面的代码中,数据存储在数据库或者服务器本地内存,磁盘中。
应对公司众多项目的埋点数据上报,必须导致服务端的资源消耗很大,上报数据,虽然做了域名性质的数据Hash映射,但是同样不能避免很大数据量,统计分析维度众多的情况下,必然带来的是大量的资源消耗,如,IO和CPU资源消耗。
从资源消耗上,看这个分析统计的功能更加适合使用实时数据组件进行统计和运算,这样从架构和资源角度看更加适合。但是使用实时数据分析,必然需要模块的拆分,同时导致链条变长,同时导致报表的数据查看,数据有一定的延迟。

10.04 小结

  • 友好的视图展示,很大程度提升了系统的颜值
  • 报表构建&加载将是Cat最佳优化的点,它的优化将会很大程度的降低硬件系统资源
posted @ 2021-02-17 10:08  可可逗豆  阅读(111)  评论(0)    收藏  举报