Package com.dianping.cat.report.page.model

Source Code of com.dianping.cat.report.page.model.Handler

package com.dianping.cat.report.page.model;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.unidal.lookup.ContainerHolder;
import org.unidal.lookup.annotation.Inject;
import org.unidal.web.mvc.PageHandler;
import org.unidal.web.mvc.annotation.InboundActionMeta;
import org.unidal.web.mvc.annotation.OutboundActionMeta;
import org.unidal.web.mvc.annotation.PayloadMeta;

import com.dianping.cat.Cat;
import com.dianping.cat.Constants;
import com.dianping.cat.consumer.cross.CrossAnalyzer;
import com.dianping.cat.consumer.dependency.DependencyAnalyzer;
import com.dianping.cat.consumer.event.EventAnalyzer;
import com.dianping.cat.consumer.event.model.entity.EventName;
import com.dianping.cat.consumer.event.model.entity.EventType;
import com.dianping.cat.consumer.heartbeat.HeartbeatAnalyzer;
import com.dianping.cat.consumer.heartbeat.model.entity.HeartbeatReport;
import com.dianping.cat.consumer.matrix.MatrixAnalyzer;
import com.dianping.cat.consumer.metric.MetricAnalyzer;
import com.dianping.cat.consumer.metric.model.entity.MetricReport;
import com.dianping.cat.consumer.problem.ProblemAnalyzer;
import com.dianping.cat.consumer.problem.model.entity.Entry;
import com.dianping.cat.consumer.problem.model.entity.JavaThread;
import com.dianping.cat.consumer.problem.model.entity.Machine;
import com.dianping.cat.consumer.problem.model.entity.Segment;
import com.dianping.cat.consumer.state.StateAnalyzer;
import com.dianping.cat.consumer.top.TopAnalyzer;
import com.dianping.cat.consumer.transaction.TransactionAnalyzer;
import com.dianping.cat.consumer.transaction.model.IEntity;
import com.dianping.cat.consumer.transaction.model.entity.AllDuration;
import com.dianping.cat.consumer.transaction.model.entity.Duration;
import com.dianping.cat.consumer.transaction.model.entity.Range;
import com.dianping.cat.consumer.transaction.model.entity.TransactionName;
import com.dianping.cat.consumer.transaction.model.entity.TransactionReport;
import com.dianping.cat.consumer.transaction.model.entity.TransactionType;
import com.dianping.cat.helper.SortHelper;
import com.dianping.cat.message.internal.MessageId;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.cdn.graph.CdnReportConvertor;
import com.dianping.cat.report.page.model.cross.LocalCrossService;
import com.dianping.cat.report.page.model.dependency.LocalDependencyService;
import com.dianping.cat.report.page.model.event.LocalEventService;
import com.dianping.cat.report.page.model.heartbeat.LocalHeartbeatService;
import com.dianping.cat.report.page.model.logview.LocalMessageService;
import com.dianping.cat.report.page.model.matrix.LocalMatrixService;
import com.dianping.cat.report.page.model.metric.LocalMetricService;
import com.dianping.cat.report.page.model.problem.LocalProblemService;
import com.dianping.cat.report.page.model.spi.ModelService;
import com.dianping.cat.report.page.model.state.LocalStateService;
import com.dianping.cat.report.page.model.top.LocalTopService;
import com.dianping.cat.report.page.model.transaction.LocalTransactionService;
import com.dianping.cat.report.page.system.graph.SystemReportConvertor;
import com.dianping.cat.report.page.web.graph.WebReportConvertor;
import com.dianping.cat.service.IpService;
import com.dianping.cat.service.ModelPeriod;
import com.dianping.cat.service.ModelRequest;
import com.dianping.cat.service.ModelResponse;

public class Handler extends ContainerHolder implements PageHandler<Context> {

  @Inject(type = ModelService.class, value = "cross-local")
  private LocalCrossService m_crossService;

  @Inject(type = ModelService.class, value = "dependency-local")
  private LocalDependencyService m_dependencyService;

  @Inject(type = ModelService.class, value = "event-local")
  private LocalEventService m_eventService;

  @Inject(type = ModelService.class, value = "heartbeat-local")
  private LocalHeartbeatService m_heartbeatService;

  @Inject(type = ModelService.class, value = "matrix-local")
  private LocalMatrixService m_matrixService;

  @Inject(type = ModelService.class, value = "message-local")
  private LocalMessageService m_messageService;

  @Inject(type = ModelService.class, value = "metric-local")
  private LocalMetricService m_metricService;

  @Inject(type = ModelService.class, value = "problem-local")
  private LocalProblemService m_problemService;

  @Inject(type = ModelService.class, value = "state-local")
  private LocalStateService m_stateService;

  @Inject(type = ModelService.class, value = "top-local")
  private LocalTopService m_topService;

  @Inject(type = ModelService.class, value = "transaction-local")
  private LocalTransactionService m_transactionService;

  @Inject
  private IpService m_ipService;

  private static final int DEFAULT_SIZE = 32 * 1024;

  private byte[] compress(String str) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream(1024 * 32);
    GZIPOutputStream gzip = new GZIPOutputStream(out);
    gzip.write(str.getBytes());
    gzip.close();
    return out.toByteArray();
  }

  private String doFilter(Payload payload, Object dataModel) {
    String report = payload.getReport();
    String ipAddress = payload.getIpAddress();
    if (TransactionAnalyzer.ID.equals(report)) {
      try {
        TransactionReportFilter filter = new TransactionReportFilter(payload.getType(), payload.getName(),
              ipAddress);

        return filter.buildXml((IEntity<?>) dataModel);
      } catch (Exception e) {
        TransactionReportFilter filter = new TransactionReportFilter(payload.getType(), payload.getName(),
              ipAddress);

        return filter.buildXml((IEntity<?>) dataModel);
      }
    } else if (EventAnalyzer.ID.equals(report)) {
      EventReportFilter filter = new EventReportFilter(payload.getType(), payload.getName(), ipAddress);

      return filter.buildXml((com.dianping.cat.consumer.event.model.IEntity<?>) dataModel);
    } else if (ProblemAnalyzer.ID.equals(report)) {
      ProblemReportFilter filter = new ProblemReportFilter(ipAddress, payload.getType(), payload.getQueryType(),
            payload.getName());

      return filter.buildXml((com.dianping.cat.consumer.problem.model.IEntity<?>) dataModel);
    } else if (HeartbeatAnalyzer.ID.equals(report)) {
      if (StringUtils.isEmpty(ipAddress)) {
        HeartbeatReport reportModel = (HeartbeatReport) dataModel;
        Set<String> ips = reportModel.getIps();
        if (ips.size() > 0) {
          ipAddress = SortHelper.sortIpAddress(ips).get(0);
        }
      }
      HeartBeatReportFilter filter = new HeartBeatReportFilter(ipAddress);

      return filter.buildXml((com.dianping.cat.consumer.heartbeat.model.IEntity<?>) dataModel);
    } else if (MatrixAnalyzer.ID.equals(report)) {
      return new MatrixReportFilter().buildXml((com.dianping.cat.consumer.matrix.model.IEntity<?>) dataModel);
    } else if (CrossAnalyzer.ID.equals(report)) {
      return new CrossReportFilter().buildXml((com.dianping.cat.consumer.cross.model.IEntity<?>) dataModel);
    } else if (StateAnalyzer.ID.equals(report)) {
      return new StateReportFilter().buildXml((com.dianping.cat.consumer.state.model.IEntity<?>) dataModel);
    } else if (TopAnalyzer.ID.equals(report)) {
      return new TopReportFilter().buildXml((com.dianping.cat.consumer.top.model.IEntity<?>) dataModel);
    } else if (MetricAnalyzer.ID.equals(report)) {
      return new MetricReportFilter().buildXml((com.dianping.cat.consumer.metric.model.IEntity<?>) dataModel);
    } else if (DependencyAnalyzer.ID.equals(report)) {
      return new DependencyReportFilter()
            .buildXml((com.dianping.cat.consumer.dependency.model.IEntity<?>) dataModel);
    } else {
      return String.valueOf(dataModel);
    }
  }

  @Override
  @PayloadMeta(Payload.class)
  @InboundActionMeta(name = "model")
  public void handleInbound(Context ctx) throws ServletException, IOException {
    // display only, no action here
  }

  @SuppressWarnings("unchecked")
  @Override
  @OutboundActionMeta(name = "model")
  public void handleOutbound(Context ctx) throws ServletException, IOException {
    Model model = new Model(ctx);
    Payload payload = ctx.getPayload();
    HttpServletResponse httpResponse = ctx.getHttpServletResponse();

    model.setAction(Action.XML);
    model.setPage(ReportPage.MODEL);

    try {
      String report = payload.getReport();
      String domain = payload.getDomain();
      ModelPeriod period = payload.getPeriod();
      ModelRequest request = null;

      if ("logview".equals(report)) {
        request = new ModelRequest(domain, MessageId.parse(payload.getMessageId()).getTimestamp());
      } else {
        request = new ModelRequest(domain, period.getStartTime());
      }
      ModelResponse<?> response = null;

      if (TransactionAnalyzer.ID.equals(report)) {
        response = m_transactionService.invoke(request);
      } else if (EventAnalyzer.ID.equals(report)) {
        response = m_eventService.invoke(request);
      } else if (ProblemAnalyzer.ID.equals(report)) {
        response = m_problemService.invoke(request);
      } else if ("logview".equals(report)) {
        String messageId = payload.getMessageId();
        MessageId id = MessageId.parse(messageId);

        request.setProperty("messageId", messageId);
        request.setProperty("waterfall", String.valueOf(payload.isWaterfall()));

        if (id.getVersion() != 1) {
          response = m_messageService.invoke(request);
        }
      } else if (HeartbeatAnalyzer.ID.equals(report)) {
        response = m_heartbeatService.invoke(request);
      } else if (MatrixAnalyzer.ID.equals(report)) {
        response = m_matrixService.invoke(request);
      } else if (CrossAnalyzer.ID.equals(report)) {
        response = m_crossService.invoke(request);
      } else if (StateAnalyzer.ID.equals(report)) {
        response = m_stateService.invoke(request);
      } else if (TopAnalyzer.ID.equals(report)) {
        response = m_topService.invoke(request);
      } else if (MetricAnalyzer.ID.equals(report)) {
        response = m_metricService.invoke(request);

        String metricType = payload.getMetricType();
        String type = payload.getType();

        if (Constants.METRIC_USER_MONITOR.equals(metricType)) {
          String city = payload.getCity();
          String channel = payload.getChannel();
          WebReportConvertor convert = new WebReportConvertor(type, city, channel);
          MetricReport metricReport = (MetricReport) response.getModel();

          convert.visitMetricReport(metricReport);
          ((ModelResponse<MetricReport>) response).setModel(convert.getReport());
        } else if (Constants.METRIC_SYSTEM_MONITOR.equals(metricType)) {
          String ipAddrsStr = payload.getIpAddress();
          Set<String> ipAddrs = null;

          if (!Constants.ALL.equalsIgnoreCase(ipAddrsStr)) {
            String[] ipAddrsArray = ipAddrsStr.split("_");
            ipAddrs = new HashSet<String>(Arrays.asList(ipAddrsArray));
          }

          SystemReportConvertor convert = new SystemReportConvertor(type, ipAddrs);
          MetricReport metricReport = (MetricReport) response.getModel();

          convert.visitMetricReport(metricReport);
          ((ModelResponse<MetricReport>) response).setModel(convert.getReport());
        } else if (Constants.METRIC_CDN.equals(metricType)) {
          String cdn = payload.getCdn();
          String province = payload.getProvince();
          String city = payload.getCity();
          MetricReport metricReport = (MetricReport) response.getModel();
          CdnReportConvertor cdnReportConvertor = new CdnReportConvertor(m_ipService);

          cdnReportConvertor.setProvince(province).setCity(city).setCdn(cdn);
          cdnReportConvertor.visitMetricReport(metricReport);
          ((ModelResponse<MetricReport>) response).setModel(cdnReportConvertor.getReport());
        }

      } else if (DependencyAnalyzer.ID.equals(report)) {
        response = m_dependencyService.invoke(request);
      } else {
        throw new RuntimeException("Unsupported report: " + report + "!");
      }

      if (response != null) {
        Object dataModel = response.getModel();
        String xml = "";

        if (dataModel != null) {
          xml = doFilter(payload, dataModel);
        }
        ServletOutputStream outputStream = httpResponse.getOutputStream();
        byte[] compress = compress(xml);

        httpResponse.setContentType("application/xml;charset=utf-8");
        httpResponse.addHeader("Content-Encoding", "gzip");
        outputStream.write(compress);
      }
    } catch (Throwable e) {
      Cat.logError(e);
    }
  }

  public static class CrossReportFilter extends com.dianping.cat.consumer.cross.model.transform.DefaultXmlBuilder {
    public CrossReportFilter() {
      super(true, new StringBuilder(DEFAULT_SIZE));
    }
  }

  public static class DependencyReportFilter extends
        com.dianping.cat.consumer.dependency.model.transform.DefaultXmlBuilder {
    public DependencyReportFilter() {
      super(true, new StringBuilder(DEFAULT_SIZE));
    }
  }

  public static class EventReportFilter extends com.dianping.cat.consumer.event.model.transform.DefaultXmlBuilder {
    private String m_ipAddress;

    private String m_name;

    private String m_type;

    public EventReportFilter(String type, String name, String ip) {
      super(true, new StringBuilder(DEFAULT_SIZE));
      m_type = type;
      m_name = name;
      m_ipAddress = ip;
    }

    @Override
    public void visitMachine(com.dianping.cat.consumer.event.model.entity.Machine machine) {
      if (m_ipAddress == null || m_ipAddress.equals(Constants.ALL)) {
        super.visitMachine(machine);
      } else if (machine.getIp().equals(m_ipAddress)) {
        super.visitMachine(machine);
      }
    }

    @Override
    public void visitName(EventName name) {
      if (m_type != null) {
        super.visitName(name);
      }
    }

    @Override
    public void visitRange(com.dianping.cat.consumer.event.model.entity.Range range) {
      if (m_type != null && m_name != null) {
        super.visitRange(range);
      }
    }

    @Override
    public void visitType(EventType type) {
      if (m_type == null) {
        super.visitType(type);
      } else if (type.getId().equals(m_type)) {
        type.setSuccessMessageUrl(null);
        type.setFailMessageUrl(null);

        super.visitType(type);
      }
    }
  }

  static class HeartBeatReportFilter extends com.dianping.cat.consumer.heartbeat.model.transform.DefaultXmlBuilder {
    private String m_ip;

    public HeartBeatReportFilter(String ip) {
      super(true, new StringBuilder(DEFAULT_SIZE));
      m_ip = ip;
    }

    @Override
    public void visitMachine(com.dianping.cat.consumer.heartbeat.model.entity.Machine machine) {
      if (machine.getIp().equals(m_ip) || StringUtils.isEmpty(m_ip) || Constants.ALL.equals(m_ip)) {
        super.visitMachine(machine);
      }
    }
  }

  public static class MatrixReportFilter extends com.dianping.cat.consumer.matrix.model.transform.DefaultXmlBuilder {
    public MatrixReportFilter() {
      super(true, new StringBuilder(DEFAULT_SIZE));
    }
  }

  public static class MetricReportFilter extends com.dianping.cat.consumer.metric.model.transform.DefaultXmlBuilder {
    public MetricReportFilter() {
      super(true, new StringBuilder(DEFAULT_SIZE));
    }
  }

  public static class ProblemReportFilter extends com.dianping.cat.consumer.problem.model.transform.DefaultXmlBuilder {
    private String m_ipAddress;

    // view is show the summary,detail show the thread info
    private String m_type;

    private String m_queryType;

    private String m_status;

    public ProblemReportFilter(String ipAddress, String type, String queryType, String name) {
      super(true, new StringBuilder(DEFAULT_SIZE));
      m_ipAddress = ipAddress;
      m_type = type;
      m_status = name;
      m_queryType = queryType;
    }

    @Override
    public void visitMachine(Machine machine) {
      if (m_ipAddress == null) {
        super.visitMachine(machine);
      } else if (machine.getIp().equals(m_ipAddress)) {
        super.visitMachine(machine);
      }
    }

    @Override
    public void visitDuration(com.dianping.cat.consumer.problem.model.entity.Duration duration) {
      super.visitDuration(duration);
    }

    @Override
    public void visitSegment(Segment segment) {
      super.visitSegment(segment);
    }

    @Override
    public void visitEntry(Entry entry) {
      if (m_type == null) {
        super.visitEntry(entry);
      } else {
        if (m_status == null) {
          if (entry.getType().equals(m_type)) {
            super.visitEntry(entry);
          }
        } else {
          if (entry.getType().equals(m_type) && entry.getStatus().equals(m_status)) {
            super.visitEntry(entry);
          }
        }
      }
    }

    @Override
    public void visitThread(JavaThread thread) {
      if ("detail".equals(m_queryType)) {
        super.visitThread(thread);
      }
    }
  }

  public static class StateReportFilter extends com.dianping.cat.consumer.state.model.transform.DefaultXmlBuilder {
    public StateReportFilter() {
      super(true, new StringBuilder(DEFAULT_SIZE));
    }
  }

  public static class TopReportFilter extends com.dianping.cat.consumer.top.model.transform.DefaultXmlBuilder {
    public TopReportFilter() {
      super(true, new StringBuilder(DEFAULT_SIZE));
    }
  }

  public static class TransactionReportFilter extends
        com.dianping.cat.consumer.transaction.model.transform.DefaultXmlBuilder {
    private String m_ipAddress;

    private String m_name;

    private String m_type;

    public TransactionReportFilter(String type, String name, String ip) {
      super(true, new StringBuilder(DEFAULT_SIZE));
      m_type = type;
      m_name = name;
      m_ipAddress = ip;
    }

    @Override
    public void visitAllDuration(AllDuration duration) {
    }

    @Override
    public void visitDuration(Duration duration) {
      if (m_type != null && m_name != null) {
        super.visitDuration(duration);
      }
    }

    @Override
    public void visitMachine(com.dianping.cat.consumer.transaction.model.entity.Machine machine) {
      synchronized (machine) {
        if (m_ipAddress == null || m_ipAddress.equals(Constants.ALL)) {
          super.visitMachine(machine);
        } else if (machine.getIp().equals(m_ipAddress)) {
          super.visitMachine(machine);
        }
      }
    }

    @Override
    public void visitName(TransactionName name) {
      if (m_type != null) {
        visitTransactionName(name);
      }
    }

    @Override
    public void visitRange(Range range) {
      if (m_type != null && m_name != null) {
        super.visitRange(range);
      }
    }

    private void visitTransactionName(TransactionName name) {
      super.visitName(name);
    }

    @Override
    public void visitTransactionReport(TransactionReport transactionReport) {
      synchronized (transactionReport) {
        super.visitTransactionReport(transactionReport);
      }
    }

    @Override
    public void visitType(TransactionType type) {
      if (m_type == null) {
        super.visitType(type);
      } else if (type.getId().equals(m_type)) {
        super.visitType(type);
      }
    }
  }

}
TOP

Related Classes of com.dianping.cat.report.page.model.Handler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.