|
@@ -26,43 +26,27 @@ import password.pwm.PwmApplication;
|
|
|
import password.pwm.bean.DomainID;
|
|
|
import password.pwm.bean.SessionLabel;
|
|
|
import password.pwm.error.PwmException;
|
|
|
-import password.pwm.error.PwmUnrecoverableException;
|
|
|
import password.pwm.svc.AbstractPwmService;
|
|
|
import password.pwm.svc.PwmService;
|
|
|
-import password.pwm.util.PwmScheduler;
|
|
|
-import password.pwm.util.debug.DebugItemGenerator;
|
|
|
-import password.pwm.util.java.AtomicLoopIntIncrementer;
|
|
|
-import password.pwm.util.java.FileSystemUtility;
|
|
|
-import password.pwm.util.java.JavaHelper;
|
|
|
import password.pwm.util.java.StatisticAverageBundle;
|
|
|
import password.pwm.util.java.StatisticCounterBundle;
|
|
|
-import password.pwm.util.java.StringUtil;
|
|
|
import password.pwm.util.java.TimeDuration;
|
|
|
-import password.pwm.util.logging.PwmLogLevel;
|
|
|
+import password.pwm.util.logging.PwmLogManager;
|
|
|
import password.pwm.util.logging.PwmLogger;
|
|
|
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
import java.io.Serializable;
|
|
|
-import java.lang.management.ManagementFactory;
|
|
|
-import java.lang.management.ThreadInfo;
|
|
|
-import java.nio.file.Files;
|
|
|
import java.time.Instant;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
-import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
import java.util.TreeSet;
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
import java.util.concurrent.Future;
|
|
|
-import java.util.concurrent.ScheduledExecutorService;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.function.Supplier;
|
|
|
-import java.util.zip.ZipOutputStream;
|
|
|
|
|
|
public class HealthService extends AbstractPwmService implements PwmService
|
|
|
{
|
|
@@ -76,8 +60,6 @@ public class HealthService extends AbstractPwmService implements PwmService
|
|
|
new CertificateChecker() );
|
|
|
|
|
|
|
|
|
- private ScheduledExecutorService executorService;
|
|
|
- private ScheduledExecutorService supportZipWriterService;
|
|
|
private HealthMonitorSettings settings;
|
|
|
|
|
|
private final Map<HealthMonitorFlag, Serializable> healthProperties = new ConcurrentHashMap<>();
|
|
@@ -121,19 +103,6 @@ public class HealthService extends AbstractPwmService implements PwmService
|
|
|
return STATUS.CLOSED;
|
|
|
}
|
|
|
|
|
|
- executorService = PwmScheduler.makeBackgroundServiceExecutor( pwmApplication, getSessionLabel(), this.getClass() );
|
|
|
- supportZipWriterService = PwmScheduler.makeBackgroundServiceExecutor( pwmApplication, getSessionLabel(), this.getClass() );
|
|
|
- scheduleNextZipOutput();
|
|
|
-
|
|
|
- if ( settings.getThreadDumpInterval().as( TimeDuration.Unit.SECONDS ) > 0 )
|
|
|
- {
|
|
|
- pwmApplication.getPwmScheduler().scheduleFixedRateJob(
|
|
|
- new ThreadDumpLogger( getSessionLabel() ),
|
|
|
- executorService,
|
|
|
- TimeDuration.SECOND,
|
|
|
- settings.getThreadDumpInterval() );
|
|
|
- }
|
|
|
-
|
|
|
return STATUS.OPEN;
|
|
|
}
|
|
|
|
|
@@ -168,7 +137,7 @@ public class HealthService extends AbstractPwmService implements PwmService
|
|
|
{
|
|
|
final Instant startTime = Instant.now();
|
|
|
LOGGER.trace( getSessionLabel(), () -> "begin force immediate check" );
|
|
|
- final Future<?> future = getPwmApplication().getPwmScheduler().scheduleJob( new ImmediateJob(), executorService, TimeDuration.ZERO );
|
|
|
+ final Future<?> future = scheduleJob( new ImmediateJob(), TimeDuration.ZERO );
|
|
|
settings.getMaximumForceCheckWait().pause( future::isDone );
|
|
|
final TimeDuration checkDuration = TimeDuration.fromCurrent( startTime );
|
|
|
averageStats.update( AverageStatKey.checkProcessTime, checkDuration.asDuration() );
|
|
@@ -176,7 +145,7 @@ public class HealthService extends AbstractPwmService implements PwmService
|
|
|
LOGGER.trace( getSessionLabel(), () -> "exit force immediate check, done=" + future.isDone(), checkDuration );
|
|
|
}
|
|
|
|
|
|
- getPwmApplication().getPwmScheduler().scheduleJob( new UpdateJob(), executorService, settings.getNominalCheckInterval() );
|
|
|
+ scheduleJob( new UpdateJob(), settings.getNominalCheckInterval() );
|
|
|
|
|
|
{
|
|
|
final HealthData localHealthData = this.healthData;
|
|
@@ -192,14 +161,6 @@ public class HealthService extends AbstractPwmService implements PwmService
|
|
|
@Override
|
|
|
public void shutdownImpl( )
|
|
|
{
|
|
|
- if ( executorService != null )
|
|
|
- {
|
|
|
- executorService.shutdown();
|
|
|
- }
|
|
|
- if ( supportZipWriterService != null )
|
|
|
- {
|
|
|
- supportZipWriterService.shutdown();
|
|
|
- }
|
|
|
healthData = emptyHealthData();
|
|
|
setStatus( STATUS.CLOSED );
|
|
|
}
|
|
@@ -319,14 +280,17 @@ public class HealthService extends AbstractPwmService implements PwmService
|
|
|
@Override
|
|
|
public void run( )
|
|
|
{
|
|
|
- try
|
|
|
- {
|
|
|
- doHealthChecks();
|
|
|
- }
|
|
|
- catch ( final Throwable e )
|
|
|
- {
|
|
|
- LOGGER.error( getSessionLabel(), () -> "error during health check execution: " + e.getMessage(), e );
|
|
|
- }
|
|
|
+ PwmLogManager.executeWithThreadSessionData( getSessionLabel(), () ->
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ doHealthChecks();
|
|
|
+ }
|
|
|
+ catch ( final Throwable e )
|
|
|
+ {
|
|
|
+ LOGGER.error( getSessionLabel(), () -> "error during health check execution: " + e.getMessage(), e );
|
|
|
+ }
|
|
|
+ } );
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -346,118 +310,4 @@ public class HealthService extends AbstractPwmService implements PwmService
|
|
|
return TimeDuration.fromCurrent( this.getTimeStamp() ).isLongerThan( settings.getMaximumRecordAge() );
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- private void scheduleNextZipOutput()
|
|
|
- {
|
|
|
- final int intervalSeconds = JavaHelper.silentParseInt( getPwmApplication().getConfig().readAppProperty( AppProperty.HEALTH_SUPPORT_BUNDLE_WRITE_INTERVAL_SECONDS ), 0 );
|
|
|
- if ( intervalSeconds > 0 )
|
|
|
- {
|
|
|
- final TimeDuration intervalDuration = TimeDuration.of( intervalSeconds, TimeDuration.Unit.SECONDS );
|
|
|
- getPwmApplication().getPwmScheduler().scheduleJob( new SupportZipFileWriter( getPwmApplication() ), supportZipWriterService, intervalDuration );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private class SupportZipFileWriter implements Runnable
|
|
|
- {
|
|
|
- private final PwmApplication pwmApplication;
|
|
|
-
|
|
|
- SupportZipFileWriter( final PwmApplication pwmApplication )
|
|
|
- {
|
|
|
- this.pwmApplication = pwmApplication;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void run()
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- writeSupportZipToAppPath();
|
|
|
- }
|
|
|
- catch ( final Exception e )
|
|
|
- {
|
|
|
- LOGGER.debug( getSessionLabel(), () -> "error writing support zip to file system: " + e.getMessage() );
|
|
|
- }
|
|
|
-
|
|
|
- scheduleNextZipOutput();
|
|
|
- }
|
|
|
-
|
|
|
- private void writeSupportZipToAppPath()
|
|
|
- throws IOException, PwmUnrecoverableException
|
|
|
- {
|
|
|
- final File appPath = getPwmApplication().getPwmEnvironment().getApplicationPath();
|
|
|
- if ( !appPath.exists() )
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- final int rotationCount = JavaHelper.silentParseInt( pwmApplication.getConfig().readAppProperty( AppProperty.HEALTH_SUPPORT_BUNDLE_FILE_WRITE_COUNT ), 10 );
|
|
|
- final DebugItemGenerator debugItemGenerator = new DebugItemGenerator( pwmApplication, getSessionLabel() );
|
|
|
-
|
|
|
- final File supportPath = new File( appPath.getPath() + File.separator + "support" );
|
|
|
-
|
|
|
- Files.createDirectories( supportPath.toPath() );
|
|
|
-
|
|
|
- final File supportFile = new File ( supportPath.getPath() + File.separator + debugItemGenerator.getFilename() );
|
|
|
-
|
|
|
- FileSystemUtility.rotateBackups( supportFile, rotationCount );
|
|
|
-
|
|
|
- final File newSupportFile = new File ( supportFile.getPath() + ".new" );
|
|
|
- Files.deleteIfExists( newSupportFile.toPath() );
|
|
|
-
|
|
|
- try ( ZipOutputStream zipOutputStream = new ZipOutputStream( new FileOutputStream( newSupportFile ) ) )
|
|
|
- {
|
|
|
- LOGGER.trace( getSessionLabel(), () -> "beginning periodic support bundle filesystem output" );
|
|
|
- debugItemGenerator.outputZipDebugFile( zipOutputStream );
|
|
|
- }
|
|
|
-
|
|
|
- Files.move( newSupportFile.toPath(), supportFile.toPath() );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static class ThreadDumpLogger implements Runnable
|
|
|
- {
|
|
|
- private static final PwmLogger LOGGER = PwmLogger.forClass( ThreadDumpLogger.class );
|
|
|
- private static final AtomicLoopIntIncrementer COUNTER = new AtomicLoopIntIncrementer();
|
|
|
-
|
|
|
- private final SessionLabel sessionLabel;
|
|
|
-
|
|
|
- ThreadDumpLogger( final SessionLabel sessionLabel )
|
|
|
- {
|
|
|
- this.sessionLabel = sessionLabel;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void run()
|
|
|
- {
|
|
|
- if ( !LOGGER.isInterestingLevel( PwmLogLevel.TRACE ) )
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- final int count = COUNTER.next();
|
|
|
- output( "---BEGIN OUTPUT THREAD DUMP #" + count + "---" );
|
|
|
-
|
|
|
- {
|
|
|
- final Map<String, String> debugValues = new LinkedHashMap<>();
|
|
|
- debugValues.put( "Memory Free", Long.toString( Runtime.getRuntime().freeMemory() ) );
|
|
|
- debugValues.put( "Memory Allocated", Long.toString( Runtime.getRuntime().totalMemory() ) );
|
|
|
- debugValues.put( "Memory Max", Long.toString( Runtime.getRuntime().maxMemory() ) );
|
|
|
- debugValues.put( "Thread Count", Integer.toString( Thread.activeCount() ) );
|
|
|
- output( "Thread Data #: " + StringUtil.mapToString( debugValues ) );
|
|
|
- }
|
|
|
-
|
|
|
- final ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true );
|
|
|
- for ( final ThreadInfo threadInfo : threads )
|
|
|
- {
|
|
|
- output( JavaHelper.threadInfoToString( threadInfo ) );
|
|
|
- }
|
|
|
-
|
|
|
- output( "---END OUTPUT THREAD DUMP #" + count + "---" );
|
|
|
- }
|
|
|
-
|
|
|
- private void output( final CharSequence output )
|
|
|
- {
|
|
|
- LOGGER.trace( sessionLabel, () -> output );
|
|
|
- }
|
|
|
- }
|
|
|
}
|