Log jemalloc presence and version at startup (#4738)

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
pull/5329/head
Fabio Di Fabio 2 years ago committed by GitHub
parent 4737f14534
commit a9b906cba5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 22
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  3. 53
      besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java
  4. 8
      besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
  5. 4
      besu/src/test/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilderTest.java
  6. 1
      util/build.gradle
  7. 33
      util/src/main/java/org/hyperledger/besu/util/platform/PlatformDetector.java

@ -7,6 +7,7 @@
### Additions and Improvements ### Additions and Improvements
- Update most dependencies to latest version [#5269](https://github.com/hyperledger/besu/pull/5269) - Update most dependencies to latest version [#5269](https://github.com/hyperledger/besu/pull/5269)
- If jemalloc is used, print its version in the configuration overview [#4738](https://github.com/hyperledger/besu/pull/4738)
- Add metrics for accounts and storage reads (Flat database vs Merkle Patricia Trie) [#5315](https://github.com/hyperledger/besu/pull/5315) - Add metrics for accounts and storage reads (Flat database vs Merkle Patricia Trie) [#5315](https://github.com/hyperledger/besu/pull/5315)
### Bug Fixes ### Bug Fixes

@ -198,7 +198,6 @@ import org.hyperledger.besu.util.PermissioningConfigurationValidator;
import org.hyperledger.besu.util.number.Fraction; import org.hyperledger.besu.util.number.Fraction;
import org.hyperledger.besu.util.number.Percentage; import org.hyperledger.besu.util.number.Percentage;
import org.hyperledger.besu.util.number.PositiveNumber; import org.hyperledger.besu.util.number.PositiveNumber;
import org.hyperledger.besu.util.platform.PlatformDetector;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -1465,8 +1464,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
final int exitCode = final int exitCode =
parse(resultHandler, executionExceptionHandler, parameterExceptionHandler, args); parse(resultHandler, executionExceptionHandler, parameterExceptionHandler, args);
detectJemalloc();
return exitCode; return exitCode;
} }
@ -1495,6 +1492,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
instantiateSignatureAlgorithmFactory(); instantiateSignatureAlgorithmFactory();
logger.info("Starting Besu"); logger.info("Starting Besu");
// Need to create vertx after cmdline has been parsed, such that metricsSystem is configurable // Need to create vertx after cmdline has been parsed, such that metricsSystem is configurable
vertx = createVertx(createVertxOptions(metricsSystem.get())); vertx = createVertx(createVertxOptions(metricsSystem.get()));
@ -1570,18 +1568,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
commandLine.registerConverter(MetricCategory.class, metricCategoryConverter); commandLine.registerConverter(MetricCategory.class, metricCategoryConverter);
} }
private void detectJemalloc() {
// jemalloc is only supported on Linux at the moment
if (PlatformDetector.getOSType().equals("linux")) {
Optional.ofNullable(environment.get("BESU_USING_JEMALLOC"))
.ifPresentOrElse(
present -> logger.info("Using jemalloc"),
() ->
logger.info(
"jemalloc library not found, memory usage may be reduced by installing it"));
}
}
private void handleStableOptions() { private void handleStableOptions() {
commandLine.addMixin("Ethstats", ethstatsOptions); commandLine.addMixin("Ethstats", ethstatsOptions);
commandLine.addMixin("Private key file", nodePrivateKeyFileOption); commandLine.addMixin("Private key file", nodePrivateKeyFileOption);
@ -3622,7 +3608,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
} }
private String generateConfigurationOverview() { private String generateConfigurationOverview() {
final ConfigurationOverviewBuilder builder = new ConfigurationOverviewBuilder(); final ConfigurationOverviewBuilder builder = new ConfigurationOverviewBuilder(logger);
if (environment != null) {
builder.setEnvironment(environment);
}
if (network != null) { if (network != null) {
builder.setNetwork(network.normalize()); builder.setNetwork(network.normalize());

@ -22,13 +22,20 @@ import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import org.slf4j.Logger;
import oshi.PlatformEnum; import oshi.PlatformEnum;
import oshi.SystemInfo; import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer; import oshi.hardware.HardwareAbstractionLayer;
/** The Configuration overview builder. */ /** The Configuration overview builder. */
public class ConfigurationOverviewBuilder { public class ConfigurationOverviewBuilder {
@SuppressWarnings("PrivateStaticFinalLoggers")
private final Logger logger;
private String network; private String network;
private BigInteger networkId; private BigInteger networkId;
private boolean hasCustomGenesis; private boolean hasCustomGenesis;
@ -40,6 +47,14 @@ public class ConfigurationOverviewBuilder {
private Collection<String> engineApis; private Collection<String> engineApis;
private String engineJwtFilePath; private String engineJwtFilePath;
private boolean isHighSpec = false; private boolean isHighSpec = false;
private Map<String, String> environment;
/**
* @param logger the logger
*/
public ConfigurationOverviewBuilder(final Logger logger) {
this.logger = logger;
}
/** /**
* Sets network. * Sets network.
@ -161,6 +176,17 @@ public class ConfigurationOverviewBuilder {
return this; return this;
} }
/**
* Sets the environment variables.
*
* @param environment the enveironment variables
* @return the builder
*/
public ConfigurationOverviewBuilder setEnvironment(final Map<String, String> environment) {
this.environment = environment;
return this;
}
/** /**
* Build configuration overview. * Build configuration overview.
* *
@ -226,6 +252,8 @@ public class ConfigurationOverviewBuilder {
if (glibcVersion != null) { if (glibcVersion != null) {
lines.add("glibc: " + glibcVersion); lines.add("glibc: " + glibcVersion);
} }
detectJemalloc(lines);
} }
final HardwareAbstractionLayer hardwareInfo = new SystemInfo().getHardware(); final HardwareAbstractionLayer hardwareInfo = new SystemInfo().getHardware();
@ -236,6 +264,31 @@ public class ConfigurationOverviewBuilder {
return FramedLogMessage.generate(lines); return FramedLogMessage.generate(lines);
} }
private void detectJemalloc(final List<String> lines) {
Optional.ofNullable(Objects.isNull(environment) ? null : environment.get("BESU_USING_JEMALLOC"))
.ifPresentOrElse(
t -> {
try {
final String version = PlatformDetector.getJemalloc();
lines.add("jemalloc: " + version);
} catch (final Throwable throwable) {
logger.warn(
"BESU_USING_JEMALLOC is present but we failed to load jemalloc library to get the version",
throwable);
}
},
() -> {
// in case the user is using jemalloc without BESU_USING_JEMALLOC env var
try {
final String version = PlatformDetector.getJemalloc();
lines.add("jemalloc: " + version);
} catch (final Throwable throwable) {
logger.info(
"jemalloc library not found, memory usage may be reduced by installing it");
}
});
}
private String normalizeSize(final long size) { private String normalizeSize(final long size) {
return String.format("%.02f", (double) (size) / 1024 / 1024 / 1024) + " GB"; return String.format("%.02f", (double) (size) / 1024 / 1024 / 1024) + " GB";
} }

@ -5404,11 +5404,15 @@ public class BesuCommandTest extends CommandTestAbstract {
} }
@Test @Test
public void logsUsingJemallocWhenEnvVarPresent() { public void logsWarningWhenFailToLoadJemalloc() {
assumeThat(PlatformDetector.getOSType(), is("linux")); assumeThat(PlatformDetector.getOSType(), is("linux"));
setEnvironmentVariable("BESU_USING_JEMALLOC", "true"); setEnvironmentVariable("BESU_USING_JEMALLOC", "true");
parseCommand(); parseCommand();
verify(mockLogger).info("Using jemalloc"); verify(mockLogger)
.warn(
eq(
"BESU_USING_JEMALLOC is present but we failed to load jemalloc library to get the version"),
any(Throwable.class));
} }
@Test @Test

@ -15,6 +15,7 @@
package org.hyperledger.besu.cli; package org.hyperledger.besu.cli;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
@ -22,13 +23,14 @@ import java.util.Collection;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
class ConfigurationOverviewBuilderTest { class ConfigurationOverviewBuilderTest {
private ConfigurationOverviewBuilder builder; private ConfigurationOverviewBuilder builder;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
builder = new ConfigurationOverviewBuilder(); builder = new ConfigurationOverviewBuilder(mock(Logger.class));
} }
@Test @Test

@ -32,6 +32,7 @@ dependencies {
api 'org.slf4j:slf4j-api' api 'org.slf4j:slf4j-api'
implementation 'com.google.guava:guava' implementation 'com.google.guava:guava'
implementation 'net.java.dev.jna:jna'
implementation 'org.apache.commons:commons-lang3' implementation 'org.apache.commons:commons-lang3'
implementation 'org.apache.logging.log4j:log4j-core' implementation 'org.apache.logging.log4j:log4j-core'
implementation 'org.apache.logging.log4j:log4j-slf4j2-impl' implementation 'org.apache.logging.log4j:log4j-slf4j2-impl'

@ -23,6 +23,11 @@ import java.util.Locale;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
/** /**
* Detects OS and VMs. * Detects OS and VMs.
* *
@ -36,6 +41,7 @@ public class PlatformDetector {
private static String _vm; private static String _vm;
private static String _arch; private static String _arch;
private static String _glibc; private static String _glibc;
private static String _jemalloc;
/** /**
* Gets OS type. * Gets OS type.
@ -98,6 +104,14 @@ public class PlatformDetector {
return _glibc; return _glibc;
} }
public static String getJemalloc() {
if (_jemalloc == null) {
detectJemalloc();
}
return _jemalloc;
}
private static final String UNKNOWN = "unknown"; private static final String UNKNOWN = "unknown";
private static void detect() { private static void detect() {
@ -306,4 +320,23 @@ public class PlatformDetector {
return matcher.find() ? matcher.group() : null; return matcher.find() ? matcher.group() : null;
} }
private static void detectJemalloc() {
interface JemallocLib extends Library {
int mallctl(
String property,
PointerByReference value,
IntByReference len,
String newValue,
int newLen);
}
final JemallocLib jemallocLib = Native.load("jemalloc", JemallocLib.class);
PointerByReference pVersion = new PointerByReference();
IntByReference pSize = new IntByReference(Native.POINTER_SIZE);
jemallocLib.mallctl("version", pVersion, pSize, null, 0);
_jemalloc = pVersion.getValue().getString(0);
}
} }

Loading…
Cancel
Save