    001/*
    002 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved.
    003 *
    004 * Project and contact information: http://www.cascading.org/
    005 *
    006 * This file is part of the Cascading project.
    007 *
    008 * Licensed under the Apache License, Version 2.0 (the "License");
    009 * you may not use this file except in compliance with the License.
    010 * You may obtain a copy of the License at
    011 *
    012 *     http://www.apache.org/licenses/LICENSE-2.0
    013 *
    014 * Unless required by applicable law or agreed to in writing, software
    015 * distributed under the License is distributed on an "AS IS" BASIS,
    016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    017 * See the License for the specific language governing permissions and
    018 * limitations under the License.
    019 */
    020
    021package cascading.stats;
    022
    023import java.util.ArrayList;
    024import java.util.Collection;
    025import java.util.HashSet;
    026import java.util.LinkedHashMap;
    027import java.util.List;
    028import java.util.Map;
    029import java.util.Set;
    030
    031import cascading.flow.Flow;
    032import cascading.management.state.ClientState;
    033import cascading.property.AppProps;
    034import cascading.util.ProcessLogger;
    035
    036/** Class FlowStats collects {@link cascading.flow.Flow} specific statistics. */
    037public class FlowStats extends CascadingStats<FlowStepStats>
    038  {
    039  final Flow flow;
    040  final Map<String, FlowStepStats> flowStepStatsMap = new LinkedHashMap<>(); // retains topological order
    041
    042  public FlowStats( Flow flow, ClientState clientState )
    043    {
    044    super( flow.getName(), clientState );
    045    this.flow = flow;
    046    }
    047
    048  @Override
    049  protected ProcessLogger getProcessLogger()
    050    {
    051    if( flow != null && flow instanceof ProcessLogger )
    052      return (ProcessLogger) flow;
    053
    054    return ProcessLogger.NULL;
    055    }
    056
    057  public Map<Object, Object> getFlowProperties()
    058    {
    059    return flow.getConfigAsProperties();
    060    }
    061
    062  public String getAppID()
    063    {
    064    return AppProps.getApplicationID( getFlowProperties() );
    065    }
    066
    067  public String getAppName()
    068    {
    069    return AppProps.getApplicationName( getFlowProperties() );
    070    }
    071
    072  @Override
    073  public String getID()
    074    {
    075    return flow.getID();
    076    }
    077
    078  @Override
    079  public Type getType()
    080    {
    081    return Type.FLOW;
    082    }
    083
    084  public Flow getFlow()
    085    {
    086    return flow;
    087    }
    088
    089  @Override
    090  public synchronized void recordInfo()
    091    {
    092    clientState.recordFlow( flow );
    093    }
    094
    095  public void addStepStats( FlowStepStats flowStepStats )
    096    {
    097    flowStepStatsMap.put( flowStepStats.getID(), flowStepStats );
    098    }
    099
    100  /**
    101   * Method getStepStats returns the stepStats owned by this FlowStats.
    102   *
    103   * @return the stepStats (type List<StepStats>) of this FlowStats object.
    104   */
    105  public List<FlowStepStats> getFlowStepStats()
    106    {
    107    return new ArrayList<>( flowStepStatsMap.values() );
    108    }
    109
    110  /**
    111   * Method getStepsCount returns the number of steps this Flow executed.
    112   *
    113   * @return the stepsCount (type int) of this FlowStats object.
    114   */
    115  public int getStepsCount()
    116    {
    117    return flowStepStatsMap.size();
    118    }
    119
    120  @Override
    121  public long getLastSuccessfulCounterFetchTime()
    122    {
    123    long max = -1;
    124
    125    for( FlowStepStats flowStepStats : flowStepStatsMap.values() )
    126      max = Math.max( max, flowStepStats.getLastSuccessfulCounterFetchTime() );
    127
    128    return max;
    129    }
    130
    131  @Override
    132  public Collection<String> getCounterGroups()
    133    {
    134    Set<String> results = new HashSet<String>();
    135
    136    for( FlowStepStats flowStepStats : flowStepStatsMap.values() )
    137      results.addAll( flowStepStats.getCounterGroups() );
    138
    139    return results;
    140    }
    141
    142  @Override
    143  public Collection<String> getCounterGroupsMatching( String regex )
    144    {
    145    Set<String> results = new HashSet<String>();
    146
    147    for( FlowStepStats flowStepStats : flowStepStatsMap.values() )
    148      results.addAll( flowStepStats.getCounterGroupsMatching( regex ) );
    149
    150    return results;
    151    }
    152
    153  @Override
    154  public Collection<String> getCountersFor( String group )
    155    {
    156    Set<String> results = new HashSet<String>();
    157
    158    for( FlowStepStats flowStepStats : flowStepStatsMap.values() )
    159      results.addAll( flowStepStats.getCountersFor( group ) );
    160
    161    return results;
    162    }
    163
    164  @Override
    165  public long getCounterValue( Enum counter )
    166    {
    167    long value = 0;
    168
    169    for( FlowStepStats flowStepStats : flowStepStatsMap.values() )
    170      value += flowStepStats.getCounterValue( counter );
    171
    172    return value;
    173    }
    174
    175  @Override
    176  public long getCounterValue( String group, String counter )
    177    {
    178    long value = 0;
    179
    180    for( FlowStepStats flowStepStats : flowStepStatsMap.values() )
    181      value += flowStepStats.getCounterValue( group, counter );
    182
    183    return value;
    184    }
    185
    186  @Override
    187  public void captureDetail( Type depth )
    188    {
    189    if( !getType().isChild( depth ) )
    190      return;
    191
    192    for( FlowStepStats flowStepStats : flowStepStatsMap.values() )
    193      flowStepStats.captureDetail( depth );
    194    }
    195
    196  @Override
    197  public Collection<FlowStepStats> getChildren()
    198    {
    199    return flowStepStatsMap.values();
    200    }
    201
    202  @Override
    203  public FlowStepStats getChildWith( String id )
    204    {
    205    return flowStepStatsMap.get( id );
    206    }
    207
    208  @Override
    209  protected String getStatsString()
    210    {
    211    return super.getStatsString() + ", stepsCount=" + getStepsCount();
    212    }
    213
    214  @Override
    215  public String toString()
    216    {
    217    return "Flow{" + getStatsString() + '}';
    218    }
    219
    220  @Override
    221  public int hashCode()
    222    {
    223    return getID().hashCode();
    224    }
    225
    226  @Override
    227  public boolean equals( Object object )
    228    {
    229    if( this == object )
    230      return true;
    231    if( object == null || !( object instanceof FlowStats ) )
    232      return false;
    233
    234    return getID().equals( ( (FlowStats) object ).getID() );
    235    }
    236  }