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  }