diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e18989cd2f..73da1555c5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,7 @@ jobs: uses: danipaniii/action-github-changelog-generator@v1.2 with: token: ${{ secrets.GITHUB_TOKEN }} - sinceTag: ${{ steps.previoustag.outputs.tag }} + sinceTag: 2.7.0 dateFormat: maxIssues: 500 unreleased: false diff --git a/inspectit-ocelot-agent/src/main/java/rocks/inspectit/ocelot/agent/AgentJars.java b/inspectit-ocelot-agent/src/main/java/rocks/inspectit/ocelot/agent/AgentJars.java index 258d529d76..bcc18d3391 100644 --- a/inspectit-ocelot-agent/src/main/java/rocks/inspectit/ocelot/agent/AgentJars.java +++ b/inspectit-ocelot-agent/src/main/java/rocks/inspectit/ocelot/agent/AgentJars.java @@ -5,6 +5,7 @@ import java.io.*; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; +import java.nio.channels.OverlappingFileLockException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -144,7 +145,7 @@ private static Path recycleJarFileWithLock(String resourcePath, Path jarPath) th try (RandomAccessFile lockFile = new RandomAccessFile(lockPath.toFile(), "rw"); FileChannel lockChannel = lockFile.getChannel(); - FileLock lock = acquireLock(lockChannel, 1500, 50) + FileLock lock = acquireLock(lockChannel, getJarRecyclingTimeout(), 50) ) { if (lock == null) throw new IOException("Could not acquire lock for: " + lockPath); @@ -167,9 +168,13 @@ private static FileLock acquireLock(FileChannel lockChannel, long timeout, long long end = System.currentTimeMillis() + timeout; while (System.currentTimeMillis() < end) { - FileLock lock = lockChannel.tryLock(); - if (lock != null) return lock; - + try { + FileLock lock = lockChannel.tryLock(); + if (lock != null) return lock; + } catch (OverlappingFileLockException e) { + System.err.println("OverlappingFileLock occured." + e); + throw new IOException(e); + } try { Thread.sleep(retryDelay); } catch (InterruptedException e) { @@ -218,6 +223,30 @@ private static boolean isRecyclingEnabled() { return "true".equalsIgnoreCase(isRecyclingEnabledValue); } + /** + * If the recycling of jars is enabled, the timeout for the recycling/file locking operation can be set. + * The value has to be a non-zero non-negative long, if the conditions are not met, it defaults to 3000ms. + * + * @return long, either the default of 3000ms or the value of the timeout property + */ + private static long getJarRecyclingTimeout() { + String recyclingTimeout = null != System.getProperty(AgentProperties.RECYCLE_JARS_TIMEOUT_PROPERTY) ? + System.getProperty(AgentProperties.RECYCLE_JARS_TIMEOUT_PROPERTY) : System.getenv(AgentProperties.RECYCLE_JARS_TIMEOUT_ENV_PROPERTY); + + final long DEFAULT_RECYCLE_TIMEOUT = 3000; + + if (recyclingTimeout == null) return DEFAULT_RECYCLE_TIMEOUT; + + try { + long recyclingTimeoutLong = Long.parseUnsignedLong(recyclingTimeout); + if (recyclingTimeoutLong <= 0) throw new NumberFormatException(); + return recyclingTimeoutLong; + } catch (NumberFormatException nfe) { + System.err.println("Jar Recycling Timeout property must be a non-negative non-zero long, therefore reverting to default timeout of 3000ms."); + return DEFAULT_RECYCLE_TIMEOUT; + } + } + /** * Reads the current agent version from the ocelot-version.info file * diff --git a/inspectit-ocelot-bootstrap/src/main/java/rocks/inspectit/ocelot/bootstrap/AgentProperties.java b/inspectit-ocelot-bootstrap/src/main/java/rocks/inspectit/ocelot/bootstrap/AgentProperties.java index 91ea10e1c5..ae86344ded 100644 --- a/inspectit-ocelot-bootstrap/src/main/java/rocks/inspectit/ocelot/bootstrap/AgentProperties.java +++ b/inspectit-ocelot-bootstrap/src/main/java/rocks/inspectit/ocelot/bootstrap/AgentProperties.java @@ -17,6 +17,10 @@ public class AgentProperties { public static final String RECYCLE_JARS_ENV_PROPERTY = "INSPECTIT_RECYCLE_JARS"; + public static final String RECYCLE_JARS_TIMEOUT_PROPERTY = "inspectit.recycle-jars-timeout"; + + public static final String RECYCLE_JARS_TIMEOUT_ENV_PROPERTY = "INSPECTIT_RECYCLE_JARS_TIMEOUT"; + public static final String INSPECTIT_TEMP_DIR_PROPERTY = "inspectit.temp-dir"; public static final String INSPECTIT_TEMP_DIR_ENV_PROPERTY = "INSPECTIT_TEMP_DIR"; @@ -27,6 +31,7 @@ public class AgentProperties { static { PROPERTY_NAMES.add(START_DELAY_PROPERTY); PROPERTY_NAMES.add(RECYCLE_JARS_PROPERTY); + PROPERTY_NAMES.add(RECYCLE_JARS_TIMEOUT_PROPERTY); PROPERTY_NAMES.add(INSPECTIT_TEMP_DIR_PROPERTY); } diff --git a/inspectit-ocelot-documentation/docs/configuration/start-configuration.md b/inspectit-ocelot-documentation/docs/configuration/start-configuration.md index e0ae8eb139..a233a28053 100644 --- a/inspectit-ocelot-documentation/docs/configuration/start-configuration.md +++ b/inspectit-ocelot-documentation/docs/configuration/start-configuration.md @@ -52,7 +52,8 @@ By default, these files will be created temporarily at runtime. Each agent will create these new JAR files for itself inside the temporary directory. When you are running multiple agents on the same machine, this would consume additional storage space. Thus, you can configure the agent to recycle such JAR files via the system property `inspectit.recycle-jars` -or the OS environment variable `INSPECTIT_RECYCLE_JARS`. +or the OS environment variable `INSPECTIT_RECYCLE_JARS`. The timeout for this recycling operation can be set via +system property `inspectit.recycle-jars-timeout` or the OS environment variable `INSPECTIT_RECYCLE_JARS_TIMEOUT` ``` -Dinspectit.recycle-jars=true @@ -60,5 +61,13 @@ or the OS environment variable `INSPECTIT_RECYCLE_JARS`. The agent will look inside ``${temporary-directory}/inspectit-ocelot/{inspectit-ocelot-version}`` for JAR files. If no files have been found, the agent will create new ones, which can also be used by other agents. -**These files will not be deleted after the shutdown of the agent.** Thus, when you are updating your agent version, +**These files will not be deletfed after the shutdown of the agent.** Thus, when you are updating your agent version, you will have to delete the JAR files from the previous version manually. + +``` +-Dinspectit.recycle-jars-timeout=3000 +``` + +During JAR recycling, the agent attempts to lock the JARs during startup. However, when starting multiple JVMs at the +same time, it can occur that the JVMs lock each other out, leading to an error. This parameter allows changing +the timeout of the file lock retry to allow for more retries, making startup more robust. The default is set to 3000ms.