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

org.neo4j.kernel.diagnostics.providers.SystemDiagnostics 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: 5.25.1
Show newest version
/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [http://neo4j.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.diagnostics.providers;

import java.io.File;
import java.io.UncheckedIOException;
import java.lang.management.CompilationMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.ByteOrder;
import java.nio.file.Path;
import java.time.ZoneId;
import java.time.zone.ZoneRulesProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.neo4j.internal.diagnostics.DiagnosticsLogger;
import org.neo4j.internal.diagnostics.DiagnosticsProvider;
import org.neo4j.internal.nativeimpl.NativeAccess;
import org.neo4j.internal.nativeimpl.NativeAccessProvider;
import org.neo4j.io.fs.FileUtils;
import org.neo4j.io.os.OsBeanUtil;
import org.neo4j.util.VisibleForTesting;

import static java.lang.String.format;
import static java.net.NetworkInterface.getNetworkInterfaces;
import static org.neo4j.io.ByteUnit.bytesToString;

public enum SystemDiagnostics implements DiagnosticsProvider
{
    SYSTEM_MEMORY( "System memory information" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            logBytes( logger, "Total Physical memory: ", OsBeanUtil.getTotalPhysicalMemory() );
            logBytes( logger, "Free Physical memory: ", OsBeanUtil.getFreePhysicalMemory() );
            logBytes( logger, "Committed virtual memory: ", OsBeanUtil.getCommittedVirtualMemory() );
            logBytes( logger, "Total swap space: ", OsBeanUtil.getTotalSwapSpace() );
            logBytes( logger, "Free swap space: ", OsBeanUtil.getFreeSwapSpace() );
        }
    },
    JAVA_MEMORY( "JVM memory information" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            logger.log( "Free  memory: " + bytesToString( Runtime.getRuntime().freeMemory() ) );
            logger.log( "Total memory: " + bytesToString( Runtime.getRuntime().totalMemory() ) );
            logger.log( "Max   memory: " + bytesToString( Runtime.getRuntime().maxMemory() ) );
            for ( GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans() )
            {
                logger.log( "Garbage Collector: " + gc.getName() + ": " + Arrays.toString( gc.getMemoryPoolNames() ) );
            }
            for ( MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans() )
            {
                MemoryUsage usage = pool.getUsage();
                logger.log( format( "Memory Pool: %s (%s): committed=%s, used=%s, max=%s, threshold=%s",
                        pool.getName(), pool.getType(), usage == null ? "?" : bytesToString( usage.getCommitted() ),
                        usage == null ? "?" : bytesToString( usage.getUsed() ), usage == null ? "?" : bytesToString( usage.getMax() ),
                        pool.isUsageThresholdSupported() ? bytesToString( pool.getUsageThreshold() ) : "?" ) );
            }
        }
    },
    OPERATING_SYSTEM( "Operating system information" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
            logger.log( format( "Operating System: %s; version: %s; arch: %s; cpus: %s", os.getName(),
                    os.getVersion(), os.getArch(), os.getAvailableProcessors() ) );
            logLong( logger, "Max number of file descriptors: ", OsBeanUtil.getMaxFileDescriptors() );
            logLong( logger, "Number of open file descriptors: ", OsBeanUtil.getOpenFileDescriptors() );
            logger.log( "Process id: " + ProcessHandle.current().pid() );
            logger.log( "Byte order: " + ByteOrder.nativeOrder() );
            logger.log( "Local timezone: " + getLocalTimeZone() );
        }

        private String getLocalTimeZone()
        {
            return ZoneId.systemDefault().getId();
        }
    },
    JAVA_VIRTUAL_MACHINE( "JVM information" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
            logger.log( "VM Name: " + runtime.getVmName() );
            logger.log( "VM Vendor: " + runtime.getVmVendor() );
            logger.log( "VM Version: " + runtime.getVmVersion() );
            CompilationMXBean compiler = ManagementFactory.getCompilationMXBean();
            logger.log( "JIT compiler: " + ( ( compiler == null ) ? "unknown" : compiler.getName() ) );
            logger.log( "VM Arguments: " + runtime.getInputArguments() );
        }
    },
    CLASSPATH( "Java classpath" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
            Collection classpath;
            if ( runtime.isBootClassPathSupported() )
            {
                classpath = buildClassPath( getClass().getClassLoader(),
                        Map.of( "bootstrap", runtime.getBootClassPath(), "classpath", runtime.getClassPath() ) );
            }
            else
            {
                classpath = buildClassPath( getClass().getClassLoader(), Map.of( "classpath", runtime.getClassPath() ) );
            }
            for ( String path : classpath )
            {
                logger.log( path );
            }
        }

        private Collection buildClassPath( ClassLoader loader, Map classPaths )
        {
            Map paths = new HashMap<>();

            Set> entries = classPaths.entrySet();
            for ( Entry classPathEntry : entries )
            {
                String classPathType = classPathEntry.getKey();
                String[] splittedClassPath = classPathEntry.getValue().split( File.pathSeparator );
                for ( String entry : splittedClassPath )
                {
                    String canonicalEntry = canonicalize( entry );
                    paths.merge( canonicalEntry, classPathType, ( k, v ) -> v + " + " + classPathType );
                }
            }

            for ( int level = 0; loader != null; level++ )
            {
                if ( loader instanceof URLClassLoader )
                {
                    URLClassLoader urls = (URLClassLoader) loader;
                    URL[] classLoaderUrls = urls.getURLs();
                    if ( classLoaderUrls != null )
                    {
                        for ( URL url : classLoaderUrls )
                        {
                            if ( "file".equalsIgnoreCase( url.getProtocol() ) )
                            {
                                String type = "loader." + level;
                                paths.merge( url.toString(), type, ( k, v ) -> k + " + " + type );
                            }
                        }
                    }
                    else
                    {
                        paths.put( loader.toString(), "" );
                    }
                }
                loader = loader.getParent();
            }
            List result = new ArrayList<>( paths.size() );
            for ( Entry path : paths.entrySet() )
            {
                result.add( " [" + path.getValue() + "] " + path.getKey() );
            }
            return result;
        }
    },
    LIBRARY_PATH( "Library path" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
            for ( String path : runtime.getLibraryPath().split( File.pathSeparator ) )
            {
                logger.log( canonicalize( path ) );
            }
        }
    },
    SYSTEM_PROPERTIES( "System properties" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            for ( Object property : System.getProperties().keySet() )
            {
                if ( property instanceof String )
                {
                    String key = (String) property;
                    if ( key.startsWith( "java." ) || key.startsWith( "os." ) || key.endsWith( ".boot.class.path" ) ||
                            key.equals( "line.separator" ) )
                    {
                        continue;
                    }
                    logger.log( key + " = " + System.getProperty( key ) );
                }
            }
        }
    },
    TIMEZONE_DATABASE( "(IANA) TimeZone database version" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            Map versions = new HashMap<>();
            for ( String tz : ZoneRulesProvider.getAvailableZoneIds() )
            {
                for ( String version : ZoneRulesProvider.getVersions( tz ).keySet() )
                {
                    versions.compute( version, ( key, value ) -> value == null ? 1 : (value + 1) );
                }
            }
            String[] sorted = versions.keySet().toArray( new String[0] );
            Arrays.sort( sorted );
            for ( String tz : sorted )
            {
                logger.log( format( "  TimeZone version: %s (available for %d zone identifiers)", tz, versions.get( tz )  ) );
            }
        }
    },
    NETWORK( "Network information" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            try
            {
                Enumeration networkInterfaces = getNetworkInterfaces();

                while ( networkInterfaces.hasMoreElements() )
                {
                    NetworkInterface iface = networkInterfaces.nextElement();
                    logger.log( format( "Interface %s:", iface.getDisplayName() ) );

                    Enumeration addresses = iface.getInetAddresses();
                    while ( addresses.hasMoreElements() )
                    {
                        InetAddress address = addresses.nextElement();
                        String hostAddress = address.getHostAddress();
                        logger.log( format( "    address: %s", hostAddress ) );
                    }
                }
            }
            catch ( SocketException e )
            {
                logger.log( "ERROR: failed to inspect network interfaces and addresses: " + e.getMessage() );
            }
        }
    },
    NATIVE_ACCESSOR( "Native access information" )
    {
        @Override
        public void dump( DiagnosticsLogger logger )
        {
            NativeAccess nativeAccess = NativeAccessProvider.getNativeAccess();
            logger.log( "Native access details: " + nativeAccess.describe() );
        }
    };

    private final String name;

    SystemDiagnostics( String name )
    {
        this.name = name;
    }

    @Override
    public String getDiagnosticsName()
    {
        return name;
    }

    @VisibleForTesting
    static String canonicalize( String path )
    {
        try
        {
            boolean hasWildcard = path.endsWith( "*" );
            if ( hasWildcard )
            {
                path = path.substring( 0, path.length() - 1 );
            }
            String result = FileUtils.getCanonicalFile( Path.of( path ) ).toAbsolutePath().toString();
            if ( hasWildcard )
            {
                result += File.separator + "*";
            }
            return result;
        }
        catch ( UncheckedIOException e )
        {
            return Path.of( path ).toAbsolutePath().toString();
        }
    }

    private static void logBytes( DiagnosticsLogger logger, String message, long value )
    {
        if ( value != OsBeanUtil.VALUE_UNAVAILABLE )
        {
            logger.log( message + bytesToString( value ) );
        }
    }

    private static void logLong( DiagnosticsLogger logger, String message, long value )
    {
        if ( value != OsBeanUtil.VALUE_UNAVAILABLE )
        {
            logger.log( message + value );
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy