Skip to content
Permalink
Browse files

Merge pull request #114 from duemir/JENKINS-46132

JENKINS-46132 - Download actual proc info from the Linux agents
  • Loading branch information
christ66 committed Jan 15, 2018
2 parents 1e4d189 + 2191eac commit 2130103a81556280d6bbf9239be2b6f9fd89b37c
@@ -24,11 +24,15 @@

package com.cloudbees.jenkins.support.api;

import com.cloudbees.jenkins.support.SupportLogFormatter;
import hudson.FilePath;
import hudson.util.IOException2;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.file.NoSuchFileException;

/**
* Content that is stored as a file on a remote disk
@@ -37,6 +41,10 @@
*/
public class FilePathContent extends Content {

private static boolean isFileNotFound(Throwable e) {
return e instanceof FileNotFoundException || e instanceof NoSuchFileException;
}

private final FilePath file;

public FilePathContent(String name, FilePath file) {
@@ -49,7 +57,25 @@ public void writeTo(OutputStream os) throws IOException {
try {
file.copyTo(os);
} catch (InterruptedException e) {
throw new IOException2(e);
throw new IOException(e);
} catch (IOException e) {
if (isFileNotFound(e) || isFileNotFound(e.getCause())) {
OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8");
try {
PrintWriter pw = new PrintWriter(osw, true);
try {
pw.println("--- WARNING: Could not attach " + file.getRemote() + " as it cannot currently be found ---");
pw.println();
SupportLogFormatter.printStackTrace(e, pw);
} finally {
pw.flush();
}
} finally {
osw.flush();
}
} else {
throw e;
}
}
}

@@ -58,7 +84,7 @@ public long getTime() throws IOException {
try {
return file.lastModified();
} catch (InterruptedException e) {
throw new IOException2(e);
throw new IOException(e);
}
}
}
@@ -3,37 +3,53 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

/**
* System metrics of the JVM process. Only supports Unix.
*/
@Extension
public class JVMProcessSystemMetricsContents extends ProcFilesRetriever {
public abstract class JVMProcessSystemMetricsContents extends ProcFilesRetriever {
@Extension
public static class Master extends JVMProcessSystemMetricsContents {
@Override
@NonNull
public String getDisplayName() {
return "Master JVM process system metrics (Linux only)";
}
}

@Extension
public static class Agents extends JVMProcessSystemMetricsContents {
@Override
@NonNull
public String getDisplayName() {
return "Agent JVM process system metrics (Linux only)";
}

@Override
public boolean isSelectedByDefault() {
return false;
}
}

private static final Logger LOGGER = Logger.getLogger(JVMProcessSystemMetricsContents.class.getName());
static final 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");
Map<String, String> contents = new HashMap<String, String>();
contents.put("/proc/meminfo", "meminfo.txt");
contents.put("/proc/self/status", "self/status.txt");
contents.put("/proc/self/cmdline", "self/cmdline");
contents.put("/proc/self/environ", "self/environ");
contents.put("/proc/self/limits", "self/limits.txt");
contents.put("/proc/self/mountstats", "self/mountstats.txt");
UNIX_PROC_CONTENTS = Collections.unmodifiableMap(contents);
}


@Override
public Map<String, String> getFilesToRetrieve() {
return UNIX_PROC_CONTENTS;
}

@Override
@NonNull
public String getDisplayName() {
return "JVM process system metrics (Linux only)";
}
}
@@ -3,16 +3,15 @@
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.api.FilePathContent;
import com.cloudbees.jenkins.support.util.SystemPlatform;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.FilePath;
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;
@@ -64,11 +63,11 @@ public void addContents(@NonNull Container container) {

protected void addUnixContents(@NonNull Container container, final @NonNull Node node) {
Computer c = node.toComputer();
if (c == null) {
if (c == null || c.isOffline()) {
return;
}
// fast path bailout for Windows
if (c instanceof SlaveComputer && !Boolean.TRUE.equals(((SlaveComputer) c).isUnix())) {
if (!Boolean.TRUE.equals(c.isUnix())) {
return;
}
SystemPlatform nodeSystemPlatform = getSystemPlatform(node);
@@ -83,8 +82,8 @@ protected void addUnixContents(@NonNull Container container, final @NonNull Node
}

for (Map.Entry<String, String> procDescriptor : getFilesToRetrieve().entrySet()) {
container.add(new FileContent("nodes/" + name + "/proc/" + procDescriptor.getValue(),
new File(procDescriptor.getKey())));
container.add(new FilePathContent("nodes/" + name + "/proc/" + procDescriptor.getValue(),
new FilePath(c.getChannel(), procDescriptor.getKey())));
}

afterAddUnixContents(container, node, name);
@@ -35,6 +35,7 @@

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
@@ -46,8 +47,29 @@
* System configuration data (CPU information, swap configuration, mount points,
* kernel messages and entropy)
*/
@Extension
public class SystemConfiguration extends ProcFilesRetriever {
public abstract class SystemConfiguration extends ProcFilesRetriever {
@Extension
public static class Master extends SystemConfiguration {
@Override
@NonNull
public String getDisplayName() {
return "Master system configuration (Linux only)";
}
}

@Extension
public static class Agents extends SystemConfiguration {
@Override
@NonNull
public String getDisplayName() {
return "Agent system configuration (Linux only)";
}

@Override
public boolean isSelectedByDefault() {
return false;
}
}

private final WeakHashMap<Node,String> sysCtlCache = new WeakHashMap<Node, String>();

@@ -59,26 +81,21 @@
private static final Map<String,String> UNIX_PROC_CONTENTS;

static {
UNIX_PROC_CONTENTS = new HashMap<String,String>();
UNIX_PROC_CONTENTS.put("/proc/swaps", "swaps.txt");
UNIX_PROC_CONTENTS.put("/proc/cpuinfo", "cpuinfo.txt");
UNIX_PROC_CONTENTS.put("/proc/mounts", "mounts.txt");
UNIX_PROC_CONTENTS.put("/proc/uptime", "system-uptime.txt");
UNIX_PROC_CONTENTS.put("/proc/net/rpc/nfs", "net/rpc/nfs.txt");
UNIX_PROC_CONTENTS.put("/proc/net/rpc/nfsd", "net/rpc/nfsd.txt");
Map<String, String> contents = new HashMap<String,String>();
contents.put("/proc/swaps", "swaps.txt");
contents.put("/proc/cpuinfo", "cpuinfo.txt");
contents.put("/proc/mounts", "mounts.txt");
contents.put("/proc/uptime", "system-uptime.txt");
contents.put("/proc/net/rpc/nfs", "net/rpc/nfs.txt");
contents.put("/proc/net/rpc/nfsd", "net/rpc/nfsd.txt");
UNIX_PROC_CONTENTS = Collections.unmodifiableMap(contents);
}

@Override
public Map<String, String> getFilesToRetrieve() {
return UNIX_PROC_CONTENTS;
}

@Override
@NonNull
public String getDisplayName() {
return "System configuration (Linux only)";
}

@Override
protected void afterAddUnixContents(@NonNull Container container, final @NonNull Node node, String name) {
container.add(

0 comments on commit 2130103

Please sign in to comment.
You can’t perform that action at this time.