All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.kernel.info.DiagnosticsManager Maven / Gradle / Ivy

Go to download

Neo4j kernel is a lightweight, embedded Java database designed to store data structured as graphs rather than tables. For more information, see http://neo4j.org.

There is a newer version: 2025.02.0
Show newest version
/*
 * Copyright (c) 2002-2015 "Neo Technology,"
 * Network Engine for Objects in Lund AB [http://neotechnology.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.kernel.info;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.neo4j.function.Consumer;
import org.neo4j.helpers.collection.Visitor;
import org.neo4j.kernel.info.DiagnosticsExtractor.VisitableDiagnostics;
import org.neo4j.kernel.lifecycle.Lifecycle;
import org.neo4j.logging.Log;
import org.neo4j.logging.Logger;

public class DiagnosticsManager implements Iterable, Lifecycle
{
    private final List providers = new CopyOnWriteArrayList();
    private final Log targetLog;
    private volatile State state = State.INITIAL;

    public DiagnosticsManager( Log targetLog )
    {
        this.targetLog = targetLog;

        providers.add( new DiagnosticsProvider(/*self*/)
        {
            @Override
            public String getDiagnosticsIdentifier()
            {
                return DiagnosticsManager.this.getClass().getName();
            }

            @Override
            public void dump( DiagnosticsPhase phase, final Logger logger )
            {
                if ( phase.isInitialization() || phase.isExplicitlyRequested() )
                {
                    logger.log( "Diagnostics providers:" );
                    for ( DiagnosticsProvider provider : providers )
                    {
                        logger.log( provider.getDiagnosticsIdentifier() );
                    }
                }
            }

            @Override
            public void acceptDiagnosticsVisitor( Object visitor )
            {
                Visitor target =
                        Visitor.SafeGenerics.castOrNull( DiagnosticsProvider.class, RuntimeException.class, visitor );
                if ( target != null ) for ( DiagnosticsProvider provider : providers )
                {
                    target.visit( provider );
                }
            }
        } );
        SystemDiagnostics.registerWith( this );
    }

    @Override
    public void init()
        throws Throwable
    {
        synchronized ( providers )
        {
            @SuppressWarnings( "hiding" ) State state = this.state;
            if ( !state.startup( this ) ) return;
        }
        dumpAll( DiagnosticsPhase.INITIALIZED, getTargetLog() );
    }

    public void start()
    {
        synchronized ( providers )
        {
            @SuppressWarnings( "hiding" ) State state = this.state;
            if ( !state.startup( this ) ) return;
        }
        dumpAll( DiagnosticsPhase.STARTED, getTargetLog() );
    }

    @Override
    public void stop()
        throws Throwable
    {
        synchronized ( providers )
        {
            @SuppressWarnings( "hiding" ) State state = this.state;
            if ( !state.shutdown( this ) ) return;
        }
        dumpAll( DiagnosticsPhase.STOPPING, getTargetLog() );
        providers.clear();
    }

    public void shutdown()
    {
        synchronized ( providers )
        {
            @SuppressWarnings( "hiding" ) State state = this.state;
            if ( !state.shutdown( this ) ) return;
        }
        dumpAll( DiagnosticsPhase.SHUTDOWN, getTargetLog() );
        providers.clear();
    }

    private enum State
    {
        INITIAL
        {
            @Override
            boolean startup( DiagnosticsManager manager )
            {
                manager.state = STARTED;
                return true;
            }
        },
        STARTED,
        STOPPED
        {
            @Override
            boolean shutdown( DiagnosticsManager manager )
            {
                return false;
            }
        };

        boolean startup( DiagnosticsManager manager )
        {
            return false;
        }

        boolean shutdown( DiagnosticsManager manager )
        {
            manager.state = STOPPED;
            return true;
        }
    }

    public Log getTargetLog()
    {
        return targetLog;
    }

    public void dumpAll()
    {
        dumpAll( DiagnosticsPhase.REQUESTED, getTargetLog() );
    }

    public void dump( String identifier )
    {
        extract( identifier, getTargetLog() );
    }

    public void dumpAll( Log log )
    {
        log.bulk( new Consumer()
        {
            @Override
            public void accept( Log bulkLog )
            {
                for ( DiagnosticsProvider provider : providers )
                {
                    dump( provider, DiagnosticsPhase.EXPLICIT, bulkLog );
                }
            }
        } );
    }

    public void extract( final String identifier, Log log )
    {
        log.bulk( new Consumer()
        {
            @Override
            public void accept( Log bulkLog )
            {
                for ( DiagnosticsProvider provider : providers )
                {
                    if ( identifier.equals( provider.getDiagnosticsIdentifier() ) )
                    {
                        dump( provider, DiagnosticsPhase.EXPLICIT, bulkLog );
                        return;
                    }
                }
            }
        } );
    }

    private void dumpAll( final DiagnosticsPhase phase, Log log )
    {
        log.bulk( new Consumer()
        {
            @Override
            public void accept( Log bulkLog )
            {
                phase.emitStart( bulkLog );
                for ( DiagnosticsProvider provider : providers )
                {
                    dump( provider, phase, bulkLog );
                }
                phase.emitDone( bulkLog );
            }
        } );
    }

    public  void register( DiagnosticsExtractor extractor, T source )
    {
        appendProvider( extractedProvider( extractor, source ) );
    }

    public  & DiagnosticsExtractor> void registerAll( Class extractorEnum, T source )
    {
        for ( DiagnosticsExtractor extractor : extractorEnum.getEnumConstants() )
        {
            register( extractor, source );
        }
    }

    public void prependProvider( DiagnosticsProvider provider )
    {
        @SuppressWarnings( "hiding" ) State state = this.state;
        if ( state == State.STOPPED ) return;
        providers.add( 0, provider );
        if ( state == State.STARTED ) dump( DiagnosticsPhase.STARTED, provider, getTargetLog() );
    }

    public void appendProvider( DiagnosticsProvider provider )
    {
        @SuppressWarnings( "hiding" ) State state = this.state;
        if ( state == State.STOPPED ) return;
        providers.add( provider );
        if ( state == State.STARTED ) dump( DiagnosticsPhase.STARTED, provider, getTargetLog() );
    }

    private void dump( DiagnosticsPhase phase, DiagnosticsProvider provider, Log log )
    {
        phase.emitStart( log, provider );
        dump( provider, phase, log );
        phase.emitDone( log, provider );
    }

    private static void dump( DiagnosticsProvider provider, DiagnosticsPhase phase, Log log )
    {
        try
        {
            provider.dump( phase, log.infoLogger() );
        }
        catch ( Exception cause )
        {
            log.error( "Failure while logging diagnostics for " + provider, cause );
        }
    }

    @Override
    public Iterator iterator()
    {
        return providers.iterator();
    }

    static  DiagnosticsProvider extractedProvider( DiagnosticsExtractor extractor, T source )
    {
        if ( extractor instanceof DiagnosticsExtractor.VisitableDiagnostics )
        {
            return new ExtractedVisitableDiagnosticsProvider(
                    (DiagnosticsExtractor.VisitableDiagnostics) extractor, source );
        }
        else
        {
            return new ExtractedDiagnosticsProvider( extractor, source );
        }
    }

    private static class ExtractedDiagnosticsProvider implements DiagnosticsProvider
    {
        final DiagnosticsExtractor extractor;
        final T source;

        ExtractedDiagnosticsProvider( DiagnosticsExtractor extractor, T source )
        {
            this.extractor = extractor;
            this.source = source;
        }

        @Override
        public String getDiagnosticsIdentifier()
        {
            return extractor.toString();
        }

        @Override
        public void acceptDiagnosticsVisitor( Object visitor )
        {
            // nobody visits the source of this
        }

        @Override
        public void dump( DiagnosticsPhase phase, Logger logger )
        {
            extractor.dumpDiagnostics( source, phase, logger );
        }
    }

    private static class ExtractedVisitableDiagnosticsProvider extends ExtractedDiagnosticsProvider
    {
        ExtractedVisitableDiagnosticsProvider( VisitableDiagnostics extractor, T source )
        {
            super( extractor, source );
        }

        @Override
        public void acceptDiagnosticsVisitor( Object visitor )
        {
            ( (DiagnosticsExtractor.VisitableDiagnostics) extractor ).dispatchDiagnosticsVisitor( source, visitor );
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy