/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2016 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * Licensed 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.pentaho.di.core.metrics; import java.util.ArrayList; import java.util.Queue; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.pentaho.di.core.logging.LoggingObjectInterface; import org.pentaho.di.core.logging.LoggingRegistry; import org.pentaho.di.core.logging.Metrics; import org.pentaho.di.core.logging.MetricsInterface; import org.pentaho.di.core.logging.MetricsRegistry; public class MetricsUtil { /** * Calculates the durations between the START and STOP snapshots for a given metric description * * @param logChannelId * the id of the log channel to investigate * @param metricsCode * the metric code * @return the duration in ms */ public static List<MetricsDuration> getDuration( String logChannelId, Metrics metric ) { List<MetricsDuration> durations = new ArrayList<MetricsDuration>(); Queue<MetricsSnapshotInterface> metrics = MetricsRegistry.getInstance().getSnapshotList( logChannelId ); MetricsSnapshotInterface start = null; Iterator<MetricsSnapshotInterface> iterator = metrics.iterator(); while ( iterator.hasNext() ) { MetricsSnapshotInterface snapshot = iterator.next(); if ( snapshot.getMetric().equals( metric ) ) { if ( snapshot.getMetric().getType() == MetricsSnapshotType.START ) { if ( start != null ) { // We didn't find a stop for the previous start so add it with a null duration durations.add( new MetricsDuration( start.getDate(), snapshot.getMetric().getDescription(), snapshot .getSubject(), logChannelId, null ) ); } start = snapshot; } else { long duration = snapshot.getDate().getTime() - start.getDate().getTime(); durations.add( new MetricsDuration( start.getDate(), snapshot.getMetric().getDescription(), snapshot .getSubject(), logChannelId, duration ) ); start = null; } } } // Now aggregate even further, calculate total times... // Map<String, MetricsDuration> map = new HashMap<String, MetricsDuration>(); for ( MetricsDuration duration : durations ) { String key = duration.getSubject() == null ? duration.getDescription() : duration.getDescription() + " / " + duration.getSubject(); MetricsDuration agg = map.get( key ); if ( agg == null ) { map.put( key, duration ); } else { agg.setDuration( agg.getDuration() + duration.getDuration() ); } } // If we already have return new ArrayList<MetricsDuration>( map.values() ); } public static List<MetricsDuration> getAllDurations( String parentLogChannelId ) { List<MetricsDuration> durations = new ArrayList<MetricsDuration>(); List<String> logChannelIds = LoggingRegistry.getInstance().getLogChannelChildren( parentLogChannelId ); for ( String logChannelId : logChannelIds ) { LoggingObjectInterface object = LoggingRegistry.getInstance().getLoggingObject( logChannelId ); if ( object != null ) { durations.addAll( getDurations( logChannelId ) ); } } return durations; } /** * Calculates the durations between the START and STOP snapshots per metric description and subject (if any) * * @param logChannelId * the id of the log channel to investigate * @return the duration in ms */ public static List<MetricsDuration> getDurations( String logChannelId ) { Map<String, MetricsSnapshotInterface> last = new HashMap<String, MetricsSnapshotInterface>(); Map<String, MetricsDuration> map = new HashMap<String, MetricsDuration>(); Queue<MetricsSnapshotInterface> metrics = MetricsRegistry.getInstance().getSnapshotList( logChannelId ); Iterator<MetricsSnapshotInterface> iterator = metrics.iterator(); while ( iterator.hasNext() ) { MetricsSnapshotInterface snapshot = iterator.next(); // Do we have a start point in the map? // String key = snapshot.getMetric().getDescription() + ( snapshot.getSubject() == null ? "" : ( " - " + snapshot.getSubject() ) ); MetricsSnapshotInterface lastSnapshot = last.get( key ); if ( lastSnapshot == null ) { lastSnapshot = snapshot; last.put( key, lastSnapshot ); } else { // If we have a START-STOP range, calculate the duration and add it to the duration map... // MetricsInterface metric = lastSnapshot.getMetric(); if ( metric.getType() == MetricsSnapshotType.START && snapshot.getMetric().getType() == MetricsSnapshotType.STOP ) { long extraDuration = snapshot.getDate().getTime() - lastSnapshot.getDate().getTime(); MetricsDuration metricsDuration = map.get( key ); if ( metricsDuration == null ) { metricsDuration = new MetricsDuration( lastSnapshot.getDate(), metric.getDescription(), lastSnapshot.getSubject(), logChannelId, extraDuration ); } else { metricsDuration.setDuration( metricsDuration.getDuration() + extraDuration ); metricsDuration.incrementCount(); if ( metricsDuration.getEndDate().getTime() < snapshot.getDate().getTime() ) { metricsDuration.setEndDate( snapshot.getDate() ); } } map.put( key, metricsDuration ); } } } return new ArrayList<MetricsDuration>( map.values() ); } public static List<MetricsSnapshotInterface> getResultsList( Metrics metric ) { List<MetricsSnapshotInterface> snapshots = new ArrayList<MetricsSnapshotInterface>(); Map<String, Map<String, MetricsSnapshotInterface>> snapshotMaps = MetricsRegistry.getInstance().getSnapshotMaps(); Iterator<Map<String, MetricsSnapshotInterface>> mapsIterator = snapshotMaps.values().iterator(); while ( mapsIterator.hasNext() ) { Map<String, MetricsSnapshotInterface> map = mapsIterator.next(); Iterator<MetricsSnapshotInterface> snapshotIterator = map.values().iterator(); while ( snapshotIterator.hasNext() ) { MetricsSnapshotInterface snapshot = snapshotIterator.next(); if ( snapshot.getMetric().equals( metric ) ) { snapshots.add( snapshot ); } } } return snapshots; } public static Long getResult( Metrics metric ) { Map<String, Map<String, MetricsSnapshotInterface>> snapshotMaps = MetricsRegistry.getInstance().getSnapshotMaps(); Iterator<Map<String, MetricsSnapshotInterface>> mapsIterator = snapshotMaps.values().iterator(); while ( mapsIterator.hasNext() ) { Map<String, MetricsSnapshotInterface> map = mapsIterator.next(); Iterator<MetricsSnapshotInterface> snapshotIterator = map.values().iterator(); while ( snapshotIterator.hasNext() ) { MetricsSnapshotInterface snapshot = snapshotIterator.next(); if ( snapshot.getMetric().equals( metric ) ) { return snapshot.getValue(); } } } return null; } }