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

com.nerdvision.agent.AgentImpl Maven / Gradle / Ivy

package com.nerdvision.agent;

import com.nerdvision.agent.api.IBreakpointListener;
import com.nerdvision.agent.api.IBreakpointService;
import com.nerdvision.agent.api.INerdVision;
import com.nerdvision.agent.inst.InstrumentationBreakpointService;
import com.nerdvision.agent.snapshot.Callback;
import java.com.nerdvision.agent.snapshot.ProxyCallback;
import java.lang.instrument.Instrumentation;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AgentImpl
{
    public static final String PRODUCT_NAME = "nerd.vision";

    private static volatile boolean shutdown = false;
    private static Logger logger;
    private static IBreakpointService breakpointService;
    private static Thread thread;


    public static void startup( final JarFile jarFile, final Instrumentation inst, final Map args )
    {
        final Attributes manifest = getManifest( jarFile );

        final Settings settings = Settings.build( args );

        logger = configureLogging( settings );
        announceClient( manifest, logger );

        final String uuid = UUID.randomUUID().toString();
        final HTTPClient httpClient = new HTTPClient( uuid, settings.getSettingAs( "api.key", String.class ) );

        final ClientReg clientReg = new ClientReg( settings, manifest, jarFile.getName(), uuid, httpClient );

        breakpointService = new InstrumentationBreakpointService( inst, settings );
        Callback.init( settings, breakpointService, httpClient );
        final ThreadGroup threadGroup = new ThreadGroup( "nerd.vision" );
        thread = new Thread( threadGroup, new Runnable()
        {
            @Override
            public void run()
            {
                final String sessionId = clientReg.getSession();
                logger.debug( "Session id: {}", sessionId );
                while( !shutdown )
                {
                    try( final GrpcService grpcService = new GrpcService( settings, breakpointService ); )
                    {
                        grpcService.connect( sessionId );
                        grpcService.await();
                    }
                    catch( Throwable t )
                    {
                        t.printStackTrace();
                    }
                }
            }
        } );
        thread.setDaemon( true );
        thread.setName( "nerd.vision" );
        thread.start();

        final Thread hook = new Thread( threadGroup, new Runnable()
        {
            @Override
            public void run()
            {
                shutdown = true;
                thread.interrupt();
            }
        } );
        hook.setName( "nerd.vision shutdown" );
        Runtime.getRuntime().addShutdownHook( hook );
    }


    public static Logger configureLogging( final Settings settings )
    {
        final java.util.logging.Logger logger = java.util.logging.Logger.getLogger( "com.nerdvision" );
        logger.setUseParentHandlers( false );
        final ConsoleHandler handler = new ConsoleHandler();
        logger.addHandler( handler );

        final Level settingAs = settings.getSettingAs( "logging.level", Level.class );
        handler.setLevel( settingAs );
        logger.setLevel( settingAs );
        return LoggerFactory.getLogger( AgentImpl.class );
    }


    public static Object loadNerdVisionAPI()
    {
        return new INerdVision()
        {
            @Override
            public long addBreakpoint( final Class clazz, final int lineNo )
            {
                return AgentImpl.breakpointService.addBreakpoint( clazz, lineNo );
            }


            @Override
            public void removeBreakpoint( final long id )
            {
                AgentImpl.breakpointService.removeBreakpoint( id );
            }


            @Override
            public long addBreakpointListener( final IBreakpointListener listener )
            {
                return AgentImpl.breakpointService.addBreakpointListener( listener );
            }


            @Override
            public void removeBreakpointListener( final long id )
            {
                AgentImpl.breakpointService.removeBreakpointListener( id );
            }


            @Override
            public void close() throws Exception
            {
                shutdown = true;
                thread.interrupt();
            }
        };
    }


    private static Attributes getManifest( final JarFile jarFile )
    {
        try
        {
            return jarFile.getManifest().getMainAttributes();
        }
        catch( Exception e )
        {
            return new Attributes( 0 );
        }
    }


    private static void announceClient( final Attributes manifest, final Logger logger )
    {
        announce( logger, "--------------------------------------------------------------------------------------" );
        announce( logger, "nerdvision - Copyright (C) Intergral GmbH. All Rights Reserved" );

        announce( logger, manifest, "Version" );
        announce( logger, manifest, "Git-Commit-Id" );
        announce( logger, manifest, "Git-Commit-Time" );
        announce( logger, manifest, "Git-Branch" );

        announce( logger,
                "OS              : " + System.getProperty( "os.name" ) + " [" + System.getProperty( "os.version" ) + "] "
                        + System.getProperty( "os.arch" ) );
        announce( logger,
                "Java            : " + System.getProperty( "java.version" ) + " [" + System.getProperty( "java.vm.version" ) +
                        "] " + System.getProperty( "java.vm.vendor" ) );
        announce( logger, "Start Time      : " + new Date() );

        announce( logger, "--------------------------------------------------------------------------------------" );
    }


    private static void announce( final Logger logger, final Attributes manifest, final String key )
    {
        final String s = String.format( "%-16s: %s", key, manifest.getValue( key ) );
        announce( logger, s );
    }


    private static void announce( final Logger logger, final String message )
    {
        logger.debug( "{}: {}", PRODUCT_NAME, message );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy