
org.neo4j.kernel.info.DiagnosticsManager Maven / Gradle / Ivy
/**
* Copyright (c) 2002-2013 "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.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.neo4j.helpers.collection.IterableWrapper;
import org.neo4j.helpers.collection.Visitor;
import org.neo4j.kernel.impl.util.StringLogger;
import org.neo4j.kernel.info.DiagnosticsExtractor.VisitableDiagnostics;
import org.neo4j.kernel.lifecycle.Lifecycle;
public final class DiagnosticsManager implements Iterable, Lifecycle
{
@SuppressWarnings( "unchecked" )
public static final Visitor super T> castToGenericVisitor( Class type, Object visitor )
{
if ( visitor instanceof Visitor> )
{
for ( Type iface : visitor.getClass().getGenericInterfaces() )
{
if ( iface instanceof ParameterizedType )
{
ParameterizedType paramType = (ParameterizedType) iface;
if ( paramType.getRawType() == Visitor.class )
{
return (Visitor super T>) visitor;
}
}
}
}
return null;
}
private final List providers = new CopyOnWriteArrayList();
private final StringLogger logger;
private volatile State state = State.INITIAL;
public DiagnosticsManager( StringLogger logger )
{
( this.logger = logger ).addRotationListener( new Runnable()
{
@Override
public void run()
{
dumpAll( DiagnosticsPhase.LOG_ROTATION );
}
} );
providers.add( new DiagnosticsProvider(/*self*/)
{
@Override
public String getDiagnosticsIdentifier()
{
return DiagnosticsManager.this.getClass().getName();
}
@Override
public void dump( DiagnosticsPhase phase, final StringLogger log )
{
if ( phase.isInitialization() || phase.isExplicitlyRequested() )
{
log.logLongMessage( "Diagnostics providers:", new IterableWrapper(
providers )
{
@Override
protected String underlyingObjectToObject( DiagnosticsProvider provider )
{
return provider.getDiagnosticsIdentifier();
}
}, true );
}
}
@Override
public void acceptDiagnosticsVisitor( Object visitor )
{
Visitor super DiagnosticsProvider> target = castToGenericVisitor( DiagnosticsProvider.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);
}
public void start()
{
synchronized ( providers )
{
@SuppressWarnings( "hiding" ) State state = this.state;
if ( !state.startup( this ) ) return;
}
dumpAll( DiagnosticsPhase.STARTED);
}
@Override
public void stop()
throws Throwable
{
synchronized ( providers )
{
@SuppressWarnings( "hiding" ) State state = this.state;
if ( !state.shutdown( this ) ) return;
}
dumpAll( DiagnosticsPhase.STOPPING );
providers.clear();
}
public void shutdown()
{
synchronized ( providers )
{
@SuppressWarnings( "hiding" ) State state = this.state;
if ( !state.shutdown( this ) ) return;
}
dumpAll( DiagnosticsPhase.SHUTDOWN );
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 StringLogger getTargetLog()
{
return logger;
}
public void dumpAll()
{
dumpAll( DiagnosticsPhase.REQUESTED );
}
public void dump( String identifier )
{
extract( identifier, logger );
}
public void dumpAll( StringLogger log )
{
for ( DiagnosticsProvider provider : providers )
{
dump( provider, DiagnosticsPhase.EXPLICIT, log );
}
}
public void extract( String identifier, StringLogger log )
{
for ( DiagnosticsProvider provider : providers )
{
if ( identifier.equals( provider.getDiagnosticsIdentifier() ) )
{
dump( provider, DiagnosticsPhase.EXPLICIT, log );
return;
}
}
}
public void visitAll( Object visitor )
{
for ( DiagnosticsProvider provider : providers )
{
provider.acceptDiagnosticsVisitor( visitor );
}
}
private void dumpAll( DiagnosticsPhase phase )
{
phase.emitStart( logger );
for ( DiagnosticsProvider provider : providers )
{
dump( provider, phase, logger );
}
phase.emitDone( logger );
}
public void register( DiagnosticsExtractor extractor, T source )
{
appendProvider( extractedProvider( extractor, source ) );
}
public T tryAppendProvider( T protentialProvider )
{
if ( protentialProvider instanceof DiagnosticsProvider )
{
appendProvider( (DiagnosticsProvider) protentialProvider );
}
return protentialProvider;
}
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 );
}
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 );
}
private void dump( DiagnosticsPhase phase, DiagnosticsProvider provider )
{
phase.emitStart( logger, provider );
dump( provider, phase, logger );
phase.emitDone( logger, provider );
}
private static void dump( DiagnosticsProvider provider, DiagnosticsPhase phase, StringLogger logger )
{
try
{
provider.dump( phase, logger );
}
catch ( Exception cause )
{
logger.logMessage( "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, StringLogger log )
{
extractor.dumpDiagnostics( source, phase, log );
}
}
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