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