blob: 0316baa1d786b53df42ad91040315e041fd058dc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.diagnostics;
import org.apache.nifi.controller.repository.ContentRepository;
import org.apache.nifi.controller.repository.FlowFileRepository;
import org.apache.nifi.provenance.ProvenanceRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A factory for creating system diagnostics.
*
*/
public class SystemDiagnosticsFactory {
private final Logger logger = LoggerFactory.getLogger(SystemDiagnosticsFactory.class);
public SystemDiagnostics create(final FlowFileRepository flowFileRepo, final ContentRepository contentRepo, ProvenanceRepository provenanceRepository) {
final SystemDiagnostics systemDiagnostics = new SystemDiagnostics();
final MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
final MemoryUsage heap = memory.getHeapMemoryUsage();
final MemoryUsage nonHeap = memory.getNonHeapMemoryUsage();
final OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
final ThreadMXBean threads = ManagementFactory.getThreadMXBean();
final List<GarbageCollectorMXBean> garbageCollectors = ManagementFactory.getGarbageCollectorMXBeans();
final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
systemDiagnostics.setDaemonThreads(threads.getDaemonThreadCount());
systemDiagnostics.setTotalThreads(threads.getThreadCount());
systemDiagnostics.setTotalHeap(heap.getCommitted());
systemDiagnostics.setUsedHeap(heap.getUsed());
systemDiagnostics.setMaxHeap(heap.getMax());
systemDiagnostics.setTotalNonHeap(nonHeap.getCommitted());
systemDiagnostics.setUsedNonHeap(nonHeap.getUsed());
systemDiagnostics.setMaxNonHeap(nonHeap.getMax());
systemDiagnostics.setUptime(runtime.getUptime());
systemDiagnostics.setAvailableProcessors(os.getAvailableProcessors());
final double systemLoad = os.getSystemLoadAverage();
if (systemLoad >= 0) {
systemDiagnostics.setProcessorLoadAverage(systemLoad);
} else {
systemDiagnostics.setProcessorLoadAverage(-1.0);
}
// get the database disk usage
final StorageUsage flowFileRepoStorageUsage = new StorageUsage();
flowFileRepoStorageUsage.setIdentifier("FlowFile Repository");
try {
flowFileRepoStorageUsage.setFreeSpace(flowFileRepo.getUsableStorageSpace());
flowFileRepoStorageUsage.setTotalSpace(flowFileRepo.getStorageCapacity());
} catch (final IOException ioe) {
flowFileRepoStorageUsage.setFreeSpace(0L);
flowFileRepoStorageUsage.setTotalSpace(-1L);
logger.warn("Unable to determine FlowFile Repository usage due to {}", ioe.toString());
if (logger.isDebugEnabled()) {
logger.warn("", ioe);
}
}
systemDiagnostics.setFlowFileRepositoryStorageUsage(flowFileRepoStorageUsage);
// get the file repository disk usage
final Set<String> containerNames = contentRepo.getContainerNames();
final Map<String, StorageUsage> fileRepositoryUsage = new LinkedHashMap<>(containerNames.size());
for (final String containerName : containerNames) {
long containerCapacity = -1L;
long containerFree = 0L;
try {
containerFree = contentRepo.getContainerUsableSpace(containerName);
containerCapacity = contentRepo.getContainerCapacity(containerName);
} catch (final IOException ioe) {
logger.warn("Unable to determine Content Repository usage for container {} due to {}", containerName, ioe.toString());
if (logger.isDebugEnabled()) {
logger.warn("", ioe);
}
}
final StorageUsage storageUsage = new StorageUsage();
storageUsage.setIdentifier(containerName);
storageUsage.setFreeSpace(containerFree);
storageUsage.setTotalSpace(containerCapacity);
fileRepositoryUsage.put(containerName, storageUsage);
}
systemDiagnostics.setContentRepositoryStorageUsage(fileRepositoryUsage);
// get provenance repository disk usage
final Set<String> provContainerNames = provenanceRepository.getContainerNames();
final Map<String, StorageUsage> provRepositoryUsage = new LinkedHashMap<>(provContainerNames.size());
for (final String containerName : provContainerNames) {
long containerCapacity = -1L;
long containerFree = 0L;
try {
containerFree = provenanceRepository.getContainerUsableSpace(containerName);
containerCapacity = provenanceRepository.getContainerCapacity(containerName);
} catch (final IOException ioe) {
logger.warn("Unable to determine Provenance Repository usage for container {} due to {}", containerName, ioe.toString());
if (logger.isDebugEnabled()) {
logger.warn("", ioe);
}
}
final StorageUsage storageUsage = new StorageUsage();
storageUsage.setIdentifier(containerName);
storageUsage.setFreeSpace(containerFree);
storageUsage.setTotalSpace(containerCapacity);
provRepositoryUsage.put(containerName, storageUsage);
}
systemDiagnostics.setProvenanceRepositoryStorageUsage(provRepositoryUsage);
// get the garbage collection statistics
final Map<String, GarbageCollection> garbageCollection = new LinkedHashMap<>(garbageCollectors.size());
for (final GarbageCollectorMXBean garbageCollector : garbageCollectors) {
final GarbageCollection garbageCollectionEntry = new GarbageCollection();
garbageCollectionEntry.setCollectionCount(garbageCollector.getCollectionCount());
garbageCollectionEntry.setCollectionTime(garbageCollector.getCollectionTime());
garbageCollection.put(garbageCollector.getName(), garbageCollectionEntry);
}
systemDiagnostics.setGarbageCollection(garbageCollection);
// This information is available only for *nix systems.
final OperatingSystemMXBean osStats = ManagementFactory.getOperatingSystemMXBean();
try {
final Class<?> unixOsMxBeanClass = Class.forName("com.sun.management.UnixOperatingSystemMXBean");
if (unixOsMxBeanClass.isAssignableFrom(osStats.getClass())) {
final Method totalPhysicalMemory = unixOsMxBeanClass.getMethod("getTotalPhysicalMemorySize");
totalPhysicalMemory.setAccessible(true);
final Long ramBytes = (Long) totalPhysicalMemory.invoke(osStats);
if (ramBytes != null) {
systemDiagnostics.setTotalPhysicalMemory(ramBytes);
}
final Method maxFileDescriptors = unixOsMxBeanClass.getMethod("getMaxFileDescriptorCount");
maxFileDescriptors.setAccessible(true);
final Long maxOpenFileDescriptors = (Long) maxFileDescriptors.invoke(osStats);
if (maxOpenFileDescriptors != null) {
systemDiagnostics.setMaxOpenFileHandles(maxOpenFileDescriptors);
}
final Method openFileDescriptors = unixOsMxBeanClass.getMethod("getOpenFileDescriptorCount");
openFileDescriptors.setAccessible(true);
final Long openDescriptorCount = (Long) openFileDescriptors.invoke(osStats);
if (openDescriptorCount != null) {
systemDiagnostics.setOpenFileHandles(openDescriptorCount);
}
}
} catch (final Throwable t) {
// Ignore. This will throw either ClassNotFound or NoClassDefFoundError if unavailable in this JVM.
}
// set the creation timestamp
systemDiagnostics.setCreationTimestamp(new Date().getTime());
return systemDiagnostics;
}
}