├── doc
├── images
│ ├── splunk_for_jenkins_post_job.png
│ └── splunk_for_jenkins_config_basic.png
└── extension.md
├── splunk-devops
└── src
│ ├── test
│ ├── resources
│ │ ├── splunk_metadata.properties
│ │ ├── com
│ │ │ └── splunk
│ │ │ │ └── splunkjenkins
│ │ │ │ ├── CoverageMetricTest
│ │ │ │ ├── config.xml
│ │ │ │ └── jobs
│ │ │ │ │ ├── JaCoCo
│ │ │ │ │ ├── workspace
│ │ │ │ │ │ ├── jacoco.exec
│ │ │ │ │ │ ├── classes
│ │ │ │ │ │ │ └── com
│ │ │ │ │ │ │ │ └── mycompany
│ │ │ │ │ │ │ │ ├── App.class
│ │ │ │ │ │ │ │ └── App$Util.class
│ │ │ │ │ │ └── java
│ │ │ │ │ │ │ └── com
│ │ │ │ │ │ │ └── mycompany
│ │ │ │ │ │ │ └── App.java
│ │ │ │ │ └── config.xml
│ │ │ │ │ ├── Cobertura
│ │ │ │ │ ├── workspace
│ │ │ │ │ │ └── coverage.xml
│ │ │ │ │ └── config.xml
│ │ │ │ │ └── Clover
│ │ │ │ │ ├── config.xml
│ │ │ │ │ └── workspace
│ │ │ │ │ └── clover.xml
│ │ │ │ ├── PostBuildGroovyScriptTest.zip
│ │ │ │ └── TestResultAdapterTest
│ │ │ │ └── jobs
│ │ │ │ ├── testng_job1
│ │ │ │ ├── config.xml
│ │ │ │ └── workspace
│ │ │ │ │ └── testng-reporter-log-result.xml
│ │ │ │ └── xunit_job1
│ │ │ │ └── config.xml
│ │ └── logging.properties
│ └── java
│ │ └── com
│ │ └── splunk
│ │ └── splunkjenkins
│ │ ├── SplunkResponse.java
│ │ ├── BaseTest.java
│ │ ├── JdkSplunkLogHandlerTest.java
│ │ ├── TestResultAdapterTest.java
│ │ ├── HealthMonitorTest.java
│ │ ├── utils
│ │ ├── LogEventHelperTest.java
│ │ └── TestCaseResultUtilsTest.java
│ │ ├── TeeConsoleLogFilterTest.java
│ │ ├── CoverageMetricTest.java
│ │ ├── SplunkArchiveFileTest.java
│ │ └── SplunkLogServiceTest.java
│ └── main
│ ├── webapp
│ ├── images
│ │ ├── splunkIcon.png
│ │ ├── hec_token_list.png
│ │ ├── hec_global_config.png
│ │ ├── splunk_logo_black.png
│ │ └── splunk_logo_green.png
│ └── help-splunkAppUrl.html
│ ├── resources
│ ├── com
│ │ └── splunk
│ │ │ └── splunkjenkins
│ │ │ ├── SplunkJenkinsInstallation
│ │ │ ├── help-retriesOnError.html
│ │ │ ├── help-no-splunkAppUrl.html
│ │ │ ├── help-maxEventsBatchSize.html
│ │ │ ├── help-metadataHost.html
│ │ │ ├── help-metadataSource.html
│ │ │ ├── help-splunkAppUrl.html
│ │ │ ├── config.properties
│ │ │ ├── help-rawEventEnabled.html
│ │ │ ├── help-delay.html
│ │ │ ├── help-indexName.html
│ │ │ ├── help-httpInputConfig.html
│ │ │ ├── help-host.html
│ │ │ ├── help-metaDataConfig.html
│ │ │ ├── help-token.html
│ │ │ ├── help-ignoredJobs.html
│ │ │ ├── help-groovyBinding.html
│ │ │ └── config.jelly
│ │ │ ├── SplunkArtifactNotifier
│ │ │ ├── help-skipGlobalSplunkArchive.html
│ │ │ ├── config.properties
│ │ │ ├── help-sizeLimit.html
│ │ │ ├── help-publishFromSlave.html
│ │ │ └── config.jelly
│ │ │ ├── listeners
│ │ │ └── Messages.properties
│ │ │ ├── model
│ │ │ └── MetaDataConfigItem
│ │ │ │ ├── help-value.html
│ │ │ │ ├── help-keyName.html
│ │ │ │ ├── help-dataSource.html
│ │ │ │ └── config.jelly
│ │ │ └── Messages.properties
│ ├── sample.groovy
│ ├── metadata.properties
│ └── junit.xsd
│ ├── java
│ └── com
│ │ └── splunk
│ │ └── splunkjenkins
│ │ ├── model
│ │ ├── TestStatus.java
│ │ ├── EmptyTestCaseGroup.java
│ │ ├── JunitResultAggregateAdapter.java
│ │ ├── EventType.java
│ │ ├── LoggingJobExtractor.java
│ │ ├── JunitTestCaseGroup.java
│ │ ├── JunitResultAdapter.java
│ │ ├── AbstractTestResultAdapter.java
│ │ ├── TestCaseResult.java
│ │ ├── CloverCoverageMetrics.java
│ │ ├── CoberturaCoverageMetrics.java
│ │ ├── JacocoCoverageMetrics.java
│ │ ├── TestNGResultAdapter.java
│ │ └── CucumberTestResultAdapter.java
│ │ ├── utils
│ │ ├── CoverageDetailJsonSerializer.java
│ │ ├── SpecialDoubleAdapter.java
│ │ ├── SpecialFloatAdapter.java
│ │ ├── MultipleHostResolver.java
│ │ └── CustomSSLConnectionSocketFactory.java
│ │ ├── links
│ │ ├── ReportAction.java
│ │ ├── HealthLinkAction.java
│ │ ├── LinkSplunkAction.java
│ │ ├── ComputerLogActionFactory.java
│ │ ├── BuildableItemActionFactory.java
│ │ └── RunActionFactory.java
│ │ ├── listeners
│ │ ├── UserSecurityListener.java
│ │ ├── LoggingComputerListener.java
│ │ ├── LoggingItemListener.java
│ │ ├── LoggingQueueListener.java
│ │ └── LoggingConfigListener.java
│ │ ├── LoggingInitStep.java
│ │ ├── Constants.java
│ │ ├── SplunkArtifactNotifier.java
│ │ └── HealthMonitor.java
│ └── groovy
│ └── com
│ └── splunk
│ └── splunkjenkins
│ └── UserActionDSL.groovy
├── splunk-devops-extend
├── src
│ ├── main
│ │ ├── resources
│ │ │ ├── com
│ │ │ │ └── splunk
│ │ │ │ │ └── splunkjenkins
│ │ │ │ │ ├── SplunkMessageStep
│ │ │ │ │ ├── help-globalScriptEnabled.html
│ │ │ │ │ └── config.jelly
│ │ │ │ │ ├── SplunkPipelineJobProperty
│ │ │ │ │ ├── help.html
│ │ │ │ │ ├── help-enableDiagram.html
│ │ │ │ │ └── config-details.jelly
│ │ │ │ │ ├── SplunkConsoleLogStep
│ │ │ │ │ └── config.jelly
│ │ │ │ │ └── SplunkLogFileStep
│ │ │ │ │ ├── config.properties
│ │ │ │ │ └── config.jelly
│ │ │ └── index.jelly
│ │ └── java
│ │ │ └── com
│ │ │ └── splunk
│ │ │ └── splunkjenkins
│ │ │ ├── SplunkPipelineJobProperty.java
│ │ │ ├── SplunkinsDslVariable.java
│ │ │ ├── SplunkConsoleLogStep.java
│ │ │ ├── PipelineGraphVizSupport.java
│ │ │ ├── SplunkLogFileStep.java
│ │ │ └── PipelineRunSupport.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── splunk
│ │ └── splunkjenkins
│ │ ├── SplunkinsDslVariableTest.java
│ │ ├── SplunkLogFileStepTest.java
│ │ ├── SplunkConsoleLogStepTest.java
│ │ ├── PipelineExecuteDiagramTest.java
│ │ └── StageStepNodesTest.java
└── pom.xml
├── readme.md
├── .gitignore
├── Jenkinsfile
└── splunk-devops-shaded
└── pom.xml
/doc/images/splunk_for_jenkins_post_job.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/splunk/splunkforjenkins/HEAD/doc/images/splunk_for_jenkins_post_job.png
--------------------------------------------------------------------------------
/doc/images/splunk_for_jenkins_config_basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/splunk/splunkforjenkins/HEAD/doc/images/splunk_for_jenkins_config_basic.png
--------------------------------------------------------------------------------
/splunk-devops/src/test/resources/splunk_metadata.properties:
--------------------------------------------------------------------------------
1 | source=unit_test
2 | host=dev
3 | sourcetype=json:jenkins
4 | sourcetype_text=text:jenkins
--------------------------------------------------------------------------------
/splunk-devops/src/test/resources/com/splunk/splunkjenkins/CoverageMetricTest/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
Please configure the URL for splunk_app_jenkins in 2 | Splunk plugin configure advance section 3 |
3 | Enable sending pipeline execution diagram by default 4 |
5 |The number of times the plugin will try to send data to Splunk before giving up.
3 |Please configure the URL for splunk_app_jenkins in 2 | Splunk plugin configure advance section 3 |
The buffer size of the batch of events to send to Splunk. The default value is 262144(256KB).
3 |
4 | search host="servername"
5 |
6 |
4 | search source="sourcename"
5 |
6 |
4 | archive("**/*.log")
5 |
6 | when the DSL does not fit for specific set of job.
7 | HTTP Event Collector supports arbitrary data formats similar to Splunk forwarders, 3 | relying on line-breaking rules etc. Supported in Splunk 6.3.1511 and later release 4 |
5 |Schedules the specified task for repeated fixed-rate execution beginning after the specified delay. Subsequent 3 | executions take place at approximately regular intervals, separated by the specified period.
4 |The index in Splunk to which the events will be indexed to. Defaults to "main" index in Splunk. Note: If using a 3 | custom index, that index must be already exist on your Splunk instance. Splunk-Jenkins will not create it for 4 | you.
5 |
3 | The event can be turned off by setting it to Disabled.
4 |
5 | Index is a data repository in Splunk, you can set a different data retention policy and access privileges for
6 | each index in Splunk.
7 |
8 | Source Type is used by Splunk to determine how incoming data is formatted.
9 |
It is recommended to use the plugin's default config 12 | if you are using Splunk App for Jenkins as the App expects a certain metadata format. 13 |
14 | 15 |You need enable HTTP Event Collector in Splunk. 3 | To enable it, go to Splunk Settings > Data inputs > HTTP Event Collector. 4 | Then click the Global Settings button in the upper-right corner. 5 | You can configure HTTP Port number and SSL on the Global Settings. 6 | Port is 8088, and SSL is enabled by default. 7 |8 |
9 | 10 | See more details at HTTP Event Collector 11 | walk through 12 |
13 |The Splunk Indexer hostname or IP address, multiple hosts separated by comma. Example: 3 | "192.168.1.4,192.168.1.5"
4 |Specify index, host, source, soucetype for the events.
3 | index is a data repository in Splunk, please create the 4 indexes in Splunk: 4 | 5 | jenkins, jenkins_statistics, jenkins_console and jenkins_artifact 6 | 7 | 8 |
9 | host is used to identify which Jenkins master is the source of the data.
10 | the metadata can be used in Splunk query language such as
11 | index="jenkins" host="servername" sourcetype="json:jenkins"
12 |
15 | See more details 16 |
17 |You can find the HTTP Event Collector Token in Splunk, go to Splunk Settings > Data inputs > HTTP Event 3 | Collector. 4 |
5 |
6 | 7 | See more details at HTTP Event Collector 8 | walk through 9 |
10 |To verify the token via curl command
11 |
12 | hec_host=<splunk-host>
13 | hec_port=8088
14 | hec_token=<splunk-token>
15 | curl -k "https://${hec_host}:${hec_port}/services/collector/event" -H "Authorization: Splunk ${hec_token}" -d \
16 | '{"host":"test-host","index":"jenkins_console","sourcetype":"json:jenkins","source":"logger://dummy","event":{"level":"INFO","log_source":"cmdline","message":"Test HEC"}}'
17 |
18 |
19 | (?:backgroundJobName|adhocJobName|tempJobName)
6 | will match backgroundJobName, backgroundJobNameBlah, blahbackgroundJobName
7 |^(?:backgroundJobName|adhocJobName|tempJobName)$
8 | will match backgroundJobName but neither backgroundJobNameBlah nor blahbackgroundJobName
9 || (?:X) | 12 |X, as a non-capturing group | 13 |
| ^ | 16 |The beginning of a line | 17 |
| $ | 20 |The end of a line | 21 |
| X|Y | 24 |Either X or Y | 25 |
| \w | 28 |A word character: [a-zA-Z_0-9] | 29 |
| Build Report | 4 |Junit or other Test Reports sent by calling "send(message)" DSL script 5 | | 6 |
| Build Event | 9 |Sent when job are started and completed 10 | | 11 |
| Queue Information | 14 |Basic queue information and Jenkins health metrics 15 | | 16 |
| Console Log | 19 |Build console log, slave log and Jenkins master log (jenkins.log) 20 | | 21 |
| Log File | 24 |Artifact contents, send by calling "archive(includes, excludes)" DSL script 25 | | 26 |
| Slave Information | 29 |The slave(agent) monitor data 30 | | 31 |
| Jenkins Config | 34 |The contents of Jenkins configuration items, e.g. config.xml, sent when the config file get updated. 35 | | 36 |
true if need spit the contents line by line if raw event not supported;
29 | * false otherwise.
30 | */
31 | public boolean needSplit() {
32 | return needSplit;
33 | }
34 |
35 | /**
36 | * @param suffix the config metadata, can be either index, source or sourcetype
37 | * @return return name.suffix
38 | */
39 | public String getKey(String suffix) {
40 | return this.name().toLowerCase() + "." + suffix;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/splunk-devops/src/test/java/com/splunk/splunkjenkins/JdkSplunkLogHandlerTest.java:
--------------------------------------------------------------------------------
1 | package com.splunk.splunkjenkins;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 |
6 | import java.util.UUID;
7 | import java.util.logging.Handler;
8 | import java.util.logging.Logger;
9 |
10 | import static com.splunk.splunkjenkins.SplunkConfigUtil.verifySplunkSearchResult;
11 | import static org.junit.Assert.assertTrue;
12 |
13 | public class JdkSplunkLogHandlerTest extends BaseTest {
14 |
15 | @Before
16 | public void setUp() throws Exception {
17 | super.setUp();
18 | LoggingInitStep.registerHandler();
19 | }
20 |
21 | @Test
22 | public void publish() throws Exception {
23 | Handler[] handlers = Logger.getLogger("").getHandlers();
24 | boolean found = false;
25 | for (Handler handler : handlers) {
26 | if (handler instanceof JdkSplunkLogHandler) {
27 | found = true;
28 | break;
29 | }
30 | }
31 | assertTrue("LoggingInitStep.setupSplunkJenkins() should be called", found);
32 | String message = "test_log_" + UUID.randomUUID();
33 | Logger.getLogger("test_info_logger").info(message);
34 | Logger.getLogger("test_warning_logger").warning(message);
35 | verifySplunkSearchResult(message + " level=WARNING", 1);
36 | verifySplunkSearchResult(message + " level=INFO", 1);
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/splunk-devops/src/test/java/com/splunk/splunkjenkins/TestResultAdapterTest.java:
--------------------------------------------------------------------------------
1 | package com.splunk.splunkjenkins;
2 |
3 | import hudson.model.FreeStyleProject;
4 | import hudson.model.Run;
5 | import org.junit.Test;
6 | import org.jvnet.hudson.test.recipes.LocalData;
7 |
8 | import java.io.IOException;
9 | import java.util.UUID;
10 | import java.util.concurrent.ExecutionException;
11 |
12 | import static com.splunk.splunkjenkins.SplunkConfigUtil.verifySplunkSearchResult;
13 |
14 | public class TestResultAdapterTest extends BaseTest {
15 | @LocalData
16 | @Test
17 | public void verifyTestNG() throws ExecutionException, InterruptedException, IOException {
18 | String query = "ExampleIntegrationTest| spath | search \"testsuite.testcase{}.classname\"=ExampleIntegrationTest";
19 | FreeStyleProject project = (FreeStyleProject) j.getInstance().getItem("testng_job1");
20 | String jobName = UUID.randomUUID().toString();
21 | project.renameTo(jobName);
22 | long startTime = System.currentTimeMillis();
23 | Run run = project.scheduleBuild2(0).get();
24 | verifySplunkSearchResult(query, startTime, 1);
25 | //verify test_summary.total number
26 | String buildUrl = run.getUrl();
27 | query = "type=completed test_summary build_url=\"" + buildUrl + "\"| spath | search test_summary.total=2";
28 | verifySplunkSearchResult(query, startTime, 1);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/Jenkinsfile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 | // Parameters to run test
3 | properties([
4 | parameters([string(defaultValue: '', description: 'Splunk host', name: 'host')
5 | , string(defaultValue: '8089', description: 'Splunk management port', name: 'port')
6 | , string(defaultValue: '', description: 'Username', name: 'username')
7 | , string(defaultValue: '', description: 'Password', name: 'password')
8 | , string(defaultValue: '', description: 'Local Repo Url', name: 'repoUrl')
9 | ]),
10 | [$class: 'jenkins.model.BuildDiscarderProperty', strategy: [$class : 'LogRotator',
11 | numToKeepStr : '50',
12 | artifactNumToKeepStr: '20']]
13 | ])
14 |
15 | node {
16 | checkout scm;
17 | def mvnHome = tool name: 'default', type: 'hudson.tasks.Maven$MavenInstallation'
18 | def mvnCmd = "${mvnHome}/bin/mvn";
19 | if (params.password) {
20 | mvnCmd += " -Dhost=${params.host} -Dport=${params.port} -Dpassword=${params.password} -Dusername=${params.username}"
21 | }
22 | mvnCmd += " -Djava.net.preferIPv4Stack=true clean verify"
23 |
24 | if (params.repoUrl) {
25 | mvnCmd += " -Plocal -Drepos.url=${params.repoUrl} deploy cobertura:cobertura"
26 | }
27 | sh mvnCmd
28 | }
29 |
--------------------------------------------------------------------------------
/splunk-devops/src/test/resources/com/splunk/splunkjenkins/TestResultAdapterTest/jobs/testng_job1/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 | //send job metadata and junit reports with page size set to 50 (each event contains max 50 test cases)
10 | splunkins.sendTestReport(50)
11 | //send coverage, each event contains max 50 class metrics
12 | splunkins.sendCoverageReport(50)
13 | //send all logs from workspace to splunk, with each file size limits to 10MB
14 | splunkins.archive("**/*.log", null, false, "10MB")
15 |
16 |
17 | The groovy script can use the variable splunkins, which provides access to the following objects and methods:
18 |
19 |
20 | Action getAction(Class type);
21 | Action getActionByClassName(String className);
22 | //send message to splunk
23 | boolean send(Object message);
24 | //Archive all configured artifacts from slave, with each file size limit to 10MB, using ant patterns defined in http://ant.apache.org/manual/Types/fileset.html
25 | archive(String includes, String excludes = null, boolean uploadFromSlave = false, String fileSizeLimit = "")
26 | //will send build parameters as metadata and with the object returned from closure to splunk
27 | sendReport(Closure closure)
28 | //a junit report with summary of passes,failures,skips and details of testcase
29 | getJunitReport()
30 | //a a list of junit report each with summary of passes,failures,skips and details of testcase
31 | //each report contains max pageSize testcases
32 | getJunitReport(int pageSize)
33 | sendTestReport(pageSize) //send Test report, with pagination support
34 | sendCoverageReport(pageSize) //send coverage report, with pagination support
35 |
36 | |
13 | |
15 |
16 | |
18 |
19 | |
21 | |
| 25 | | 26 | | 27 | | |
{@code from jenkins javadoc
19 | * (enter) --> waitingList --+--> blockedProjects
20 | * | ^
21 | * | |
22 | * | v
23 | * +--> buildables ---> pending ---> left
24 | * ^ |
25 | * | |
26 | * +---(rarely)---+
27 | *
28 | * }
29 | */
30 | @SuppressWarnings("unused")
31 | @Extension
32 | public class LoggingQueueListener extends QueueListener {
33 | private final static Cache