Skip to content
This repository has been archived by the owner on Nov 17, 2022. It is now read-only.
Permalink
Browse files
[JENKINS-50669] reflective access shim
  • Loading branch information
batmat committed Apr 9, 2018
1 parent 4de3883 commit 5f42dc4e3cca1981dc7c5636b4139731c0d16ec4
Showing 1 changed file with 32 additions and 6 deletions.
@@ -1,12 +1,14 @@
package io.jenkins.plugins.essentials.logging;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.WebAppMain;
import hudson.init.InitMilestone;
import hudson.init.Initializer;
import hudson.triggers.SafeTimerTask;
import jenkins.model.Jenkins;

import java.io.File;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Comparator;
import java.util.logging.FileHandler;
@@ -27,10 +29,7 @@ public static void configure() throws Exception {
// Lower Level, debugging hack
LOGGER.log(Level.SEVERE, "I started!");

if (Jenkins.logRecords.size() >= getMaxNumberOfLogs()) {
LOGGER.severe("The Jenkins logs buffer is full. " +
"Some logs might have been missed, and so many logs shows something probably very wrong!");
}
checkNotTooManyLogsAlready();

// FIXME: should I use the no-arg ctor to let usual sysprops be usable?
FileHandler fileHandler = new FileHandler(getFilePattern(), 10 * 1000 * 1000, 5, false);
@@ -44,6 +43,25 @@ public static void configure() throws Exception {
Logger.getLogger("").addHandler(fileHandler);
}

/**
* {@link Jenkins#logRecords} uses an underlying {@link hudson.util.RingBufferLogHandler} with a default size of 256 (at least until 2.114 included).
* In our case, we use it only once to access the logs that were generated <strong>before</strong> the current plugin is started.
* <p>
* If that ring buffer is full, that already means per-se something is most likely unhealthy.
* In normal conditions, there should be only like 20 log entries in that buffer when the plugin starts.
*/
private static void checkNotTooManyLogsAlready() {
final int logRecordsSize = Jenkins.logRecords.size();
LOGGER.log(Level.INFO, "There are {0} log entries that were generated already.", logRecordsSize);

final int maxNumberOfLogs = getMaxNumberOfLogs();
if (logRecordsSize >= maxNumberOfLogs) {
LOGGER.log(Level.SEVERE,
"The Jenkins logs buffer is already full. " +
"Some logs might have been missed, and so many logs shows something probably very wrong! (max={0})",
maxNumberOfLogs);
}
}

@SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
private static String getFilePattern() {
@@ -55,12 +73,20 @@ private static String getFilePattern() {
/**
* Returns the size of the logs buffer used behind .
* <p>
* FIXME: un-hardcode 256 to use the actual value used in {@link hudson.util.RingBufferLogHandler#records.size()}
* FIXME: use the new non-reflective access method when JENKINS-50669 is done.
*
* @return the size of the {@link Jenkins#logRecords} logs buffer.
*/
private static int getMaxNumberOfLogs() {
return 256;
try {
final Field default_ring_buffer_size = WebAppMain.class.getDeclaredField("DEFAULT_RING_BUFFER_SIZE");
default_ring_buffer_size.setAccessible(true);
final int anInt = default_ring_buffer_size.getInt(null);
return anInt;
} catch (NoSuchFieldException | IllegalAccessException e) {
LOGGER.log(Level.SEVERE, "Unable to access WebAppMain.DEFAULT_RING_BUFFER_SIZE. Returning default value.");
return 256;
}
}

}

0 comments on commit 5f42dc4

Please sign in to comment.