|
|
|
/// <reference path="../../includes.ts"/>
|
|
|
|
/// <reference path="../../kubernetes/ts/kubernetesHelpers.ts"/>
|
|
|
|
/// <reference path="developerEnrichers.ts"/>
|
|
|
|
/// <reference path="developerHelpers.ts"/>
|
|
|
|
/// <reference path="developerNavigation.ts"/>
|
|
|
|
|
|
|
|
module Developer {
|
|
|
|
|
|
|
|
export var JenkinsMetricsController = controller("JenkinsMetricsController",
|
|
|
|
["$scope", "KubernetesModel", "KubernetesState", "KubernetesSchema", "$templateCache", "$location", "$routeParams", "$http", "$timeout", "KubernetesApiURL", "ServiceRegistry",
|
|
|
|
($scope, KubernetesModel:Kubernetes.KubernetesModelService, KubernetesState, KubernetesSchema,
|
|
|
|
$templateCache:ng.ITemplateCacheService, $location:ng.ILocationService, $routeParams, $http, $timeout, KubernetesApiURL, ServiceRegistry) => {
|
|
|
|
|
|
|
|
$scope.kubernetes = KubernetesState;
|
|
|
|
$scope.model = KubernetesModel;
|
|
|
|
$scope.id = $routeParams["id"];
|
|
|
|
$scope.jobId = $routeParams["job"];
|
|
|
|
$scope.schema = KubernetesSchema;
|
|
|
|
$scope.jenkins = null;
|
|
|
|
$scope.entityChangedCache = {};
|
|
|
|
|
|
|
|
Kubernetes.initShared($scope, $location, $http, $timeout, $routeParams, KubernetesModel, KubernetesState, KubernetesApiURL);
|
|
|
|
$scope.breadcrumbConfig = Developer.createProjectBreadcrumbs($scope.id);
|
|
|
|
$scope.subTabConfig = Developer.createProjectSubNavBars($scope.id, $scope.jobId);
|
|
|
|
|
|
|
|
$scope.$on('kubernetesModelUpdated', function () {
|
|
|
|
updateData();
|
|
|
|
});
|
|
|
|
|
|
|
|
$scope.$on('$routeUpdate', ($event) => {
|
|
|
|
updateData();
|
|
|
|
});
|
|
|
|
|
|
|
|
$scope.options = {
|
|
|
|
chart: {
|
|
|
|
type: 'discreteBarChart',
|
|
|
|
autorefresh: false,
|
|
|
|
height: 450,
|
|
|
|
margin: {
|
|
|
|
top: 20,
|
|
|
|
right: 20,
|
|
|
|
bottom: 60,
|
|
|
|
left: 45
|
|
|
|
},
|
|
|
|
clipEdge: true,
|
|
|
|
staggerLabels: false,
|
|
|
|
transitionDuration: 500,
|
|
|
|
stacked: false,
|
|
|
|
interactive: true,
|
|
|
|
tooltip: {
|
|
|
|
enabled: true,
|
|
|
|
contentGenerator: (args) => {
|
|
|
|
var data = args.data || {};
|
|
|
|
return data.tooltip;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
color: (d, i) => {
|
|
|
|
return d.color;
|
|
|
|
},
|
|
|
|
xAxis: {
|
|
|
|
axisLabel: 'Builds',
|
|
|
|
showMaxMin: false,
|
|
|
|
tickFormat: function (d) {
|
|
|
|
return "#" + d;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
yAxis: {
|
|
|
|
axisLabel: 'Build Duration (seconds)',
|
|
|
|
tickFormat: function (d) {
|
|
|
|
return d3.format(',.1f')(d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
$scope.data = [];
|
|
|
|
|
|
|
|
updateData();
|
|
|
|
|
|
|
|
function barColourForBuildResult(result) {
|
|
|
|
if (result) {
|
|
|
|
if (result === "FAILURE" || result === "FAILED") {
|
|
|
|
return "red";
|
|
|
|
} else if (result === "ABORTED" || result === "INTERUPTED") {
|
|
|
|
return "tan";
|
|
|
|
} else if (result === "SUCCESS") {
|
|
|
|
return "green";
|
|
|
|
} else if (result === "NOT_STARTED") {
|
|
|
|
return "lightgrey"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "darkgrey";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function updateChartData() {
|
|
|
|
var useSingleSet = true;
|
|
|
|
var buildsSucceeded = [];
|
|
|
|
var buildsFailed = [];
|
|
|
|
var successBuildKey = "Succeeded builds";
|
|
|
|
var failedBuildKey = "Failed builds";
|
|
|
|
|
|
|
|
if (useSingleSet) {
|
|
|
|
successBuildKey = "Builds";
|
|
|
|
}
|
|
|
|
|
|
|
|
var count = 0;
|
|
|
|
var builds = _.sortBy($scope.metrics.builds || [], "number");
|
|
|
|
angular.forEach(builds, (build:any) => {
|
|
|
|
var x = build.number;
|
|
|
|
var y = build.duration / 1000;
|
|
|
|
var date = Developer.asDate(build.timeInMillis);
|
|
|
|
var result = build.result || "NOT_STARTED";
|
|
|
|
var color = barColourForBuildResult(result);
|
|
|
|
var iconClass = createBuildStatusIconClass(result);
|
|
|
|
var tooltip = '<h3><i class="' + iconClass + '"></i> ' + build.displayName + '</h3>' +
|
|
|
|
'<p>duration: <b>' + y + '</b> seconds</p>';
|
|
|
|
if (date) {
|
|
|
|
tooltip += '<p>started: <b>' + date + '</b></p>';
|
|
|
|
}
|
|
|
|
if (result) {
|
|
|
|
tooltip += '<p>result: <b>' + result + '</b></p>';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x) {
|
|
|
|
var data = buildsSucceeded;
|
|
|
|
var key = successBuildKey;
|
|
|
|
if (!successBuildKey && (!result || !result.startsWith("SUCC"))) {
|
|
|
|
data = buildsFailed;
|
|
|
|
key = failedBuildKey;
|
|
|
|
}
|
|
|
|
data.push({
|
|
|
|
tooltip: tooltip,
|
|
|
|
color: color,
|
|
|
|
x: x, y: y});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
$scope.data = [];
|
|
|
|
if (buildsSucceeded.length) {
|
|
|
|
$scope.data.push({
|
|
|
|
key: successBuildKey,
|
|
|
|
values: buildsSucceeded
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (buildsFailed.length) {
|
|
|
|
$scope.data.push({
|
|
|
|
key: failedBuildKey,
|
|
|
|
values: buildsFailed
|
|
|
|
});
|
|
|
|
}
|
|
|
|
$scope.api.updateWithData($scope.data);
|
|
|
|
|
|
|
|
$timeout(() => {
|
|
|
|
$scope.api.update();
|
|
|
|
}, 50);
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateData() {
|
|
|
|
var metricsPath = $scope.jobId ? UrlHelpers.join("job", $scope.jobId, "fabric8/metrics") : "fabric8/metrics";
|
|
|
|
var url = Kubernetes.kubernetesProxyUrlForServiceCurrentNamespace(jenkinsServiceNameAndPort, metricsPath);
|
|
|
|
log.info("");
|
|
|
|
if (url && (!$scope.jenkins || Kubernetes.keepPollingModel)) {
|
|
|
|
$http.get(url, jenkinsHttpConfig).
|
|
|
|
success(function (data, status, headers, config) {
|
|
|
|
if (data) {
|
|
|
|
if (hasObjectChanged(data, $scope.entityChangedCache)) {
|
|
|
|
log.info("entity has changed!");
|
|
|
|
$scope.metrics = data;
|
|
|
|
updateChartData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$scope.model.fetched = true;
|
|
|
|
Core.$apply($scope);
|
|
|
|
}).
|
|
|
|
error(function (data, status, headers, config) {
|
|
|
|
log.warn("Failed to load " + url + " " + data + " " + status);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}]);
|
|
|
|
}
|