├── .mvn ├── maven.config └── extensions.xml ├── docs ├── images │ ├── graphics.png │ ├── statistics.png │ ├── systemmonitor128.png │ ├── systemmonitor32.png │ └── system_infos_and_threads.png └── MonitoringScripts.md ├── .gitignore ├── Jenkinsfile ├── src ├── main │ ├── resources │ │ ├── index.jelly │ │ ├── META-INF │ │ │ └── hudson.remoting.ClassFilter │ │ ├── net │ │ │ └── bull │ │ │ │ └── javamelody │ │ │ │ └── NodesColumn │ │ │ │ └── column.jelly.bak │ │ └── org │ │ │ └── jvnet │ │ │ └── hudson │ │ │ └── plugins │ │ │ └── monitoring │ │ │ └── NodeMonitoringAction │ │ │ └── index.jelly │ └── java │ │ ├── org │ │ └── jvnet │ │ │ └── hudson │ │ │ └── plugins │ │ │ └── monitoring │ │ │ ├── NodesMonitoringActionFactory.java │ │ │ ├── NodesListener.java │ │ │ ├── PluginManagementLink.java │ │ │ ├── NodesManagementLink.java │ │ │ ├── NodeMonitoringAction.java │ │ │ ├── HudsonMonitoringFilter.java │ │ │ └── PluginImpl.java │ │ └── net │ │ └── bull │ │ └── javamelody │ │ ├── WaitingDurationQueueListener.java │ │ ├── NodesColumn.bak │ │ ├── CounterBuildStepListener.java │ │ ├── CounterRunListener.java │ │ ├── NodesCollector.java │ │ ├── RemoteCallHelper.java │ │ └── NodesController.java └── test │ └── java │ └── org │ └── jvnet │ └── hudson │ └── plugins │ └── monitoring │ └── MonitoringFilterIntegrationTest.java ├── .github ├── workflows │ └── jenkins-security-scan.yml └── FUNDING.yml ├── pom.xml ├── LICENSE └── README.md /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Pconsume-incrementals 2 | -Pmight-produce-incrementals 3 | -------------------------------------------------------------------------------- /docs/images/graphics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/monitoring-plugin/HEAD/docs/images/graphics.png -------------------------------------------------------------------------------- /docs/images/statistics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/monitoring-plugin/HEAD/docs/images/statistics.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | work 3 | .settings 4 | .classpath 5 | .project 6 | *.iml 7 | *.ipr 8 | *.iws 9 | .idea/ 10 | -------------------------------------------------------------------------------- /docs/images/systemmonitor128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/monitoring-plugin/HEAD/docs/images/systemmonitor128.png -------------------------------------------------------------------------------- /docs/images/systemmonitor32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/monitoring-plugin/HEAD/docs/images/systemmonitor32.png -------------------------------------------------------------------------------- /docs/images/system_infos_and_threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/monitoring-plugin/HEAD/docs/images/system_infos_and_threads.png -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* `buildPlugin` step provided by: https://github.com/jenkins-infra/pipeline-library */ 4 | buildPlugin(useContainerAgent: true, configurations: [ 5 | [platform: 'linux', jdk: 21], 6 | [platform: 'windows', jdk: 17], 7 | ]) 8 | -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 6 | 7 |
32 | ${%JavaMelody Monitoring}
33 | This page provides access to the JavaMelody monitoring of the 35 | ${it.computer.displayName} node. 36 |
37 | 38 | 39 |
36 | * There must be one {@link Plugin} class in each plugin. See javadoc of
37 | * {@link Plugin} for more about what can be done on this class.
38 | * @author Emeric Vernat
39 | */
40 | @SuppressWarnings("deprecation")
41 | public class PluginImpl extends Plugin {
42 | private ServletContext context;
43 | private HudsonMonitoringFilter filter;
44 |
45 | private static class CsrfThread extends Thread {
46 | CsrfThread() {
47 | super();
48 | }
49 |
50 | @Override
51 | public void run() {
52 | final Jenkins jenkins = Jenkins.getInstance();
53 | while (jenkins.getInitLevel() != InitMilestone.COMPLETED) {
54 | try {
55 | Thread.sleep(1000);
56 | } catch (final InterruptedException e) {
57 | // RAS
58 | }
59 | }
60 | if (jenkins.isUseCrumbs()) {
61 | Parameter.CSRF_PROTECTION_ENABLED.setValue("true");
62 | }
63 | }
64 | }
65 |
66 | /** {@inheritDoc} */
67 | @Override
68 | public void start() throws Exception {
69 | super.start();
70 |
71 | // get the servletContext in Jenkins instead of overriding Plugin.setServletContext
72 | final Jenkins jenkins = Jenkins.getInstance();
73 | this.context = jenkins.getServletContext();
74 |
75 | // jenkins.isUseCrumbs() is always false here because it's too early
76 | // and we can't use @Initializer(after = InitMilestone.COMPLETED)
77 | // because of https://issues.jenkins-ci.org/browse/JENKINS-37807
78 | // so check when jenkins is initialized
79 | final Thread thread = new CsrfThread();
80 | thread.setName("javamelody-initializer");
81 | thread.setDaemon(true);
82 | thread.start();
83 |
84 | // on active les actions systemes (gc, heap dump, histogramme memoire,
85 | // processus...), sauf si l'administrateur a dit differemment
86 | if (isParameterUndefined(Parameter.SYSTEM_ACTIONS_ENABLED)) {
87 | Parameter.SYSTEM_ACTIONS_ENABLED.setValue("true");
88 | }
89 | // on desactive les graphiques jdbc et statistiques sql puisqu'il n'y en
90 | // aura pas
91 | if (isParameterUndefined(Parameter.NO_DATABASE)) {
92 | Parameter.NO_DATABASE.setValue("true");
93 | }
94 | // le repertoire de stockage est dans le repertoire de Hudson/Jenkins au lieu
95 | // d'etre dans le repertoire temporaire
96 | // ("/" initial necessaire sous windows pour javamelody v1.8.1)
97 | if (isParameterUndefined(Parameter.STORAGE_DIRECTORY)) {
98 | Parameter.STORAGE_DIRECTORY
99 | .setValue("/" + new File(jenkins.getRootDir(), "monitoring").getAbsolutePath());
100 | }
101 | // http-transform-pattern pour agreger les requetes contenant des
102 | // parties "dynamiques" comme des numeros des builds,
103 | // les fichiers dans job/, Throwable> PROCESS_INFORMATIONS_TASK = new ProcessInformationsTask();
47 | private static final MasterToSlaveCallable
, Throwable> MBEANS_TASK = new MBeansTask();
48 |
49 | private static final class MBeansTask
50 | extends MasterToSlaveCallable
, Throwable> {
51 | private static final long serialVersionUID = 7010512609895185019L;
52 |
53 | MBeansTask() {
54 | super();
55 | }
56 |
57 | @Override
58 | public List
, Throwable> {
65 | private static final long serialVersionUID = -4653173833541398792L;
66 |
67 | ProcessInformationsTask() {
68 | super();
69 | }
70 |
71 | @Override
72 | public List
No agents online, try again in a minute.");
167 | writer.write("");
168 | writer.close();
169 | }
170 | }
171 |
172 | private void writeMessage(HttpServletResponse resp, String message, String partToRedirectTo)
173 | throws IOException {
174 | MonitoringController.noCache(resp);
175 | final PrintWriter writer = createWriterFromOutputStream(resp);
176 | // la periode n'a pas d'importance pour writeMessageIfNotNull
177 | new HtmlReport(collector, null, lastJavaInformationsList, Period.TOUT, writer)
178 | .writeMessageIfNotNull(message, partToRedirectTo);
179 | writer.close();
180 | }
181 |
182 | private void doPdf(HttpServletRequest req, HttpServletResponse resp,
183 | MonitoringController monitoringController) throws IOException, ServletException {
184 | if (HttpPart.PROCESSES.isPart(req)) {
185 | monitoringController.addPdfContentTypeAndDisposition(req, resp);
186 | final Map> result = new ArrayList<>();
344 | for (final JavaInformations javaInformations : lastJavaInformationsList) {
345 | result.add(new ArrayList<>(javaInformations.getThreadInformationsList()));
346 | }
347 | return result;
348 | }
349 |
350 | // utile pour JROBINS_PART, OTHER_JROBINS_PART, SESSIONS_PART et
351 | // defaultSerializable notamment
352 | final SerializableController serializableController = new SerializableController(collector);
353 | return serializableController.createSerializable(httpRequest, lastJavaInformationsList,
354 | null);
355 | }
356 |
357 | private HtmlReport createHtmlReport(HttpServletRequest req, HttpServletResponse resp,
358 | PrintWriter writer) {
359 | final Range range = httpCookieManager.getRange(req, resp);
360 | return new HtmlReport(collector, null, lastJavaInformationsList, range, writer);
361 | }
362 |
363 | private static PrintWriter createWriterFromOutputStream(HttpServletResponse httpResponse)
364 | throws IOException {
365 | MonitoringController.noCache(httpResponse);
366 | httpResponse.setContentType("text/html; charset=UTF-8");
367 | return new PrintWriter(HtmlController.getWriter(httpResponse));
368 | }
369 |
370 | private RemoteCallHelper getRemoteCallHelper() {
371 | return new RemoteCallHelper(nodeName);
372 | }
373 |
374 | /**
375 | * Is it necessary to collect java informations for this monitoring request?
376 | * @param httpRequest HttpServletRequest
377 | * @return boolean
378 | */
379 | public static boolean isJavaInformationsNeeded(HttpServletRequest httpRequest) {
380 | return MonitoringController.isJavaInformationsNeeded(httpRequest);
381 | }
382 | }
383 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |  Monitoring plugin
2 | =================
3 |
4 | [](https://plugins.jenkins.io/monitoring)
5 | [](https://plugins.jenkins.io/monitoring)
6 | [](https://ci.jenkins.io/job/Plugins/job/monitoring-plugin)
7 | [](https://issues.jenkins-ci.org/issues/?jql=component%20%3D%20monitoring-plugin)
8 |
9 | [Monitoring plugin](https://plugins.jenkins.io/monitoring): Monitoring of the performance of Jenkins itself with [JavaMelody](https://github.com/javamelody/javamelody/wiki).
10 |
11 | Open the [report](http://localhost:8080/monitoring) (or