Package com.aelitis.azureus.core.stats

Source Code of com.aelitis.azureus.core.stats.AzureusCoreStats

/*
* Created on 1 Nov 2006
* Created by Paul Gardner
* Copyright (C) 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* AELITIS, SAS au capital de 63.529,40 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/


package com.aelitis.azureus.core.stats;

import java.util.*;
import java.util.regex.Pattern;

import org.gudy.azureus2.core3.util.AEDiagnostics;
import org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.IndentWriter;
import org.gudy.azureus2.core3.util.Timer;
import org.gudy.azureus2.core3.util.TimerEvent;
import org.gudy.azureus2.core3.util.TimerEventPerformer;

import com.aelitis.azureus.core.util.CopyOnWriteList;
import com.aelitis.azureus.core.util.average.Average;
import com.aelitis.azureus.core.util.average.AverageFactory;

public class
AzureusCoreStats
{
  public static final int AVERAGE_PERIOD  = 1000;
 
  public static final String ST_ALL              = ".*";
 
    // DISK
 
  public static final String ST_DISK              = "disk.*";
  public static final String ST_DISK_READ_QUEUE_LENGTH    = "disk.read.queue.length"
  public static final String ST_DISK_READ_QUEUE_BYTES      = "disk.read.queue.bytes"
  public static final String ST_DISK_READ_REQUEST_COUNT    = "disk.read.request.count"
  public static final String ST_DISK_READ_REQUEST_SINGLE    = "disk.read.request.single"
  public static final String ST_DISK_READ_REQUEST_MULTIPLE  = "disk.read.request.multiple"
  public static final String ST_DISK_READ_REQUEST_BLOCKS    = "disk.read.request.blocks"
  public static final String ST_DISK_READ_BYTES_TOTAL      = "disk.read.bytes.total"
  public static final String ST_DISK_READ_BYTES_SINGLE    = "disk.read.bytes.single"
  public static final String ST_DISK_READ_BYTES_MULTIPLE    = "disk.read.bytes.multiple"
  public static final String ST_DISK_READ_IO_TIME        = "disk.read.io.time"
  public static final String ST_DISK_READ_IO_COUNT      = "disk.read.io.count"
 
  public static final String ST_DISK_WRITE_QUEUE_LENGTH    = "disk.write.queue.length"
  public static final String ST_DISK_WRITE_QUEUE_BYTES    = "disk.write.queue.bytes"
  public static final String ST_DISK_WRITE_REQUEST_COUNT    = "disk.write.request.count"
  public static final String ST_DISK_WRITE_REQUEST_BLOCKS    = "disk.write.request.blocks"
  public static final String ST_DISK_WRITE_BYTES_TOTAL    = "disk.write.bytes.total"
  public static final String ST_DISK_WRITE_BYTES_SINGLE    = "disk.write.bytes.single"
  public static final String ST_DISK_WRITE_BYTES_MULTIPLE    = "disk.write.bytes.multiple"
  public static final String ST_DISK_WRITE_IO_TIME      = "disk.write.io.time"
  public static final String ST_DISK_WRITE_IO_COUNT      = "disk.write.io.count"
 
    // NETWORK
 
  public static final String ST_NET_WRITE_CONTROL_WAIT_COUNT      = "net.write.control.wait.count"
  public static final String ST_NET_WRITE_CONTROL_NP_COUNT      = "net.write.control.np.count"
  public static final String ST_NET_WRITE_CONTROL_P_COUNT        = "net.write.control.p.count";   
  public static final String ST_NET_WRITE_CONTROL_ENTITY_COUNT    = "net.write.control.entity.count"
  public static final String ST_NET_WRITE_CONTROL_CON_COUNT      = "net.write.control.con.count"
  public static final String ST_NET_WRITE_CONTROL_READY_CON_COUNT    = "net.write.control.ready.con.count"
  public static final String ST_NET_WRITE_CONTROL_READY_BYTE_COUNT  = "net.write.control.ready.byte.count"
     
  public static final String ST_NET_READ_CONTROL_LOOP_COUNT      = "net.read.control.loop.count"
  public static final String ST_NET_READ_CONTROL_NP_COUNT        = "net.read.control.np.count"
  public static final String ST_NET_READ_CONTROL_P_COUNT        = "net.read.control.p.count"
  public static final String ST_NET_READ_CONTROL_WAIT_COUNT      = "net.read.control.wait.count"
  public static final String ST_NET_READ_CONTROL_ENTITY_COUNT      = "net.read.control.entity.count"
  public static final String ST_NET_READ_CONTROL_CON_COUNT      = "net.read.control.con.count"
  public static final String ST_NET_READ_CONTROL_READY_CON_COUNT    = "net.read.control.ready.con.count"
 
    // TCP
 
  public static final String ST_NET_TCP_OUT_CONNECT_QUEUE_LENGTH    = "net.tcp.outbound.connect.queue.length"
  public static final String ST_NET_TCP_OUT_PENDING_QUEUE_LENGTH    = "net.tcp.outbound.pending.queue.length"
  public static final String ST_NET_TCP_OUT_CANCEL_QUEUE_LENGTH    = "net.tcp.outbound.cancel.queue.length"
  public static final String ST_NET_TCP_OUT_CLOSE_QUEUE_LENGTH    = "net.tcp.outbound.close.queue.length"

  public static final String ST_NET_TCP_SELECT_WRITE_COUNT      = "net.tcp.select.write.count";
  public static final String ST_NET_TCP_SELECT_READ_COUNT        = "net.tcp.select.read.count";

    // HTTP
 
  public static final String ST_NET_HTTP_IN_REQUEST_COUNT        = "net.http.inbound.request.count";     
  public static final String ST_NET_HTTP_IN_REQUEST_OK_COUNT      = "net.http.inbound.request.ok.count";   
  public static final String ST_NET_HTTP_IN_REQUEST_INVALID_COUNT    = "net.http.inbound.request.invalid.count";   
  public static final String ST_NET_HTTP_IN_REQUEST_WEBSEED_COUNT    = "net.http.inbound.request.webseed.count"
  public static final String ST_NET_HTTP_IN_REQUEST_GETRIGHT_COUNT  = "net.http.inbound.request.getright.count"
 
    // Peer Control
 
 
  public static final String ST_PEER_CONTROL_SCHEDULE_COUNT  = "peer.control.schedule.count";
  public static final String ST_PEER_CONTROL_LOOP_COUNT    = "peer.control.loop.count";
  public static final String ST_PEER_CONTROL_YIELD_COUNT    = "peer.control.yield.count";
  public static final String ST_PEER_CONTROL_WAIT_COUNT    = "peer.control.wait.count";
  public static final String ST_PEER_CONTROL_WAIT_TIME    = "peer.control.wait.time";

    // Peer Manager
 
  public static final String ST_PEER_MANAGER_COUNT          = "peer.manager.count";
  public static final String ST_PEER_MANAGER_PEER_COUNT        = "peer.manager.peer.count";
  public static final String ST_PEER_MANAGER_PEER_SNUBBED_COUNT    = "peer.manager.peer.snubbed.count";
  public static final String ST_PEER_MANAGER_PEER_STALLED_DISK_COUNT  = "peer.manager.peer.stalled.disk.count";

    // Tracker
 
  public static final String ST_TRACKER_READ_BYTES    = "tracker.read.bytes.total";
  public static final String ST_TRACKER_WRITE_BYTES    = "tracker.write.bytes.total";
  public static final String ST_TRACKER_ANNOUNCE_COUNT  = "tracker.announce.count";
  public static final String ST_TRACKER_ANNOUNCE_TIME    = "tracker.announce.time";
  public static final String ST_TRACKER_SCRAPE_COUNT    = "tracker.scrape.count";
  public static final String ST_TRACKER_SCRAPE_TIME    = "tracker.scrape.time";

    // xfer (persistent)
 
  public static final String ST_XFER_UPLOADED_PROTOCOL_BYTES    = "xfer.upload.protocol.bytes.total";
  public static final String ST_XFER_UPLOADED_DATA_BYTES      = "xfer.upload.data.bytes.total";
  public static final String ST_XFER_DOWNLOADED_PROTOCOL_BYTES  = "xfer.download.protocol.bytes.total";
  public static final String ST_XFER_DOWNLOADED_DATA_BYTES    = "xfer.download.data.bytes.total";

 
  public static final String  POINT     = "Point";
  public static final String  CUMULATIVE   = "Cumulative";
 
  private static final List    stats_names  = new ArrayList();
  private static final Map    stats_types  = new HashMap();
 
  private static final String[][] _ST_ALL = {
   
    { ST_DISK_READ_QUEUE_LENGTH,        POINT },
    { ST_DISK_READ_QUEUE_BYTES,          POINT },
    { ST_DISK_READ_REQUEST_COUNT,        CUMULATIVE },
    { ST_DISK_READ_REQUEST_SINGLE,        CUMULATIVE },
    { ST_DISK_READ_REQUEST_MULTIPLE,      CUMULATIVE },
    { ST_DISK_READ_REQUEST_BLOCKS,        CUMULATIVE },
    { ST_DISK_READ_BYTES_TOTAL,          CUMULATIVE },
    { ST_DISK_READ_BYTES_SINGLE,        CUMULATIVE },
    { ST_DISK_READ_BYTES_MULTIPLE,        CUMULATIVE },
    { ST_DISK_READ_IO_TIME,            CUMULATIVE },
    { ST_DISK_READ_IO_COUNT,          CUMULATIVE },
       
    { ST_DISK_WRITE_QUEUE_LENGTH,        POINT },
    { ST_DISK_WRITE_QUEUE_BYTES,        POINT },
    { ST_DISK_WRITE_REQUEST_COUNT,        CUMULATIVE },
    { ST_DISK_WRITE_REQUEST_BLOCKS,        CUMULATIVE },
    { ST_DISK_WRITE_BYTES_TOTAL,        CUMULATIVE },
    { ST_DISK_WRITE_BYTES_SINGLE,        CUMULATIVE },
    { ST_DISK_WRITE_BYTES_MULTIPLE,        CUMULATIVE },
    { ST_DISK_WRITE_IO_TIME,          CUMULATIVE },
    { ST_DISK_WRITE_IO_COUNT,          CUMULATIVE },

    { ST_NET_WRITE_CONTROL_WAIT_COUNT,      CUMULATIVE },
    { ST_NET_WRITE_CONTROL_P_COUNT,        CUMULATIVE },
    { ST_NET_WRITE_CONTROL_NP_COUNT,      CUMULATIVE },
    { ST_NET_WRITE_CONTROL_ENTITY_COUNT,    POINT },
    { ST_NET_WRITE_CONTROL_CON_COUNT,      POINT },
    { ST_NET_WRITE_CONTROL_READY_CON_COUNT,    POINT },
    { ST_NET_WRITE_CONTROL_READY_BYTE_COUNT,  POINT },

    { ST_NET_READ_CONTROL_LOOP_COUNT,      CUMULATIVE },
    { ST_NET_READ_CONTROL_P_COUNT,        CUMULATIVE },
    { ST_NET_READ_CONTROL_NP_COUNT,        CUMULATIVE },
    { ST_NET_READ_CONTROL_WAIT_COUNT,      CUMULATIVE },
    { ST_NET_READ_CONTROL_ENTITY_COUNT,      POINT },
    { ST_NET_READ_CONTROL_CON_COUNT,      POINT },
    { ST_NET_READ_CONTROL_READY_CON_COUNT,    POINT },
   
    { ST_NET_TCP_OUT_CONNECT_QUEUE_LENGTH,    POINT },
    { ST_NET_TCP_OUT_PENDING_QUEUE_LENGTH,    POINT },
    { ST_NET_TCP_OUT_CANCEL_QUEUE_LENGTH,    POINT },
    { ST_NET_TCP_OUT_CLOSE_QUEUE_LENGTH,    POINT },
   
    { ST_NET_TCP_SELECT_WRITE_COUNT,      CUMULATIVE },
    { ST_NET_TCP_SELECT_READ_COUNT,        CUMULATIVE },
   
    { ST_NET_HTTP_IN_REQUEST_COUNT,        CUMULATIVE },
    { ST_NET_HTTP_IN_REQUEST_OK_COUNT,      CUMULATIVE },
    { ST_NET_HTTP_IN_REQUEST_INVALID_COUNT,    CUMULATIVE },
    { ST_NET_HTTP_IN_REQUEST_WEBSEED_COUNT,    CUMULATIVE },
    { ST_NET_HTTP_IN_REQUEST_GETRIGHT_COUNT,  CUMULATIVE },
   
    { ST_PEER_CONTROL_SCHEDULE_COUNT,      CUMULATIVE },
    { ST_PEER_CONTROL_LOOP_COUNT,        CUMULATIVE },
    { ST_PEER_CONTROL_YIELD_COUNT,        CUMULATIVE },
    { ST_PEER_CONTROL_WAIT_COUNT,        CUMULATIVE },
    { ST_PEER_CONTROL_WAIT_TIME,        CUMULATIVE },
   
    { ST_PEER_MANAGER_COUNT,          POINT },
    { ST_PEER_MANAGER_PEER_COUNT,        POINT },
    { ST_PEER_MANAGER_PEER_SNUBBED_COUNT,    POINT },
    { ST_PEER_MANAGER_PEER_STALLED_DISK_COUNT,  POINT },
   
    { ST_TRACKER_READ_BYTES,          CUMULATIVE },
    { ST_TRACKER_WRITE_BYTES,          CUMULATIVE },
    { ST_TRACKER_ANNOUNCE_COUNT,        CUMULATIVE },
    { ST_TRACKER_ANNOUNCE_TIME,          CUMULATIVE },
    { ST_TRACKER_SCRAPE_COUNT,          CUMULATIVE },
    { ST_TRACKER_SCRAPE_TIME,          CUMULATIVE },

    { ST_XFER_UPLOADED_PROTOCOL_BYTES,      CUMULATIVE },
    { ST_XFER_UPLOADED_DATA_BYTES,        CUMULATIVE },
    { ST_XFER_DOWNLOADED_PROTOCOL_BYTES,    CUMULATIVE },
    { ST_XFER_DOWNLOADED_DATA_BYTES,      CUMULATIVE }
  };
 
  static{
   
    addStatsDefinitions( _ST_ALL );
   
    AEDiagnostics.addEvidenceGenerator(
      new AEDiagnosticsEvidenceGenerator()
      {
          public void
          generate(
            IndentWriter writer )
          {
          writer.println( "Stats" );
           
          boolean  turn_on_averages = !getEnableAverages();

          try{
            writer.indent()
           
            if ( turn_on_averages ){
             
              setEnableAverages( true );
             
              try{
                Thread.sleep( AVERAGE_PERIOD * 5 );
               
              }catch( Throwable e ){
              }
            }
                       
            Set  types = new HashSet();
           
            types.add( ST_ALL );
           
            Map  reply = getStats( types );
           
            Iterator  it = reply.entrySet().iterator();
           
            List  lines = new ArrayList();
           
            while( it.hasNext()){
             
              Map.Entry  entry = (Map.Entry)it.next();
             
              lines.add( entry.getKey() + " -> " + entry.getValue());
            }
           
            Collections.sort( lines );
       
            for ( int i=0;i<lines.size();i++){

              writer.println((String)lines.get(i));
            }
           
          }finally{
           
            if ( turn_on_averages ){
             
              setEnableAverages( false );
            }
           
            writer.exdent();
          }
          }
      });
  }
 
  private static final CopyOnWriteList  providers   = new CopyOnWriteList();
 
  private static  Map  averages  = new HashMap();
 
  private static boolean   enable_averages;
  private static Timer  average_timer;
 
  private static CopyOnWriteList provider_listeners = new CopyOnWriteList();
  private static CopyOnWriteList derived_generators = new CopyOnWriteList();
 
  public static void
  addStatsDefinitions(
    String[][]    stats )
  {
    for (int i=0;i<stats.length;i++){
     
      String  name = stats[i][0];
     
      stats_names.add( name );
     
      stats_types.put( name, stats[i][1] );
    }
  }
 
  public static Map
  getStats(
    Set    types )
  {
    Set  expanded = new HashSet();
   
    Iterator  it = types.iterator();
   
    while( it.hasNext()){
     
      String  type = (String)it.next();
     
      if ( type.endsWith( ".average" )){
       
        type = type.substring(0,type.length()-8);
      }
     
      if ( !type.endsWith("*")){
       
        type = type + ".*";
      }
     
      Pattern pattern = Pattern.compile( type );
           
      for (int i=0;i<stats_names.size();i++){
       
        String  s = (String)stats_names.get(i);
       
        if ( pattern.matcher( s ).matches()){
         
          expanded.add( s );
        }
      }
     
      Iterator provider_it = providers.iterator();
     
      while( provider_it.hasNext()){
       
        Object[]  provider_entry = (Object[])provider_it.next();
       
        Set provider_types = (Set)provider_entry[0];
       
        Iterator pt_it = provider_types.iterator();
       
        while( pt_it.hasNext()){
         
          String  s = (String)pt_it.next();
         
          if ( pattern.matcher( s ).matches()){
           
            expanded.add( s );
          }
        }
      }
     
      Iterator derived_it = derived_generators.iterator();
     
      while( derived_it.hasNext()){
       
        try{
         
          ((derivedStatsGenerator)derived_it.next()).match( pattern, expanded );
         
        }catch( Throwable e ){
         
          Debug.printStackTrace( e );
        }
      }
    }
   
    Map  result = getStatsSupport( expanded );
   
    Map  ave = averages;
   
    if ( ave != null ){
     
      it = result.keySet().iterator();
     
      Map  ave_results = new HashMap();
     
      while( it.hasNext()){
               
        String  key = (String)it.next();
       
        Object[]  a_entry = (Object[])ave.get( key );
       
        if ( a_entry != null ){
         
          Average  average = (Average)a_entry[0];
         
          ave_results.put( key + ".average", new Long((long)average.getAverage()));
        }
      }
           
      result.putAll( ave_results );
    }
   
    Iterator derived_it = derived_generators.iterator();
       
    while( derived_it.hasNext()){
     
      try{
       
        ((derivedStatsGenerator)derived_it.next()).generate( result );
       
      }catch( Throwable e ){
       
        Debug.printStackTrace( e );
      }
    }
   
    return( result );
  }
 
  protected static Map
  getStatsSupport(
    Set    types )
  {
    Map  result = new HashMap();
   
    Iterator it = providers.iterator();
   
    while( it.hasNext()){
     
      Object[]  provider_entry = (Object[])it.next();
     
      Map  provider_result = new HashMap();

      Set  target_types;
     
      if ( types == null ){
       
        target_types = (Set)provider_entry[0];
      }else{
     
        target_types = types;
      }
     
      try{
        ((AzureusCoreStatsProvider)provider_entry[1]).updateStats( target_types, provider_result );
       
        Iterator pit = provider_result.entrySet().iterator();
       
        while( pit.hasNext()){
         
          Map.Entry  pe = (Map.Entry)pit.next();
         
          String  key = (String)pe.getKey();
          Object  obj  = pe.getValue();
         
          if ( obj instanceof Long ){
           
            Long  old = (Long)result.get(key);
           
            if ( old == null ){
             
              result.put( key, obj );
             
            }else{
             
              long  v = ((Long)obj).longValue();
             
              result.put( key, new Long( v + old.longValue()));
            }
          }else{
           
            result.put( key, obj );
          }
        }
      }catch( Throwable e ){
       
        Debug.printStackTrace(e);
      }
    }
   
    return( result );
  }
 
  public static void
  registerProvider(
    Set              types,
    AzureusCoreStatsProvider  provider )
  {
    synchronized( providers ){
     
      providers.add( new Object[]{ types, provider });
    }
   
    fireProvidersChangeListeners();
  }

  public static void
  addProvidersChangeListener(
    providersChangeListener    l )
  {
    provider_listeners.add( l );
  }

  protected static void
  fireProvidersChangeListeners()
  {
    Iterator it = provider_listeners.iterator();
   
    while( it.hasNext()){
     
      try{
        ((providersChangeListener)it.next()).providersChanged();
       
      }catch( Throwable e ){
       
        Debug.printStackTrace(e);
      }
    }
  }
 
  public static void
  registerDerivedStatsGenerator(
    derivedStatsGenerator  gen )
  {
    derived_generators.add( gen );
  }
 
  public static synchronized void
  setEnableAverages(
    boolean    enabled )
  {
    if ( enabled == enable_averages ){
     
      return;
    }
   
    enable_averages = enabled;
   
    if ( enabled ){
     
      if ( average_timer == null ){
       
        average_timer = new Timer( "AzureusCoreStats:average" );
       
        averages = new HashMap();
       
        average_timer.addPeriodicEvent(
          AVERAGE_PERIOD,
          new TimerEventPerformer()
          {
            private Map  ave = averages;

            public void
            perform(
              TimerEvent  event )
            {
              Map  stats = getStatsSupport( null );
                               
              Iterator  it = stats.entrySet().iterator();
             
              boolean  new_averages = false;
             
              while( it.hasNext()){
               
                Map.Entry  entry = (Map.Entry)it.next();
               
                String  key   = (String)entry.getKey();
                Object  value   = entry.getValue();
               
                if ( value instanceof Long ){
                 
                  long  last_value;
                  Average  a;
                  boolean  new_average;
                 
                  Object[] a_entry = (Object[])ave.get( key );
                 
                  if ( a_entry == null ){
 
                    a       = AverageFactory.MovingImmediateAverage( 10 );
                    last_value  = 0;
                   
                    a_entry = new Object[]{ a, value };
                   
                    ave.put( key, a_entry );
                   
                    new_averages = new_average = true;
                   
                  }else{
                    a      = (Average)a_entry[0];
                    last_value  = ((Long)a_entry[1]).longValue();
                   
                    new_average = false;
                  }
                 
                  if ( stats_types.get( key ) == CUMULATIVE ){
                 
                      // skip initial value as 'last_value' is invalid
                   
                    if ( !new_average ){
                   
                      a.update(((Long)value).longValue() - last_value);
                    }
                  }else{
                   
                    a.update(((Long)value).longValue());

                  }
                 
                  a_entry[1] = value;
                }
              }
             
              if ( new_averages ){
               
                fireProvidersChangeListeners();
              }
            }
          });
      }
    }else{
     
      if ( average_timer != null ){
       
        average_timer.destroy();
       
        average_timer = null;
       
        averages  = null;
      }
    }
  }
 
  public static boolean
  getEnableAverages()
  {
    return( enable_averages );
  }
 
  public interface
  providersChangeListener
  {
    public void
    providersChanged();
  }
 
  public interface
  derivedStatsGenerator
  {
    public void
    match(
      Pattern    p,
      Set      required );
   
    public void
    generate(
      Map  map );
  }
}
TOP

Related Classes of com.aelitis.azureus.core.stats.AzureusCoreStats

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.