Author: burton Date: Wed Mar 9 11:37:12 2005 New Revision: 156674 URL: http://svn.apache.org/viewcvs?view=rev&rev=156674 Log: new rrd logging and graphing infra
Added: jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/ jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/BenchmarkSource.java jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/ExampleRandomSource.java jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTask.java jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTaskRunner.java jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Main.java (with props) jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Source.java Added: jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/BenchmarkSource.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/BenchmarkSource.java?view=auto&rev=156674 ============================================================================== --- jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/BenchmarkSource.java (added) +++ jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/BenchmarkSource.java Wed Mar 9 11:37:12 2005 @@ -0,0 +1,37 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * 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.apache.commons.benchmark.rrd; + +/** + * Represents an abstract datasource for an source for logging. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + * @version $Id: $ + */ +public abstract class BenchmarkSource { + + String title = null; + String description = null; + + /** + * Get the current value for this counter. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + */ + public abstract long getValue() throws Exception; + +} \ No newline at end of file Added: jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/ExampleRandomSource.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/ExampleRandomSource.java?view=auto&rev=156674 ============================================================================== --- jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/ExampleRandomSource.java (added) +++ jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/ExampleRandomSource.java Wed Mar 9 11:37:12 2005 @@ -0,0 +1,50 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * 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.apache.commons.benchmark.rrd; + +import java.util.*; + +/** + * Source which logs a random number between 0 and 100 for testing purposes. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + * @version $Id: $ + */ +public class ExampleRandomSource extends Source { + + private String foo = null; + + /** + * Get the current value for this counter. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + */ + public long getValue() throws Exception { + + Random r = new Random(); + return (long)(r.nextFloat() * 100F); + } + + public void setFoo( String foo ) { + this.foo = foo; + } + + public String getFoo() { + return foo; + } + +} \ No newline at end of file Added: jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTask.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTask.java?view=auto&rev=156674 ============================================================================== --- jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTask.java (added) +++ jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTask.java Wed Mar 9 11:37:12 2005 @@ -0,0 +1,354 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * 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.apache.commons.benchmark.rrd; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.text.*; + +import org.jrobin.core.*; +import org.jrobin.graph.*; + +import java.awt.Color; + +/** + * Handles updating Sources and updating the RRD information. This is done so + * that we can then generate human readable histographs from the data. Note + * that this is a Thread which is a bit heavy when all the datasources are local + * benchmarks. The problem is that we have NO idea the complexity of the Source + * and it might block on database resources, filesystems, etc and we need to + * make sure all the benchmarks complete at once. + */ +public class GraphTask extends Thread { + + /** + * True when we should generate tasks within the current process. + */ + public static boolean ENABLE_GENERATE_GRAPHS=true; + + /** + * Used to store RRDs and graphs. + */ + public static String ROOT = "/var/benchmark"; + + public long lastUpdatedSeconds = currentTimeSeconds(); + + long begin = lastUpdatedSeconds; + + private String name, title = null; + + /** + * Path to the RRD file. + */ + private String rrd_path = null; + + /** + * The current RRD sample... + */ + private Sample sample = null; + + /** + * Unit title and description. + */ + private String unit_desc, unit_name = null; + + /** + * The given source for this task which provides getValue() + */ + Source source = null; + + /** + * True when this task is waiting to run again. + */ + boolean isWaiting = false; + + /** + * + * @param unit_desc The description of this unit. Example: "Feeds Per Minute (FPM)" + * @param unit_name The name of this unit. Example: "FPM" + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + */ + public GraphTask( String name, + String title, + String unit_desc, + String unit_name, + Source source ) { + + this.name = name; + this.title = title; + this.unit_desc = unit_desc; + this.unit_name = unit_name; + this.source = source; + + rrd_path = new File( ROOT, name + ".rrd" ).getPath(); + + } + + /** + * Get the current time in seconds for use with RRD. + */ + public static long currentTimeSeconds() { + return System.currentTimeMillis() / 1000; + } + + /** + * Simple time format. + */ + public String formatTime( long v ) { + + return new SimpleDateFormat().format( new java.util.Date( v * 1000 ) ); + } + + /** + * Generate all graphs necessary to view this RRD. + */ + void generateGraphs() throws Exception { + + //FIXME: ideally we wouldn't have to generate these each time because + //they waste a LOT of CPU. + + generateGraph( name + "-1-hour.png", + 60 * 60, + title + " - 1 hour" ); + + generateGraph( name + "-6-hours.png", + 6 * 60 * 60, + title + " - 6 hours" ); + + generateGraph( name + "-12-hours.png", + 12 * 60 * 60, + title + " - 12 hours" ); + + generateGraph( name + "-1-day.png", + 24 * 60 * 60, + title + " - 1 day" ); + + generateGraph( name + "-1-week.png", + 7 * 24 * 60 * 60, + title + " - 1 week" ); + + generateGraph( name + "-1-month.png", + 30 * 24 * 60 * 60, + title + " - 1 month" ); + + generateGraph( name + "-1-year.png", + 365 * 24 * 60 * 60, + title + " - 1 year" ); + + } + + void generateGraph( String path, + long interval, + String title ) throws Exception { + + if ( ENABLE_GENERATE_GRAPHS = false ) + return; + + path = new File( ROOT, path ).getPath(); + + System.out.println( "Generating graph: " + path + " ..." ); + + //FIXME: only generate the last HOURS worth of data. + + RrdGraphDef graphDef = new RrdGraphDef(); + + long startTime, endTime = lastUpdatedSeconds; + + startTime = endTime - interval; + + System.out.println( "startTime: " + formatTime( startTime ) ); + System.out.println( "endTime: " + formatTime( endTime ) ); + + graphDef.setShowSignature( false ); + + graphDef.setTimePeriod( startTime, endTime ); + graphDef.setTitle( title ); + graphDef.datasource( "myspeed", rrd_path, "speed", "AVERAGE" ); + + //graphDef.line( "myspeed", + // new Color.RED, + // "Feeds Per Minute (FPM)", + // 1 ); + + graphDef.area( "myspeed", Color.GREEN, unit_desc ); + + //FIXME: don't include 3 decimal places of precision. We don't need + //this. + graphDef.gprint( "myspeed", "AVERAGE", "Average " + unit_name + ": @[EMAIL PROTECTED]"); + graphDef.gprint( "myspeed", "MAX", "Max " + unit_name + ": @[EMAIL PROTECTED]"); + graphDef.gprint( "myspeed", "MIN", "Min " + unit_name + ": @[EMAIL PROTECTED]"); + + //Sat Dec 25 2004 03:04 PM ([EMAIL PROTECTED]): LAST doesn't work and + //returns NaN. Why is this? + //graphDef.gprint( "myspeed", "LAST", "Current " + unit_name + ": @[EMAIL PROTECTED]"); + + //FIXME: would be NICE to have STDDEV here as well as MEDIAN as well as + //LAST. I could ADD this to JRobin but I'd need to do it in + //FetchData.java and add getStandardDeviation and getMedian methods. + //Should be easy though.cn + + //NOTE: total doesn't seem to make much sense at all times. + //graphDef.gprint( "myspeed", "TOTAL", "Total " + unit_name + ": @[EMAIL PROTECTED]"); + + graphDef.comment( "Last updated on: " + formatTime( endTime ) ); + + RrdGraph graph = new RrdGraph( graphDef ); + + //graph.saveAsGIF( path ); + graph.saveAsPNG( path ); + + System.out.println( "Generating graph: " + path + " ...done" ); + + } + + /** + * Create the RRD when it doesn't exist including setting up archive + * functions, adding datasources, etc. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + */ + private void doCreateRRD() throws Exception { + + new File( ROOT ).mkdirs(); + + System.out.println( "Creating rrd file: " + rrd_path ); + + RrdDef rrdDef = new RrdDef( rrd_path ); + rrdDef.setStartTime( begin ); + + rrdDef.addDatasource( "speed", + "GAUGE", + GraphTaskRunner.COUNTER_INTERVAL_SECONDS, + Double.NaN, + Double.NaN ); + + //set the step to 1 minute (the default is 5 minutes). + rrdDef.setStep( GraphTaskRunner.COUNTER_INTERVAL_SECONDS ); + + //keep one measurement for every single poll. + + //rrdDef.addArchive( "AVERAGE", 0.5, 1, 3600 ); + + //rrdDef.addArchive( "AVERAGE", 0.5, 1, 60 ); + + //FIXME: increase this to about 400... because this would yield a much + //higher density image. + + //6 hours (6 minute intervals... with 60 measurements which yields 360 + //minutes which is 6 hours). + + rrdDef.addArchive( "AVERAGE", 0.5, 1, 360 ); + + //12 hours + rrdDef.addArchive( "AVERAGE", 0.5, 2, 360 ); + + //24 hours + rrdDef.addArchive( "AVERAGE", 0.5, 4, 360 ); + + //1 week + rrdDef.addArchive( "AVERAGE", 0.5, 28, 360 ); + + //1 month + rrdDef.addArchive( "AVERAGE", 0.5, 120, 360 ); + + //1 year + rrdDef.addArchive( "AVERAGE", 0.5, 1460, 360 ); + + //FIXME: don't we need additional archives here? + + RrdDb rrdDb = new RrdDb( rrdDef ); + rrdDb.close(); + + } + + /** + * Exec this task in the current thread. + */ + public void exec() throws Exception { + + File file = new File( rrd_path ); + + if ( file.exists() == false ) { + doCreateRRD(); + } + + RrdDb rrdDb = new RrdDb( rrd_path ); + sample = rrdDb.createSample(); + + try { + + data( source.getValue() ); + //value += 10; + //data( value ); + rrdDb.sync(); + rrdDb.close(); + + } finally { + + rrdDb.sync(); + rrdDb.close(); + } + + } + + /** + * Run this task as a dedicated thread waiting to be notified by the runner. + */ + public void run() { + + while ( true ) { + synchronized( this ) { + + try { + + isWaiting = true; + wait(); + isWaiting = false; + + exec(); + generateGraphs(); + + } catch ( Exception e ) { + e.printStackTrace(); + } + + } + } + } + + /** + * Take the RRD and call setAndUpdate on it with the given value. + */ + public void data( long v ) throws Exception { + + //NOTE: this is the correct mechanism but it might be off by a bit due + //to skew with running getValue() from diff impls... + //lastUpdatedSeconds = currentTimeSeconds(); + + lastUpdatedSeconds += GraphTaskRunner.COUNTER_INTERVAL_SECONDS; + + String time = formatTime( lastUpdatedSeconds ); + + System.out.println( "time: " + time + " , " + unit_name + " value: " + v ); + System.out.println( "lastUpdated: " + lastUpdatedSeconds ); + + sample.setAndUpdate( lastUpdatedSeconds + ":" + v ); + + } + +} \ No newline at end of file Added: jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTaskRunner.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTaskRunner.java?view=auto&rev=156674 ============================================================================== --- jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTaskRunner.java (added) +++ jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/GraphTaskRunner.java Wed Mar 9 11:37:12 2005 @@ -0,0 +1,105 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * 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.apache.commons.benchmark.rrd; + +import java.util.*; + +/** + * Handles processing all tasks and updating graphs if enabled and necessary. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + */ +public class GraphTaskRunner { + + public static final long SLEEP_INTERVAL_MILLIS = 60L * 1000L; + public static final long COUNTER_INTERVAL_SECONDS = 60L; + + public static List tasks = new LinkedList(); + + /** + * Runs all given tasks. Designed to be used within an infinite loop. + */ + public void run() throws Exception { + + Iterator it = tasks.iterator(); + + long lastUpdatedSeconds = GraphTask.currentTimeSeconds(); + + while ( it.hasNext() ) { + + try { + + GraphTask t = (GraphTask)it.next(); + + if ( t.isAlive() == false ) { + t.start(); + } + + while ( t.isWaiting == false ) { + Thread.sleep( 50 ); + } + + t.lastUpdatedSeconds = lastUpdatedSeconds; + + synchronized( t ) { + t.notifyAll(); + } + + } catch ( Throwable t ) { + + //FIXME: what happens here when we fail too many times..? This + //would be bad and we wouldn't really handle it well. + t.printStackTrace(); + } + + } + + } + + public void runForever() throws Exception { + + // ******************** + while ( true ) { + + //FIXME: modularize this more. + + long begin = System.currentTimeMillis(); + + run(); + + long duration = System.currentTimeMillis() - begin; + + long sleep_interval = GraphTaskRunner.SLEEP_INTERVAL_MILLIS - duration; + + if ( sleep_interval > 0 ) { + + System.out.println( "Sleeping for millis: " + sleep_interval ); + + //spin until the next read interval... + Thread.sleep( sleep_interval ); + + } else { + + System.out.println( "Took too long to perform tasks. Not sleeping..." ); + + } + + } + + } + +} Added: jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Main.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Main.java?view=auto&rev=156674 ============================================================================== --- jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Main.java (added) +++ jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Main.java Wed Mar 9 11:37:12 2005 @@ -0,0 +1,44 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * 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.apache.commons.benchmark.rrd; + +import org.apache.commons.benchmark.config.*; + +/** + * Simple commandline rrd grapher based on GraphTaskRunner. This can be used by + * itself or with another package. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + * @version $Id: $ + */ +public class Main { + + /** + * Default path to the configuration file for launching the RRD daemon. + */ + public static String CONFIG = "/etc/commons-benchmark/benchmark.xml"; + + public static void main( String[] args ) throws Exception { + + XMLConfigurator.configure( CONFIG ); + + GraphTaskRunner runner = new GraphTaskRunner(); + runner.runForever(); + + } + +} Propchange: jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Main.java ------------------------------------------------------------------------------ svn:executable = * Added: jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Source.java URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Source.java?view=auto&rev=156674 ============================================================================== --- jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Source.java (added) +++ jakarta/commons/sandbox/benchmark/trunk/src/java/org/apache/commons/benchmark/rrd/Source.java Wed Mar 9 11:37:12 2005 @@ -0,0 +1,37 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * 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.apache.commons.benchmark.rrd; + +/** + * Represents an abstract datasource for an source for logging. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + * @version $Id: $ + */ +public abstract class Source { + + String title = null; + String description = null; + + /** + * Get the current value for this counter. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</a> + */ + public abstract long getValue() throws Exception; + +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]