Package org.apache.helix.monitoring

Source Code of org.apache.helix.monitoring.ZKPathDataDumpTask

package org.apache.helix.monitoring;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.
*/

import java.io.StringWriter;
import java.util.Date;
import java.util.List;
import java.util.TimerTask;

import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyType;
import org.apache.helix.ZNRecord;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkClient;
import org.apache.helix.util.HelixUtil;
import org.apache.log4j.Logger;
import org.apache.zookeeper.data.Stat;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;


public class ZKPathDataDumpTask extends TimerTask
{
  static Logger logger = Logger.getLogger(ZKPathDataDumpTask.class);

  private final int _thresholdNoChangeInMs;
  private final HelixManager _manager;
  private final ZkClient _zkClient;

  public ZKPathDataDumpTask(HelixManager manager, ZkClient zkClient, int thresholdNoChangeInMs)
  {
    _manager = manager;
    _zkClient = zkClient;
    logger.info("Scannning cluster statusUpdate " + manager.getClusterName()
        + " thresholdNoChangeInMs: " + thresholdNoChangeInMs);
    _thresholdNoChangeInMs = thresholdNoChangeInMs;
  }

  @Override
  public void run()
  {
    // For each record in status update and error node
    // TODO: for now the status updates are dumped to cluster manager log4j log.
    // We need to think if we should create per-instance log files that contains
    // per-instance statusUpdates
    // and errors
    logger.info("Scannning status updates ...");
    try
    {
      HelixDataAccessor accessor = _manager.getHelixDataAccessor();
      Builder keyBuilder = accessor.keyBuilder();

      List<String> instances = accessor.getChildNames(keyBuilder.instanceConfigs());
      for (String instanceName : instances)
      {
        scanPath(HelixUtil.getInstancePropertyPath(_manager.getClusterName(), instanceName,
            PropertyType.STATUSUPDATES), _thresholdNoChangeInMs);
        scanPath(HelixUtil.getInstancePropertyPath(_manager.getClusterName(), instanceName,
            PropertyType.ERRORS), _thresholdNoChangeInMs * 3);
      }
      scanPath(HelixUtil.getControllerPropertyPath(_manager.getClusterName(),
          PropertyType.STATUSUPDATES_CONTROLLER), _thresholdNoChangeInMs);

      scanPath(HelixUtil.getControllerPropertyPath(_manager.getClusterName(),
          PropertyType.ERRORS_CONTROLLER), _thresholdNoChangeInMs * 3);
    } catch (Exception e)
    {
      logger.error(e);
    }
  }

  void scanPath(String path, int thresholdNoChangeInMs)
  {
    logger.info("Scannning path " + path);
    List<String> subPaths = _zkClient.getChildren(path);
    for (String subPath : subPaths)
    {
      try
      {
        String nextPath = path + "/" + subPath;
        List<String> subSubPaths = _zkClient.getChildren(nextPath);
        for (String subsubPath : subSubPaths)
        {
          try
          {
            checkAndDump(nextPath + "/" + subsubPath, thresholdNoChangeInMs);
          } catch (Exception e)
          {
            logger.error(e);
          }
        }
      } catch (Exception e)
      {
        logger.error(e);
      }
    }
  }

  void checkAndDump(String path, int thresholdNoChangeInMs)
  {
    List<String> subPaths = _zkClient.getChildren(path);
    if(subPaths.size() == 0)
    {
      subPaths.add("");
    }
    for (String subPath : subPaths)
    {
      String fullPath = subPath.length() > 0 ? path + "/" + subPath : path;
      Stat pathStat = _zkClient.getStat(fullPath);

      long lastModifiedTimeInMs = pathStat.getMtime();
      long nowInMs = new Date().getTime();
      // logger.info(nowInMs + " " + lastModifiedTimeInMs + " " + fullPath);

      // Check the last modified time
      if (nowInMs > lastModifiedTimeInMs)
      {
        long timeDiff = nowInMs - lastModifiedTimeInMs;
        if (timeDiff > thresholdNoChangeInMs)
        {
          logger.info("Dumping status update path " + fullPath + " " + timeDiff + "MS has passed");
          _zkClient.setZkSerializer(new ZNRecordSerializer());
          ZNRecord record = _zkClient.readData(fullPath);

          // dump the node content into log file
          ObjectMapper mapper = new ObjectMapper();
          SerializationConfig serializationConfig = mapper.getSerializationConfig();
          serializationConfig.set(SerializationConfig.Feature.INDENT_OUTPUT, true);

          StringWriter sw = new StringWriter();
          try
          {
            mapper.writeValue(sw, record);
            logger.info(sw.toString());
          } catch (Exception e)
          {
            logger.warn(
                    "Exception during serialization in ZKPathDataDumpTask.checkAndDump. This can mostly be ignored",
                    e);
          }
          // Delete the leaf data
          _zkClient.deleteRecursive(fullPath);
        }
      }
    }
  }
}
TOP

Related Classes of org.apache.helix.monitoring.ZKPathDataDumpTask

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.