jenkins 查看请求调用栈信息

前言  

  在日常开发的过程中,经常使用到Jenkins执行相关的构建任务。因为经常使用,便对Jenkins产生了浓厚的兴趣,尤其是对它插件机制想一探究竟。当把Jenkins源码下载到本地之后,才发现阅读Jenkins源码是一份十分痛苦的事情,它并不是采用经常使用到的spring系列来开发出来。在网上了解一下Jenkins所使用的开发框架和相关的技术,发现相关的资料少的可怜。想根据请求的URL,找到该URL被路由到那个方法,完全不像SpringMVC只要搜索一下就找出来了,剩下的工作只需要打断点,慢慢调试就能弄清楚全部执行流程。不过好在它是用JAVA开发的,于是硬着头皮折腾一阵子,终于发现了一小窍门。原来Jenkins开发人员早就是意识到这个问题了,只需要在启动命令上面加上-Dstapler.trace=true 这一参数,就可以看到请求URL所对应的调用栈信息。

 

原理

  Jenkins是采用Stapler框架开发,有关这个框架的详细介绍,大家可以在网上查找相关资料来了解它在此不在详述。通过阅读这个框架最核心的类 org.kohsuke.stapler.Stapler (类似于SpringMVC DispatcherServlet,用于将请求映射到具体的处理方法),发现该类存在如下变量

    /**
     * This flag will activate the evaluation trace.
     * It adds the evaluation process as HTTP headers,
     * and when the evaluation failed, special diagnostic 404 page will be rendered.
     * Useful for developer assistance.
     */
    public static boolean TRACE = Boolean.getBoolean("stapler.trace");

如果该变量值为true的话,将会将触发org.kohsuke.stapler.EvaluationTrace类的trace方法调用,该方法源码如下,该方法会将调用堆栈信息放到请求响应头中。

 1 public class EvaluationTrace {
 2 
 3     public void trace(StaplerResponse rsp, String msg) {
 4         traces.add(msg);
 5         // Firefox Live HTTP header plugin cannot nicely render multiple headers
 6         // with the same name, so give each one unique name.
 7         rsp.addHeader(String.format("Stapler-Trace-%03d",traces.size()),msg.replace("\n","\\n").replace("\r","\\r"));
 8     }
 9 
10

 

设置参数

  Boolean.getBoolean方法是从System.getProperties中获取变量值,所以只需要在启动命令上使用-D传入该参数即可。我在本地是使用tomcat部署jenkins的,使用eclipse没有跑起来,在tomcat上设置变量
值有多种方法,我采取是比较“暴力”的手段,直接修改启动脚本。打开tomcat/bin文件夹中的catalina.bat脚本文件,在文件开始部分添加如下变量,如下所示:
  1 @echo off
  2 rem Licensed to the Apache Software Foundation (ASF) under one or more
  3 rem contributor license agreements.  See the NOTICE file distributed with
  4 rem this work for additional information regarding copyright ownership.
  5 rem The ASF licenses this file to You under the Apache License, Version 2.0
  6 rem (the "License"); you may not use this file except in compliance with
  7 rem the License.  You may obtain a copy of the License at
  8 rem
  9 rem     http://www.apache.org/licenses/LICENSE-2.0
 10 rem
 11 rem Unless required by applicable law or agreed to in writing, software
 12 rem distributed under the License is distributed on an "AS IS" BASIS,
 13 rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14 rem See the License for the specific language governing permissions and
 15 rem limitations under the License.
 16 
 17 rem ---------------------------------------------------------------------------
 18 rem Start/Stop Script for the CATALINA Server
 19 rem
 20 rem For supported commands call "catalina.bat help" or see the usage section
 21 rem towards the end of this file.
 22 rem
 23 rem Environment Variable Prerequisites
 24 rem
 25 rem   Do not set the variables in this script. Instead put them into a script
 26 rem   setenv.bat in CATALINA_BASE/bin to keep your customizations separate.
 27 rem
 28 rem   WHEN RUNNING TOMCAT AS A WINDOWS SERVICE:
 29 rem   Note that the environment variables that affect the behavior of this
 30 rem   script will have no effect at all on Windows Services. As such, any
 31 rem   local customizations made in a CATALINA_BASE/bin/setenv.bat script
 32 rem   will also have no effect on Tomcat when launched as a Windows Service.
 33 rem   The configuration that controls Windows Services is stored in the Windows
 34 rem   Registry, and is most conveniently maintained using the "tomcat8w.exe"
 35 rem   maintenance utility.
 36 rem
 37 rem   CATALINA_HOME   May point at your Catalina "build" directory.
 38 rem
 39 rem   CATALINA_BASE   (Optional) Base directory for resolving dynamic portions
 40 rem                   of a Catalina installation.  If not present, resolves to
 41 rem                   the same directory that CATALINA_HOME points to.
 42 rem
 43 rem   CATALINA_OPTS   (Optional) Java runtime options used when the "start",
 44 rem                   "run" or "debug" command is executed.
 45 rem                   Include here and not in JAVA_OPTS all options, that should
 46 rem                   only be used by Tomcat itself, not by the stop process,
 47 rem                   the version command etc.
 48 rem                   Examples are heap size, GC logging, JMX ports etc.
 49 rem
 50 rem   CATALINA_TMPDIR (Optional) Directory path location of temporary directory
 51 rem                   the JVM should use (java.io.tmpdir).  Defaults to
 52 rem                   %CATALINA_BASE%\temp.
 53 rem
 54 rem   JAVA_HOME       Must point at your Java Development Kit installation.
 55 rem                   Required to run the with the "debug" argument.
 56 rem
 57 rem   JRE_HOME        Must point at your Java Runtime installation.
 58 rem                   Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME
 59 rem                   are both set, JRE_HOME is used.
 60 rem
 61 rem   JAVA_OPTS       (Optional) Java runtime options used when any command
 62 rem                   is executed.
 63 rem                   Include here and not in CATALINA_OPTS all options, that
 64 rem                   should be used by Tomcat and also by the stop process,
 65 rem                   the version command etc.
 66 rem                   Most options should go into CATALINA_OPTS.
 67 rem
 68 rem   JAVA_ENDORSED_DIRS (Optional) Lists of of semi-colon separated directories
 69 rem                   containing some jars in order to allow replacement of APIs
 70 rem                   created outside of the JCP (i.e. DOM and SAX from W3C).
 71 rem                   It can also be used to update the XML parser implementation.
 72 rem                   This is only supported for Java <= 8.
 73 rem                   Defaults to $CATALINA_HOME/endorsed.
 74 rem
 75 rem   JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"
 76 rem                   command is executed. The default is "dt_socket".
 77 rem
 78 rem   JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"
 79 rem                   command is executed. The default is localhost:8000.
 80 rem
 81 rem   JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"
 82 rem                   command is executed. Specifies whether JVM should suspend
 83 rem                   execution immediately after startup. Default is "n".
 84 rem
 85 rem   JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"
 86 rem                   command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
 87 rem                   and JPDA_SUSPEND are ignored. Thus, all required jpda
 88 rem                   options MUST be specified. The default is:
 89 rem
 90 rem                   -agentlib:jdwp=transport=%JPDA_TRANSPORT%,
 91 rem                       address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
 92 rem
 93 rem   JSSE_OPTS       (Optional) Java runtime options used to control the TLS
 94 rem                   implementation when JSSE is used. Default is:
 95 rem                   "-Djdk.tls.ephemeralDHKeySize=2048"
 96 rem
 97 rem   LOGGING_CONFIG  (Optional) Override Tomcat's logging config file
 98 rem                   Example (all one line)
 99 rem                   set LOGGING_CONFIG="-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties"
100 rem
101 rem   LOGGING_MANAGER (Optional) Override Tomcat's logging manager
102 rem                   Example (all one line)
103 rem                   set LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
104 rem
105 rem   TITLE           (Optional) Specify the title of Tomcat window. The default
106 rem                   TITLE is Tomcat if it's not specified.
107 rem                   Example (all one line)
108 rem                   set TITLE=Tomcat.Cluster#1.Server#1 [%DATE% %TIME%]
109 rem ---------------------------------------------------------------------------
110 
111 setlocal
112 
113 set JAVA_OPTS="-Djenkins.install.runSetupWizard=false"
114 set JAVA_OPTS="%JAVA_OPTS%" "-Dstapler.trace=true"

直接在 JAVA_OPTS变量名中设置-Dstapler.trace=true,-Djenkins.install.runSetupWizard=false 这个变量是用来跳过安装向导,因为安装jenkins是要下载插件而下载这些插件十分耗时,所以使用这个参数直接跳过安装向导。

 

效果

老套路,使用chrome浏览器,按F12,切换到Network,随便点击面板中某个请求链接(非请求静态资源),查看请求的响应头。比如请求 /jenkins/,该请求响应头包含的调用栈信息,如下所示:

1 Stapler-Trace-001: -> evaluate(<hudson.model.Hudson@28cec7> :hudson.model.Hudson,"")
2 Stapler-Trace-002: -> evaluate(((StaplerProxy)<hudson.model.Hudson@28cec7>).getTarget(),"")
3 Stapler-Trace-003: -> evaluate(((StaplerFallback)<hudson.model.Hudson@28cec7>).getStaplerFallback(),"")
4 Stapler-Trace-004: -> evaluate(<hudson.model.AllView@552d7b[view/all/]> :hudson.model.AllView,"")
5 Stapler-Trace-005: -> index on <hudson.model.AllView@552d7b[view/all/]>

你可能感兴趣的:(jenkins 查看请求调用栈信息)