JENKINS-36884# Analytics-tools plugin to integrated rollbar (#374)
* JENKINS-36884# Analytics-tools plugin to integrated rollbar Also includes infrastrucutre to inject HTML head tags and HTTP header by any plugin that implements BluePageDecorator and appropriate jelly files. * Doc update * Wrapped rollbar JS code inside IIFE. * Use rollbar-browser package and build browser bundle * Fixes and doc update - Stapler includei jelly tag needs escaping $ - Added missing dependency in gulpfile.js - require should load browser-rollbar
This commit is contained in:
parent
3958b8aaa3
commit
e181cf5a91
|
@ -39,8 +39,11 @@ Provides implementation of Pipeline apis for Jenkins pipeline and multi-branch j
|
||||||
|
|
||||||
## blueocean-web
|
## blueocean-web
|
||||||
|
|
||||||
Web infrastructure that glues Jenkins and Blue Ocean plugin together on the /blue endpoint.
|
Core Web infrastructure that bootstraps BlueOcean UI and integrates REST API core blueocean-rest.
|
||||||
|
|
||||||
|
## blueocean-analytics-tools
|
||||||
|
|
||||||
|
Plugin to inject analytics tools as HTML header in blueocean UI.
|
||||||
|
|
||||||
# Building and running
|
# Building and running
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 CloudBees Inc and a number of other of contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
|
@ -0,0 +1,21 @@
|
||||||
|
> Analytics Tools to be injected in to BlueOcean UI
|
||||||
|
|
||||||
|
# RollBar
|
||||||
|
|
||||||
|
* Enable RollBar
|
||||||
|
|
||||||
|
RollBar is disabled by default. Use BLUEOCEAN_ROLLBAR_ENABLED JVM property to enable.
|
||||||
|
|
||||||
|
````
|
||||||
|
mvn hpi:run -DBLUEOCEAN_ROLLBAR_ENABLED=true
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
## Usage ...
|
||||||
|
|
||||||
|
try {
|
||||||
|
foo();
|
||||||
|
$blueocean_Rollbar.debug('foo() called');
|
||||||
|
} catch (e) {
|
||||||
|
$blueocean_Rollbar.error('Problem calling foo()', e);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
var builder = require('@jenkins-cd/js-builder');
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the rollbar bundle.
|
||||||
|
// See https://github.com/jenkinsci/js-builder
|
||||||
|
//
|
||||||
|
builder.bundle('src/main/js/rollbar.js');
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "blueocean-analytics-tools",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "Analytics tools that gets injected in BlueOcean UI",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Vivek Pandey <vivek.pandey@gmail.com> (https://github.com/vivek)",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@jenkins-cd/js-modules": "0.0.5",
|
||||||
|
"rollbar-browser": "1.9.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@jenkins-cd/js-builder": "0.0.35",
|
||||||
|
"babel-eslint": "^6.1.2",
|
||||||
|
"gulp": "3.9.1",
|
||||||
|
"eslint-plugin-react": "^5.0.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>io.jenkins.blueocean</groupId>
|
||||||
|
<artifactId>blueocean-parent</artifactId>
|
||||||
|
<version>1.0-alpha-5-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>blueocean-analytics-tools</artifactId>
|
||||||
|
<packaging>hpi</packaging>
|
||||||
|
|
||||||
|
<name>BlueOcean :: Analytics Tools</name>
|
||||||
|
<url>https://wiki.jenkins-ci.org/display/JENKINS/Blue+Ocean+Plugin</url>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>blueocean-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,22 @@
|
||||||
|
package io.jenkins.blueocean.analyticstools;
|
||||||
|
|
||||||
|
import hudson.Extension;
|
||||||
|
import io.jenkins.blueocean.BluePageDecorator;
|
||||||
|
import jenkins.model.Jenkins;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vivek Pandey
|
||||||
|
*/
|
||||||
|
@Extension(ordinal = 10)
|
||||||
|
public class AnalyticsTools extends BluePageDecorator {
|
||||||
|
|
||||||
|
public boolean isRollBarEnabled(){
|
||||||
|
return Boolean.getBoolean("BLUEOCEAN_ROLLBAR_ENABLED");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** gives Blueocean plugin version. blueocean-web being core module is looked at to determine the version */
|
||||||
|
public String getBlueOceanPluginVersion(){
|
||||||
|
return Jenkins.getInstance().getPlugin("blueocean-web").getWrapper().getVersion();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
function getConfigAttribute(name) {
|
||||||
|
var headElements = document.getElementsByTagName('head');
|
||||||
|
if (headElements.length === 1) {
|
||||||
|
return headElements[0].getAttribute(name);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeURL(location) {
|
||||||
|
var normalizedUrl = 'http://anon.blueocean.io' + location;
|
||||||
|
var rootUrl = getConfigAttribute('data-rooturl');
|
||||||
|
if (rootUrl && location.startsWith(rootUrl)) {
|
||||||
|
normalizedUrl = 'http://anon.blueocean.io' + location.substring(rootUrl.length - 1, location.length);
|
||||||
|
}
|
||||||
|
return normalizedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
var transformer = function (payload) {
|
||||||
|
payload.data.request.user_ip = '0.0.0.0';
|
||||||
|
payload.data.request.url = normalizeURL(window.location.pathname);
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure rollbar ...
|
||||||
|
// See https://github.com/rollbar/rollbar.js/tree/master/examples/browserify
|
||||||
|
//
|
||||||
|
|
||||||
|
var _rollbarConfig = {
|
||||||
|
accessToken: '81f3134dedf44871b9cc0a347b1313df',
|
||||||
|
captureUncaught: true,
|
||||||
|
code_version: window.$blueocean_pluginVersion, // see header.jelly
|
||||||
|
source_map_enabled: true,
|
||||||
|
guess_uncaught_frames: true,
|
||||||
|
transform: transformer
|
||||||
|
};
|
||||||
|
|
||||||
|
var rollbarBrowser = require('rollbar-browser');
|
||||||
|
var Rollbar = rollbarBrowser.init(_rollbarConfig);
|
||||||
|
|
||||||
|
// Looking at docs (https://github.com/rollbar/rollbar.js/tree/master/examples/browserify)
|
||||||
|
// it seems like they stuff it into a global. We are trying hard not to do that
|
||||||
|
// under any circumstances, but maybe this is an exception if it's only going to be
|
||||||
|
// used in a closed/controlled env.
|
||||||
|
//
|
||||||
|
// Soooo .... lets export it to global for now, but as $blueocean_Rollbar ...
|
||||||
|
//
|
||||||
|
|
||||||
|
window.$blueocean_Rollbar = Rollbar;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Usage ...
|
||||||
|
//
|
||||||
|
//try {
|
||||||
|
// foo();
|
||||||
|
// $blueocean_Rollbar.debug('foo() called');
|
||||||
|
//} catch (e) {
|
||||||
|
// $blueocean_Rollbar.error('Problem calling foo()', e);
|
||||||
|
//}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?jelly escape-by-default='true'?>
|
||||||
|
<div>
|
||||||
|
BlueOcean Analytics Tools plugin
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
|
||||||
|
<j:if test="${it.rollBarEnabled}">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Still use a small bit of JS to inject the Rollbar access token.
|
||||||
|
|
||||||
|
I think this is ok for now because we're setting a global anyway - see
|
||||||
|
comment at the end of src/main/js/rollbar.js
|
||||||
|
-->
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
window.$$blueocean_pluginVersion = '${it.blueOceanPluginVersion}';
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Running the plugin build (or just "gulp" from the command line) will
|
||||||
|
generate a browser bundle of what's in src/main/js/rollbar.js and we
|
||||||
|
can load that using an adjunct as follows.
|
||||||
|
|
||||||
|
See gulpfile.js and see the output from running the "gulp" command.
|
||||||
|
-->
|
||||||
|
<st:adjunct includes="org.jenkins.ui.jsmodules.blueocean_analytics_tools.rollbar"/>
|
||||||
|
</j:if>
|
||||||
|
</j:jelly>
|
|
@ -44,6 +44,11 @@
|
||||||
<artifactId>blueocean-pipeline-api-impl</artifactId>
|
<artifactId>blueocean-pipeline-api-impl</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>blueocean-analytics-tools</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Test deps -->
|
<!-- Test deps -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
|
@ -107,6 +112,7 @@
|
||||||
linkHPI('blueocean-commons');
|
linkHPI('blueocean-commons');
|
||||||
linkHPI('blueocean-rest-impl');
|
linkHPI('blueocean-rest-impl');
|
||||||
linkHPI('blueocean-pipeline-api-impl')
|
linkHPI('blueocean-pipeline-api-impl')
|
||||||
|
linkHPI('blueocean-analytics-tools')
|
||||||
</source>
|
</source>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -2,6 +2,8 @@ package io.jenkins.blueocean;
|
||||||
|
|
||||||
import hudson.ExtensionList;
|
import hudson.ExtensionList;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root of Blue Ocean UI
|
* Root of Blue Ocean UI
|
||||||
*
|
*
|
||||||
|
@ -34,4 +36,8 @@ public class BlueOceanUI {
|
||||||
public String getUrlBase() {
|
public String getUrlBase() {
|
||||||
return urlBase;
|
return urlBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<BluePageDecorator> getPageDecorators(){
|
||||||
|
return BluePageDecorator.all();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package io.jenkins.blueocean;
|
||||||
|
|
||||||
|
import hudson.Extension;
|
||||||
|
import hudson.ExtensionList;
|
||||||
|
import hudson.ExtensionPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Participates in the rendering of HTML pages for all pages of Hudson.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This class provides a few hooks to augument the HTML generation process of Hudson, across
|
||||||
|
* all the HTML pages that Hudson delivers.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* For example, if you'd like to add a Google Analytics stat to Hudson, then you need to inject
|
||||||
|
* a small script fragment to all Hudson pages. This extension point provides a means to do that.
|
||||||
|
*
|
||||||
|
* <h2>Life-cycle</h2>
|
||||||
|
* <p>
|
||||||
|
* Plugins that contribute this extension point
|
||||||
|
* should implement a new decorator and put {@link Extension} on the class.
|
||||||
|
*
|
||||||
|
* <h2>Associated Views</h2>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <h3>header.jelly</h3>
|
||||||
|
* <p>
|
||||||
|
* This page is added right before the </head> tag. Convenient place for additional stylesheet, <meta> tags, etc.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
|
||||||
|
* <script>
|
||||||
|
* //your JS code
|
||||||
|
* </script>
|
||||||
|
* </j:jelly>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <h3>httpHeaders.jelly</h3>
|
||||||
|
*
|
||||||
|
* For example, this httpHeader.jelly adds HTTP X-MY-HEADER
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* <?jelly escape-by-default='true'?>
|
||||||
|
* <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
|
||||||
|
* <st:header name="X-MY-HEADER" value="${it.someValue}"/>
|
||||||
|
* </j:jelly>
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* This is a generalization of the X-Jenkins header that aids auto-discovery.
|
||||||
|
* This fragment can write additional <st:header name="..." value="..." /> tags that go along with it.
|
||||||
|
*
|
||||||
|
* @author Vivek Pandey
|
||||||
|
*/
|
||||||
|
public abstract class BluePageDecorator implements ExtensionPoint {
|
||||||
|
|
||||||
|
public static ExtensionList<BluePageDecorator> all() {
|
||||||
|
return ExtensionList.lookup(BluePageDecorator.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,11 @@
|
||||||
<?jelly escape-by-default='true'?>
|
<?jelly escape-by-default='true'?>
|
||||||
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:x="jelly:xml">
|
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:x="jelly:xml">
|
||||||
<st:contentType value="text/html;charset=UTF-8"/>
|
<st:contentType value="text/html;charset=UTF-8"/>
|
||||||
|
|
||||||
|
<!-- Add HTTP headers from extensions. See BluePageDecorator.java -->
|
||||||
|
<j:forEach var="pd" items="${it.pageDecorators}">
|
||||||
|
<st:include it="${pd}" page="httpHeaders.jelly" optional="true"/>
|
||||||
|
</j:forEach>
|
||||||
<x:doctype name="html"/>
|
<x:doctype name="html"/>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
|
@ -29,6 +34,11 @@
|
||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
href="${resURL}/plugin/blueocean-web/assets/css/jenkins-design-language.css"
|
href="${resURL}/plugin/blueocean-web/assets/css/jenkins-design-language.css"
|
||||||
type="text/css"/>
|
type="text/css"/>
|
||||||
|
|
||||||
|
<!-- Inject headers from other extensions. See BluePageDecorator.java -->
|
||||||
|
<j:forEach var="pd" items="${it.pageDecorators}">
|
||||||
|
<st:include it="${pd}" page="header.jelly" optional="true" />
|
||||||
|
</j:forEach>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
7
pom.xml
7
pom.xml
|
@ -105,6 +105,7 @@
|
||||||
<module>blueocean-dashboard</module>
|
<module>blueocean-dashboard</module>
|
||||||
<module>blueocean-personalization</module>
|
<module>blueocean-personalization</module>
|
||||||
<module>blueocean-plugin</module>
|
<module>blueocean-plugin</module>
|
||||||
|
<module>blueocean-analytics-tools</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
@ -172,6 +173,12 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>blueocean-analytics-tools</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>blueocean-plugin</artifactId>
|
<artifactId>blueocean-plugin</artifactId>
|
||||||
|
|
Loading…
Reference in New Issue