blob: 3a47b92614aa07f71816c4e8b3c08b262a63fe49 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
define([
"app",
"api",
"backbone"
],
function (app, FauxtonAPI, Backbone) {
var Log = FauxtonAPI.addon();
Log.Model = Backbone.Model.extend({
date: function () {
var date = new Date(this.get('date'));
var formatted_time = date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
var formatted_date = date.toDateString().slice(4, 10);
return formatted_date + ' ' + formatted_time;
},
logLevel: function () {
return this.get('log_level').replace(/ /g,'');
},
pid: function () {
return _.escape(this.get('pid'));
},
args: function () {
return _.escape(this.get('args'));
}
});
Log.Collection = Backbone.Collection.extend({
model: Log.Model,
initialize: function (options) {
this.params = {bytes: 5000};
},
documentation: "log",
url: function () {
query = "?" + $.param(this.params);
return app.host + '/_log' + query;
},
// override fetch because backbone expects json and couchdb sends text/html for logs,
// I think its more elegant to set the dataType here than where ever fetch is called
fetch: function (options) {
options = options ? options : {};
return Backbone.Collection.prototype.fetch.call(this, _.extend(options, {dataType: "html"}));
},
parse: function (resp) {
var lines = resp.split(/\n/);
return _.foldr(lines, function (acc, logLine) {
var match = logLine.match(/^\[(.*?)\]\s\[(.*?)\]\s\[(.*?)\]\s(.*)/);
if (!match) { return acc;}
acc.push({
date: match[1],
log_level: match[2],
pid: match[3],
args: match[4]
});
return acc;
}, []);
}
});
Log.events = {};
_.extend(Log.events, Backbone.Events);
Log.Views.View = FauxtonAPI.View.extend({
template: "addons/logs/templates/dashboard",
initialize: function (options) {
this.refreshTime = options.refreshTime || 5000;
Log.events.on("log:filter", this.filterLogs, this);
Log.events.on("log:remove", this.removeFilterLogs, this);
this.filters = [];
this.collection.on("add", function () {
this.render();
}, this);
},
establish: function () {
return [this.collection.fetch()];
},
serialize: function () {
return { logs: new Log.Collection(this.createFilteredCollection())};
},
afterRender: function () {
this.startRefreshInterval();
},
cleanup: function () {
this.stopRefreshInterval();
},
filterLogs: function (filter) {
this.filters.push(filter);
this.render();
},
createFilteredCollection: function () {
var that = this;
return _.reduce(this.filters, function (logs, filter) {
return _.filter(logs, function (log) {
var match = false;
_.each(log, function (value) {
if (value.toString().match(new RegExp(filter))) {
match = true;
}
});
return match;
});
}, this.collection.toJSON(), this);
},
removeFilterLogs: function (filter) {
this.filters.splice(this.filters.indexOf(filter), 1);
this.render();
},
startRefreshInterval: function () {
var collection = this.collection;
// Interval already set
if (this.intervalId) { return ; }
this.intervalId = setInterval(function () {
collection.fetch();
}, this.refreshTime);
},
stopRefreshInterval: function () {
clearInterval(this.intervalId);
}
});
Log.Views.FilterView = FauxtonAPI.View.extend({
template: "addons/logs/templates/sidebar",
events: {
"submit #log-filter-form": "filterLogs"
},
filterLogs: function (event) {
event.preventDefault();
var $filter = this.$('input[name="filter"]'),
filter = $filter.val();
Log.events.trigger("log:filter", filter);
this.insertView("#filter-list", new Log.Views.FilterItemView({
filter: filter
})).render();
$filter.val('');
}
});
Log.Views.FilterItemView = FauxtonAPI.View.extend({
template: "addons/logs/templates/filterItem",
tagName: "li",
initialize: function (options) {
this.filter = options.filter;
},
events: {
"click .remove-filter": "removeFilter"
},
serialize: function () {
return {
filter: this.filter
};
},
removeFilter: function (event) {
event.preventDefault();
Log.events.trigger("log:remove", this.filter);
this.remove();
}
});
return Log;
});