Package com.dianping.cat.broker.api.page

Source Code of com.dianping.cat.broker.api.page.MonitorManager

package com.dianping.cat.broker.api.page;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.unidal.helper.Threads;
import org.unidal.helper.Threads.Task;
import org.unidal.lookup.annotation.Inject;

import com.dianping.cat.Cat;
import com.dianping.cat.CatConstants;
import com.dianping.cat.Monitor;
import com.dianping.cat.config.url.UrlPatternConfigManager;
import com.dianping.cat.message.Event;
import com.dianping.cat.message.Metric;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.message.internal.DefaultMetric;
import com.dianping.cat.service.IpService;
import com.dianping.cat.service.IpService.IpInfo;
import com.site.lookup.util.StringUtils;

public class MonitorManager implements Initializable, LogEnabled {

  private final int m_threadCounts = 20;

  private volatile long m_total = 0;

  private volatile long m_errorCount = -1;

  private Map<Integer, BlockingQueue<MonitorEntity>> m_queues = new LinkedHashMap<Integer, BlockingQueue<MonitorEntity>>();

  @Inject
  private IpService m_ipService;

  @Inject
  private UrlPatternConfigManager m_patternManger;

  private Logger m_logger;

  private void buildMessage(MonitorEntity entity, String url, IpInfo ipInfo) {
    String city = ipInfo.getProvince() + "-" + ipInfo.getCity();
    String channel = ipInfo.getChannel();
    String httpStatus = entity.getHttpStatus();
    String errorCode = entity.getErrorCode();
    long timestamp = entity.getTimestamp();
    double duration = entity.getDuration();
    String group = url;
    int count = entity.getCount();

    if (duration > 0) {
      logMetricForAvg(timestamp, duration, group, city + ":" + channel + ":" + Monitor.AVG);
    }

    String hitKey = city + ":" + channel + ":" + Monitor.HIT;

    logMetricForCount(timestamp, group, hitKey, count);

    if (!"200".equals(httpStatus)) {
      String key = city + ":" + channel + ":" + Monitor.ERROR;

      logMetricForCount(timestamp, group, key, count);
    }

    if (!StringUtils.isEmpty(httpStatus)) {
      String key = city + ":" + channel + ":" + Monitor.HTTP_STATUS + "|" + httpStatus;

      logMetricForCount(timestamp, group, key, count);
    }
    if (!StringUtils.isEmpty(errorCode)) {
      String key = city + ":" + channel + ":" + Monitor.ERROR_CODE + "|" + errorCode;

      logMetricForCount(timestamp, group, key, count);
    }
  }

  @Override
  public void enableLogging(Logger logger) {
    m_logger = logger;
  }

  @Override
  public void initialize() throws InitializationException {
    for (int i = 0; i < m_threadCounts; i++) {
      BlockingQueue<MonitorEntity> queue = new LinkedBlockingQueue<MonitorEntity>(10000);
      Threads.forGroup("cat").start(new MessageSender(queue, i));

      m_queues.put(i, queue);
    }
  }

  private void logMetricForAvg(long timestamp, double duration, String group, String key) {
    Metric metric = Cat.getProducer().newMetric(group, key);
    DefaultMetric defaultMetric = (DefaultMetric) metric;

    defaultMetric.setTimestamp(timestamp);
    defaultMetric.setStatus("S,C");
    defaultMetric.addData(String.format("%s,%.2f", 1, duration));
  }

  private void logMetricForCount(long timestamp, String group, String key, int count) {
    Metric metric = Cat.getProducer().newMetric(group, key);
    DefaultMetric defaultMetric = (DefaultMetric) metric;

    defaultMetric.setTimestamp(timestamp);

    defaultMetric.setStatus("C");
    defaultMetric.addData(String.valueOf(count));
  }

  public boolean offer(MonitorEntity entity) {
    if (!StringUtils.isEmpty(entity.getTargetUrl())) {
      m_total++;

      int index = (int) (m_total % m_threadCounts);
      int retryTime = 0;

      while (retryTime < m_threadCounts) {
        BlockingQueue<MonitorEntity> queue = m_queues.get((index + retryTime) % m_threadCounts);
        boolean result = queue.offer(entity);

        if (result) {
          return true;
        }
        retryTime++;
      }

      m_errorCount++;
      if (m_errorCount % CatConstants.ERROR_COUNT == 0) {
        m_logger.error("Error when offer entity to queues, size:" + m_errorCount);
      }
    }
    return false;
  }

  private String parseFormatUrl(String url) {
    String result = m_patternManger.handle(url);

    return result;
  }

  private void processOneEntity(MonitorEntity entity) {
    String targetUrl = entity.getTargetUrl();
    String url = parseFormatUrl(targetUrl);

    if (url != null) {
      Transaction t = Cat.newTransaction("Monitor", url);
      String ip = entity.getIp();
      IpInfo ipInfo = m_ipService.findIpInfoByString(ip);

      try {
        if (ipInfo != null) {
          buildMessage(entity, url, ipInfo);
        } else {
          Cat.logEvent("ip", "notFound", Event.SUCCESS, ip);
        }
        t.setStatus(Transaction.SUCCESS);
      } catch (Exception e) {
        Cat.logError(e);
        t.setStatus(e);
      } finally {
        t.complete();
      }
    }
  }

  public class MessageSender implements Task {

    private BlockingQueue<MonitorEntity> m_queue;

    private int m_index;

    public MessageSender(BlockingQueue<MonitorEntity> queue, int index) {
      m_queue = queue;
      m_index = index;
    }

    @Override
    public String getName() {
      return "Message-Send-" + m_index;
    }

    @Override
    public void run() {
      while (true) {
        try {
          MonitorEntity entity = m_queue.poll(5, TimeUnit.MILLISECONDS);

          if (entity != null) {
            try {
              processOneEntity(entity);
            } catch (Exception e) {
              Cat.logError(e);
            }
          }
        } catch (InterruptedException e) {
          break;
        }
      }
    }

    @Override
    public void shutdown() {
    }
  }

}
TOP

Related Classes of com.dianping.cat.broker.api.page.MonitorManager

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.