Package org.apache.hadoop.chukwa.datacollection.adaptor

Source Code of org.apache.hadoop.chukwa.datacollection.adaptor.FileAdaptor

/*
* 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.
*/

package org.apache.hadoop.chukwa.datacollection.adaptor;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.hadoop.chukwa.ChunkImpl;
import org.apache.hadoop.chukwa.datacollection.ChunkReceiver;
import org.apache.hadoop.chukwa.datacollection.agent.ChukwaAgent;
import org.apache.hadoop.conf.Configuration;
import org.apache.log4j.Logger;


class FileAdaptorTailer extends Thread {
  static Logger log = Logger.getLogger(FileAdaptorTailer.class);
  private List<FileAdaptor> adaptors = null;
  private static Configuration conf = null;
  private Object lock = new Object();
 
  /**
   * How often to call each adaptor.
   */
  int DEFAULT_SAMPLE_PERIOD_MS = 1000 * 10;
  int SAMPLE_PERIOD_MS = DEFAULT_SAMPLE_PERIOD_MS;

 
  public FileAdaptorTailer() {
   
    if (conf == null) {
      ChukwaAgent agent = ChukwaAgent.getAgent();
      if (agent != null) {
        conf = agent.getConfiguration();
        if (conf != null) {
          SAMPLE_PERIOD_MS = conf.getInt(
              "chukwaAgent.adaptor.context.switch.time",
              DEFAULT_SAMPLE_PERIOD_MS);
        }
      }
    }
   
    // iterations are much more common than adding a new adaptor
    adaptors = new CopyOnWriteArrayList<FileAdaptor>();

    setDaemon(true);
    start();// start the FileAdaptorTailer thread
  }
  @Override
  public void run() {
    while(true) {
      try {

        while (adaptors.size() == 0) {
          synchronized (lock) {
            try {
              log.info("Waiting queue is empty");
              lock.wait();
            } catch (InterruptedException e) {
              // do nothing
            }
          }
        }
       
        long startTime = System.currentTimeMillis();
        for (FileAdaptor adaptor: adaptors) {
          log.info("calling sendFile for " + adaptor.toWatch.getCanonicalPath());
          adaptor.sendFile();
        }
       
        long timeToReadFiles = System.currentTimeMillis() - startTime;
        if (timeToReadFiles < SAMPLE_PERIOD_MS) {
          Thread.sleep(SAMPLE_PERIOD_MS);
        }
       
      }catch (Throwable e) {
        log.warn("Exception in FileAdaptorTailer:",e);
      }
    }
  }
 
  public void addFileAdaptor(FileAdaptor adaptor) {
    adaptors.add(adaptor);
    synchronized (lock) {
      lock.notifyAll();
    }
  }
 
  public void removeFileAdaptor(FileAdaptor adaptor) {
    adaptors.remove(adaptor);
  }
}

/**
* File Adaptor push small size file in one chunk to collector
*/
public class FileAdaptor extends AbstractAdaptor {

  static Logger log = Logger.getLogger(FileAdaptor.class);
  static FileAdaptorTailer tailer = null;
 
  static final int DEFAULT_TIMEOUT_PERIOD = 5*60*1000;
  static int TIMEOUT_PERIOD = DEFAULT_TIMEOUT_PERIOD;
 
  static {
    tailer = new FileAdaptorTailer();
  }
 
  private long startTime = 0;
  private long timeOut = 0;
 
  protected volatile boolean finished = false;
  File toWatch;
  protected RandomAccessFile reader = null;
  protected long fileReadOffset;
  protected boolean shutdownCalled = false;
 
  /**
   * The logical offset of the first byte of the file
   */
  private long offsetOfFirstByte = 0;

  public void start(long bytes) {
    // in this case params = filename
    log.info("adaptor id: " + adaptorID + " started file adaptor on file "
        + toWatch);
    this.startTime = System.currentTimeMillis();
    TIMEOUT_PERIOD = control.getConfiguration().getInt(
        "chukwaAgent.adaptor.fileadaptor.timeoutperiod",
        DEFAULT_TIMEOUT_PERIOD);
    this.timeOut = startTime + TIMEOUT_PERIOD;
   
    tailer.addFileAdaptor(this);
  }

  void sendFile() {
    long now = System.currentTimeMillis() ;
    long oneMinAgo = now - (60*1000);
    if (toWatch.exists()) {
     if (toWatch.lastModified() > oneMinAgo && now < timeOut) {
       log.info("Last modified time less than one minute, keep waiting");
       return;
     } else {
       try {
        
         long bufSize = toWatch.length();
         byte[] buf = new byte[(int) bufSize];
        
         reader = new RandomAccessFile(toWatch, "r");
         reader.read(buf);
         reader.close();
         reader = null;
        
         long fileTime = toWatch.lastModified();
         int bytesUsed = extractRecords(dest, 0, buf, fileTime);
         this.fileReadOffset = bytesUsed;
         finished = true;
         deregisterAndStop();
         cleanUp();
       } catch(Exception e) {
         log.warn("Exception while trying to read: " + toWatch.getAbsolutePath(),e);
       finally {
         if (reader != null) {
           try {
             reader.close();
           } catch (Exception e) {
            // do nothing
          }
           reader = null;
         }
       }
     }
    } else {
      if (now > timeOut) {
        finished = true;
        log.warn("Couldn't read this file: " + toWatch.getAbsolutePath());
        deregisterAndStop();
        cleanUp() ;
      }
    }
  }
 
  private void cleanUp() {
    tailer.removeFileAdaptor(this);
    if (reader != null) {
      try {
        reader.close();
      } catch (Exception e) {
       // do nothing
     }
      reader = null;
    }
  }
 

  @Override
  public long shutdown(AdaptorShutdownPolicy shutdownPolicy) {
    log.info("Enter Shutdown:" + shutdownPolicy.name()+ " - ObjectId:" + this);
    switch(shutdownPolicy) {
      case GRACEFULLY : {
        int retry = 0;
        while (!finished && retry < 60) {
          try {
            log.info("GRACEFULLY Retry:" + retry);
            Thread.sleep(1000);
            retry++;
          } catch (InterruptedException ex) {
          }
        }
      }
      break;
      case WAIT_TILL_FINISHED : {
        int retry = 0;
        while (!finished) {
          try {
            if (retry%100 == 0) {
              log.info("WAIT_TILL_FINISHED Retry:" + retry);
            }

            Thread.sleep(1000);
            retry++;
          } catch (InterruptedException ex) {
          }
        }
      }

      break;
      default :
        cleanUp();
        break;
    }
    log.info("Exist Shutdown:" + shutdownPolicy.name()+ " - ObjectId:" + this);
    return fileReadOffset + offsetOfFirstByte;
  }
 
  public String parseArgs(String params) {

    String[] words = params.split(" ");
    if (words.length > 1) {
      offsetOfFirstByte = Long.parseLong(words[0]);
      toWatch = new File(params.substring(words[0].length() + 1));
    } else {
      toWatch = new File(params);
    }
    return toWatch.getAbsolutePath();
  }

  /**
   * Extract records from a byte sequence
   *
   * @param eq
   *          the queue to stick the new chunk[s] in
   * @param buffOffsetInFile
   *          the byte offset in the stream at which buf[] begins
   * @param buf
   *          the byte buffer to extract records from
   * @return the number of bytes processed
   * @throws InterruptedException
   */
  protected int extractRecords(final ChunkReceiver eq, long buffOffsetInFile,
      byte[] buf, long fileTime) throws InterruptedException {
    final ChunkImpl chunk = new ChunkImpl(type, toWatch.getAbsolutePath(),
        buffOffsetInFile + buf.length, buf, this);
    chunk.addTag("time=\"" + fileTime + "\"");
    log.info("Adding " + toWatch.getAbsolutePath() + " to the queue");
    eq.add(chunk);
    log.info( toWatch.getAbsolutePath() + " added to the queue");
    return buf.length;
  }

  @Override
  public String getCurrentStatus() {
    return type.trim() + " " + offsetOfFirstByte + " " + toWatch.getPath();
  }

}
TOP

Related Classes of org.apache.hadoop.chukwa.datacollection.adaptor.FileAdaptor

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.