Skip to content

Commit

Permalink
Add smart lookup for logback JMXConfigurator MBean
Browse files Browse the repository at this point in the history
Rather than relying on a constant mbean name for logbacks JMXConfigurator mbean, search for
all available beans of the type. If a single one is found take that. If multiple are found
first choose the one with Name=application name, if not present take the one with Name=default.
In case none matches display an error.

closes #124
  • Loading branch information
joshiste committed Nov 17, 2015
1 parent 18f1281 commit f4b2c38
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 88 deletions.
139 changes: 72 additions & 67 deletions spring-boot-admin-server-ui/app/js/controller/apps/loggingCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,90 +15,95 @@
*/
'use strict';

module.exports = function ($scope, application, ApplicationLogging) {
module.exports = function ($scope, application) {
$scope.loggers = [];
$scope.filteredLoggers = [];
$scope.limit = 10;

var findLogger = function (loggers, name) {
for (var i in loggers) {
if (loggers[i].name === name) {
return loggers[i];
application.getLogging().then(function (logging) {
var findLogger = function (loggers, name) {
for (var i in loggers) {
if (loggers[i].name === name) {
return loggers[i];
}
}
}
};
};

$scope.setLogLevel = function (name, level) {
ApplicationLogging.setLoglevel(application, name, level)
.then(function () {
$scope.reload(name);
}, function (response) {
$scope.error = response;
$scope.reload(name);
});
};
$scope.setLogLevel = function (name, level) {
logging.setLoglevel(name, level)
.then(function () {
$scope.reload(name);
}, function (response) {
$scope.error = response;
$scope.reload(name);
});
};

$scope.reload = function (prefix) {
for (var i in $scope.loggers) {
if (prefix === null || prefix === 'ROOT' || $scope.loggers[i].name.indexOf(
prefix) === 0) {
$scope.loggers[i].level = null;
$scope.reload = function (prefix) {
for (var i in $scope.loggers) {
if (prefix === null || prefix === 'ROOT' || $scope.loggers[i].name.indexOf(
prefix) === 0) {
$scope.loggers[i].level = null;
}
}
}
$scope.refreshLevels();
};
$scope.refreshLevels();
};

$scope.refreshLevels = function () {
var toLoad = [];
var slice = $scope.filteredLoggers.slice(0, $scope.limit);
for (var i in slice) {
if (slice[i].level === null) {
toLoad.push(slice[i]);
$scope.refreshLevels = function () {
var toLoad = [];
var slice = $scope.filteredLoggers.slice(0, $scope.limit);
for (var i in slice) {
if (slice[i].level === null) {
toLoad.push(slice[i]);
}
}
}

if (toLoad.length === 0) {
return;
}
if (toLoad.length === 0) {
return;
}

ApplicationLogging.getLoglevel(application, toLoad)
.then(
function (responses) {
logging.getLoglevel(toLoad)
.then(
function (responses) {
for (var j in responses) {
var name = responses[j].request.arguments[0];
var level = responses[j].value;
findLogger($scope.loggers, name)
.level = level;
}
}, function (responses) {
for (var j in responses) {
var name = responses[j].request.arguments[0];
var level = responses[j].value;
findLogger($scope.loggers, name)
.level = level;
}
}, function (responses) {
for (var j in responses) {
if (responses[j].error !== null) {
$scope.error = responses[j];
break;
if (responses[j].error !== null) {
$scope.error = responses[j];
break;
}
}
});
};

logging.getAllLoggers()
.then(function (response) {
$scope.loggers = [];
for (var i in response.value) {
$scope.loggers.push({
name: response.value[i],
level: null
});
}
});
};

ApplicationLogging.getAllLoggers(application)
.then(function (response) {
$scope.loggers = [];
for (var i in response.value) {
$scope.loggers.push({
name: response.value[i],
level: null
$scope.$watchCollection('filteredLoggers', function () {
$scope.refreshLevels();
});
}

$scope.$watchCollection('filteredLoggers', function () {
$scope.refreshLevels();
});

$scope.$watch('limit', function () {
$scope.refreshLevels();
$scope.$watch('limit', function () {
$scope.refreshLevels();
});
}, function (response) {
$scope.error = response;
$scope.errorWhileListing = true;
});
}, function (response) {
$scope.error = response;
$scope.errorWhileListing = true;
});
}, function (response) {
$scope.error = response;
$scope.errorWhileListing = true;
});
};
6 changes: 5 additions & 1 deletion spring-boot-admin-server-ui/app/js/service/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
'use strict';

module.exports = function ($resource, $http, $q) {
module.exports = function ($resource, $http, $q, ApplicationLogging) {

var isEndpointPresent = function(endpoint, configprops) {
if (configprops[endpoint]) {
Expand Down Expand Up @@ -104,5 +104,9 @@ module.exports = function ($resource, $http, $q) {
return convert($http.get('api/applications/' + this.id + '/activiti'));
};

Application.prototype.getLogging = function() {
return ApplicationLogging.getLoggingConfigurator(this);
};

return Application;
};
71 changes: 51 additions & 20 deletions spring-boot-admin-server-ui/app/js/service/applicationLogging.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,61 @@
*/
'use strict';

module.exports = function ($http, jolokia) {
var LOGBACK_MBEAN =
'ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator';

this.getLoglevel = function (app, loggers) {
var requests = [];
for (var j in loggers) {
requests.push({
type: 'exec',
mbean: LOGBACK_MBEAN,
operation: 'getLoggerEffectiveLevel',
arguments: [loggers[j].name]
});
module.exports = function ($http, $q, jolokia) {
var findInArray = function (a, name) {
for (var i = 0; i < a.length; i++) {
var match = /ch.qos.logback.classic:Name=([^,]+)/.exec(a[i]);
if (match !== null && match[1].toUpperCase() === name.toUpperCase()) {
return a[i];
}
}
return jolokia.bulkRequest('api/applications/' + app.id + '/jolokia/', requests);
return null;
};

this.setLoglevel = function (app, logger, level) {
return jolokia.exec('api/applications/' + app.id + '/jolokia/', LOGBACK_MBEAN, 'setLoggerLevel', [logger,
level
]);
var findLogbackMbean = function (app) {
return jolokia.search('api/applications/' + app.id + '/jolokia/', 'ch.qos.logback.classic:Name=*,Type=ch.qos.logback.classic.jmx.JMXConfigurator').then(function (response) {
if (response.value.length === 1) {
return response.value[0];
}
if (response.value.length > 1) {
//find the one with the appname or default
var value = findInArray(response.value, app.name);
if (value === null) {
value = findInArray(response.value, 'default');
}
if (value !== null) {
return value;
}
return $q.reject({ error:'Ambigious Logback JMXConfigurator-MBeans found!', candidates: response.value});
}
return $q.reject({ error: 'Couldn\'t find Logback JMXConfigurator-MBean' });
});
};

this.getAllLoggers = function (app) {
return jolokia.readAttr('api/applications/' + app.id + '/jolokia/', LOGBACK_MBEAN, 'LoggerList');
this.getLoggingConfigurator = function (app) {
return findLogbackMbean(app).then(function (logbackMbean) {
return {
getLoglevel: function (loggers) {
var requests = [];
for (var j in loggers) {
requests.push({
type: 'exec',
mbean: logbackMbean,
operation: 'getLoggerEffectiveLevel',
arguments: [loggers[j].name]
});
}
return jolokia.bulkRequest('api/applications/' + app.id + '/jolokia/', requests);
},
setLoglevel: function (logger, level) {
return jolokia.exec('api/applications/' + app.id + '/jolokia/', logbackMbean, 'setLoggerLevel', [logger,
level
]);
},
getAllLoggers: function () {
return jolokia.readAttr('api/applications/' + app.id + '/jolokia/', logbackMbean, 'LoggerList');
}
};
});
};
};
7 changes: 7 additions & 0 deletions spring-boot-admin-server-ui/app/js/service/jolokia.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,11 @@ module.exports = function ($q) {
type: 'list'
});
};

this.search = function (url, mbean) {
return outer.request(url, {
type: 'search',
mbean: mbean
});
};
};

0 comments on commit f4b2c38

Please sign in to comment.