alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.core.perftool;

import java.util.Stack;
import java.util.Arrays;

/** Logger that will enable the logging of important events during the startup
 * annotated with real time and possibly time differences.
 *
 * @author Petr Nejedly, Jesse Glick
 */
public class StartLog {

    private static final StartImpl impl;
    private static final Stack actions = new Stack(); // Stack
    private static final Stack places = new Stack(); // Stack
    private static final boolean DEBUG_NESTING = Boolean.getBoolean("org.netbeans.log.startup.debug"); // NOI18N
    
    static {
        String logProp = System.getProperty( "org.netbeans.log.startup" ); // NOI18N
        String logFileProp = System.getProperty( "org.netbeans.log.startup.logfile" ); // NOI18N
        if( logProp == null) {
            if(logFileProp != null) {
                impl = new PrintImpl();
            }else{
                impl = new StartImpl();
            }
        } else {
            if( "print".equals(logProp) ) { // NOI18N
                impl = new PrintImpl();
            } else {
                throw new Error("Unknown org.netbeans.log.startup value: " + logProp); // NOI18N
            }
        }
    }
    
    /** Start running some interval action.
     * @param action some identifying string
     */
    public static void logStart( String action ) {
        if (willLog()) {
            impl.start(action, System.currentTimeMillis());
            actions.push(action);
            if (DEBUG_NESTING) {
                places.push(new Throwable("logStart called here:")); // NOI18N
            }
        }
    }

    /** Note that something happened, but not an interval.
     * The log will note only the time elapsed since the last interesting event.
     * @param action some identifying string
     */
    public static void logProgress( String note ) {
        if( willLog() ) impl.progress( note, System.currentTimeMillis() );
    }

    /** Stop running some interval action.
     * The log will note the time elapsed since the start of the action.
     * Actions must be properly nested.
     * @param action some identifying string
     */
    public static void logEnd( String action ) {
        if (willLog()) {
            String old = actions.empty() ? null : (String)actions.pop();
            Throwable oldplace = DEBUG_NESTING && !places.empty() ? (Throwable)places.pop() : null;
            if (!action.equals(old)) {
                // Error, not ISE; don't want this caught and reported
                // with ErrorManager, for then you get a wierd cycle!
                if (oldplace != null) {
                    oldplace.printStackTrace();
                } else {
                    System.err.println("Either ending too soon, or no info about caller of unmatched start log."); // NOI18N
                    System.err.println("Try running with -J-Dorg.netbeans.log.startup.debug=true"); // NOI18N
                }
                Error e = new Error("StartLog mismatch: ending '" + action + "' but expecting '" + old + "'; rest of stack: " + actions); // NOI18N
                // Print stack trace since you can get strange situations
                // when ErrorManager tries to report it - may need to initialize
                // ErrorManager, etc.
                e.printStackTrace();
                // Presumably you did want to keep on going at this point.
                // Note that this can only happen when logging is off
                // (which is the default).
                System.exit(1);
            }
            impl.end(action, System.currentTimeMillis());
        }
    }

    public static boolean willLog() {
        return impl.willLog();
    }
    
    public static long measuredStartupTime(){
        return ((PrintImpl)impl).prog - ((PrintImpl)impl).zero;
    }
    

    public static void logMeasuredStartupTime(){
        java.io.File file;
        String filePath = System.getProperty("org.netbeans.log.startup.logfile"); // NOI18N
        if(filePath!=null){
            try{
                file = new java.io.File(filePath);
                java.io.FileWriter writer = new java.io.FileWriter(file);
                writer.write(Long.toString(((PrintImpl)impl).prog - ((PrintImpl)impl).zero));
                writer.close();
            }catch (Exception exc){
                exc.printStackTrace(System.err);
            }
        }
    }
    
    
    
    /** The dummy, no-op implementation */
    private static class StartImpl {
        StartImpl() {}
        void start( String action, long time ) {}
        void progress( String note, long time ) {}
        void end( String action, long time ) {}
        boolean willLog() {
            return false;
        }
    }

    private static class PrintImpl extends StartImpl {
        PrintImpl() {}
        long zero = System.currentTimeMillis();
        private Stack starts = new Stack();
        long prog;
        private int indent = 0;
        
        synchronized void start( String action, long time ) {
            starts.push( new Long( time ) );
            prog=time;
            System.err.println( getIndentString(indent) + "@" + 
                    (time - zero) + " - " + action + " started" // NOI18N
            );
            indent += 2;
        }
        
        synchronized void progress( String note, long time ) {
            System.err.println( getIndentString(indent) + "@" + 
                    (time - zero) + " - " + note + " dT=" + (time - prog) // NOI18N
            );
            prog = time;
        }
        
        synchronized void end( String action, long time ) {
            indent -= 2;
            long start = ((Long)starts.pop()).longValue();
            prog = time;
            System.err.println( getIndentString(indent) + "@" + 
                    (time - zero) + " - " + action + " finished, took " + // NOI18N
                    (time - start) + "ms" // NOI18N
            );
        }
        
        boolean willLog() {
            return true;
        }
        
        private char[] spaces = new char[0];
        private String getIndentString( int indent ) {
            if( spaces.length < indent ) {
                spaces = new char[Math.max( spaces.length*2, indent+10 )];
                Arrays.fill( spaces, ' ');
            }
            return new String(spaces,0, indent);
        }

    }

}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.