Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #112 from batmat/JENKINS-44236
[JENKINS-44236] NFS stats related /proc files should also be gathered
- Loading branch information
Showing
4 changed files
with
165 additions
and
148 deletions.
There are no files selected for viewing
89 changes: 9 additions & 80 deletions
89
src/main/java/com/cloudbees/jenkins/support/impl/JVMProcessSystemMetricsContents.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,39 @@ | ||
package com.cloudbees.jenkins.support.impl; | ||
|
||
import com.cloudbees.jenkins.support.AsyncResultCache; | ||
import com.cloudbees.jenkins.support.api.Component; | ||
import com.cloudbees.jenkins.support.api.Container; | ||
import com.cloudbees.jenkins.support.api.FileContent; | ||
import com.cloudbees.jenkins.support.util.Helper; | ||
import com.cloudbees.jenkins.support.util.SystemPlatform; | ||
import edu.umd.cs.findbugs.annotations.NonNull; | ||
import hudson.Extension; | ||
import hudson.model.Computer; | ||
import hudson.model.Node; | ||
import hudson.security.Permission; | ||
import hudson.slaves.SlaveComputer; | ||
import jenkins.model.Jenkins; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.WeakHashMap; | ||
import java.util.logging.Level; | ||
import java.util.logging.LogRecord; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* System metrics of the JVM process. Only support Unix | ||
* System metrics of the JVM process. Only supports Unix. | ||
*/ | ||
@Extension | ||
public class JVMProcessSystemMetricsContents extends Component { | ||
public class JVMProcessSystemMetricsContents extends ProcFilesRetriever { | ||
|
||
private static final Logger LOGGER = Logger.getLogger(JVMProcessSystemMetricsContents.class.getName()); | ||
|
||
private final WeakHashMap<Node,SystemPlatform> systemPlatformCache = new WeakHashMap<Node, SystemPlatform>(); | ||
|
||
static Map<String,String> UNIX_PROC_CONTENTS; | ||
static final Map<String,String> UNIX_PROC_CONTENTS; | ||
static { | ||
UNIX_PROC_CONTENTS = new HashMap<String,String>(); | ||
UNIX_PROC_CONTENTS.put("/proc/meminfo", "meminfo.txt"); | ||
UNIX_PROC_CONTENTS.put("/proc/self/status", "self/status.txt"); | ||
UNIX_PROC_CONTENTS.put("/proc/self/cmdline", "self/cmdline"); | ||
UNIX_PROC_CONTENTS.put("/proc/self/environ", "self/environ"); | ||
UNIX_PROC_CONTENTS.put("/proc/self/limits", "self/limits.txt"); | ||
UNIX_PROC_CONTENTS.put("/proc/self/mountstats", "self/mountstats.txt"); | ||
} | ||
|
||
@Override | ||
@NonNull | ||
public String getDisplayName() { | ||
return "JVM process system metrics (Linux only)"; | ||
} | ||
|
||
@NonNull | ||
@Override | ||
public Set<Permission> getRequiredPermissions() { | ||
return Collections.singleton(Jenkins.ADMINISTER); | ||
public Map<String, String> getFilesToRetrieve() { | ||
return UNIX_PROC_CONTENTS; | ||
} | ||
|
||
@Override | ||
public void addContents(@NonNull Container container) { | ||
Jenkins j = Helper.getActiveInstance(); | ||
addUnixContents(container, j); | ||
|
||
for (Node node : j.getNodes()) { | ||
addUnixContents(container, node); | ||
} | ||
} | ||
|
||
private void addUnixContents(@NonNull Container container, final @NonNull Node node) { | ||
Computer c = node.toComputer(); | ||
if (c == null) { | ||
return; | ||
} | ||
// fast path bailout for Windows | ||
if (c instanceof SlaveComputer && !Boolean.TRUE.equals(((SlaveComputer) c).isUnix())) { | ||
return; | ||
} | ||
SystemPlatform nodeSystemPlatform = getSystemPlatform(node); | ||
if (!SystemPlatform.LINUX.equals(nodeSystemPlatform)) { | ||
return; | ||
} | ||
String name; | ||
if (node instanceof Jenkins) { | ||
name = "master"; | ||
} else { | ||
name = "slave/" + node.getNodeName(); | ||
} | ||
|
||
for (Map.Entry<String,String> procDescriptor : UNIX_PROC_CONTENTS.entrySet()) { | ||
container.add(new FileContent("nodes/" + name + "/proc/" + procDescriptor.getValue(), new File(procDescriptor.getKey()))); | ||
} | ||
} | ||
|
||
public SystemPlatform getSystemPlatform(Node node) { | ||
try { | ||
return AsyncResultCache.get(node, systemPlatformCache, new SystemPlatform.GetCurrentPlatform(), "platform", SystemPlatform.UNKNOWN); | ||
} catch (IOException e) { | ||
final LogRecord lr = new LogRecord(Level.FINE, "Could not retrieve system platform type from {0}"); | ||
lr.setParameters(new Object[]{getNodeName(node)}); | ||
lr.setThrown(e); | ||
LOGGER.log(lr); | ||
} | ||
return SystemPlatform.UNKNOWN; | ||
} | ||
|
||
private static String getNodeName(Node node) { | ||
return node instanceof Jenkins ? "master" : node.getNodeName(); | ||
@NonNull | ||
public String getDisplayName() { | ||
return "JVM process system metrics (Linux only)"; | ||
} | ||
} |
116 changes: 116 additions & 0 deletions
116
src/main/java/com/cloudbees/jenkins/support/impl/ProcFilesRetriever.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package com.cloudbees.jenkins.support.impl; | ||
|
||
import com.cloudbees.jenkins.support.AsyncResultCache; | ||
import com.cloudbees.jenkins.support.api.Component; | ||
import com.cloudbees.jenkins.support.api.Container; | ||
import com.cloudbees.jenkins.support.api.FileContent; | ||
import com.cloudbees.jenkins.support.util.Helper; | ||
import com.cloudbees.jenkins.support.util.SystemPlatform; | ||
import edu.umd.cs.findbugs.annotations.NonNull; | ||
import hudson.model.Computer; | ||
import hudson.model.Node; | ||
import hudson.security.Permission; | ||
import hudson.slaves.SlaveComputer; | ||
import jenkins.model.Jenkins; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.WeakHashMap; | ||
import java.util.logging.Level; | ||
import java.util.logging.LogRecord; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* Base class for gathering specified /proc files | ||
*/ | ||
public abstract class ProcFilesRetriever extends Component { | ||
private static final Logger LOGGER = Logger.getLogger(ProcFilesRetriever.class.getName()); | ||
private final WeakHashMap<Node, SystemPlatform> systemPlatformCache = new WeakHashMap<>(); | ||
|
||
protected static String getNodeName(Node node) { | ||
return node instanceof Jenkins ? "master" : node.getNodeName(); | ||
} | ||
|
||
/** | ||
* Returns the map of files that should be retrieved. | ||
* <p> | ||
* <code>file name => path in the support bundle</code>. | ||
* </p> | ||
* <p> | ||
* For example <code>/proc/meminfo => meminfo.txt</code>. | ||
* </p> | ||
* | ||
* @return the map of files that should be retrieved and put in the support bundle. | ||
*/ | ||
abstract public Map<String, String> getFilesToRetrieve(); | ||
|
||
@NonNull | ||
@Override | ||
public Set<Permission> getRequiredPermissions() { | ||
return Collections.singleton(Jenkins.ADMINISTER); | ||
} | ||
|
||
@Override | ||
public void addContents(@NonNull Container container) { | ||
Jenkins j = Helper.getActiveInstance(); | ||
addUnixContents(container, j); | ||
|
||
for (Node node : j.getNodes()) { | ||
addUnixContents(container, node); | ||
} | ||
} | ||
|
||
protected void addUnixContents(@NonNull Container container, final @NonNull Node node) { | ||
Computer c = node.toComputer(); | ||
if (c == null) { | ||
return; | ||
} | ||
// fast path bailout for Windows | ||
if (c instanceof SlaveComputer && !Boolean.TRUE.equals(((SlaveComputer) c).isUnix())) { | ||
return; | ||
} | ||
SystemPlatform nodeSystemPlatform = getSystemPlatform(node); | ||
if (!SystemPlatform.LINUX.equals(nodeSystemPlatform)) { | ||
return; | ||
} | ||
String name; | ||
if (node instanceof Jenkins) { | ||
name = "master"; | ||
} else { | ||
name = "slave/" + node.getNodeName(); | ||
} | ||
|
||
for (Map.Entry<String, String> procDescriptor : getFilesToRetrieve().entrySet()) { | ||
container.add(new FileContent("nodes/" + name + "/proc/" + procDescriptor.getValue(), | ||
new File(procDescriptor.getKey()))); | ||
} | ||
|
||
afterAddUnixContents(container, node, name); | ||
} | ||
|
||
/** | ||
* Override this method if you want to hook some code after {@link #addUnixContents(Container, Node)}. | ||
* | ||
* @param container the support {@link Container}. | ||
* @param node the node for which the method is called. | ||
* @param name the node name, <em>"master"</em> if Master, and <em>slave/${nodeName}</em> if an agent. | ||
*/ | ||
protected void afterAddUnixContents(@NonNull Container container, final @NonNull Node node, String name) { | ||
} | ||
|
||
public SystemPlatform getSystemPlatform(Node node) { | ||
try { | ||
return AsyncResultCache.get(node, systemPlatformCache, new SystemPlatform.GetCurrentPlatform(), "platform", | ||
SystemPlatform.UNKNOWN); | ||
} catch (IOException e) { | ||
final LogRecord record = new LogRecord(Level.FINE, "Could not retrieve system platform type from {0}"); | ||
record.setParameters(new Object[]{getNodeName(node)}); | ||
record.setThrown(e); | ||
LOGGER.log(record); | ||
} | ||
return SystemPlatform.UNKNOWN; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.