/*
* Copyright 2018 Anyware Services
*
* 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.
*/
/**
* A log tool displayed logs from a file.
* @private
*/
Ext.define('Ametys.plugins.coreui.log.ArchivedLogTool', {
extend: "Ametys.plugins.coreui.log.AbstractLogTool",
statics: {
/**
* @property {Number} DEFAULT_EVENTS_LIMIT The default max number of events to display
* @private
* @readonly
*/
DEFAULT_EVENTS_LIMIT: 1000
},
constructor: function(config)
{
this.callParent(arguments);
this._detailsTpl = new Ext.XTemplate(
"<tpl if='timestamp'><b>{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_TIMESTAMP_TEXT}}</b> {timestamp}<br /></tpl>",
"<tpl if='thread'><b>{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_THREAD_TEXT}}</b> {thread}<br /></tpl>",
"<tpl if='level'><b>{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_LEVEL_TEXT}}</b> {level}<br /></tpl>",
"<tpl if='category'><b>{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_CATEGORY_TEXT}}</b> {category}<br /></tpl>",
"<tpl if='message'><b>{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_MESSAGE_TEXT}}</b> {message}<br /></tpl>",
"<tpl if='callstack'><br /><b>{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_CALLSTACK_TEXT}}</b><br />{callstack}</tpl>"
);
},
getMBSelectionInteraction: function()
{
return Ametys.tool.Tool.MB_TYPE_ACTIVE;
},
sendCurrentSelection: function()
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.SELECTION_CHANGED,
targets: {
id: Ametys.message.MessageTarget.LOG_CATEGORY,
parameters: {
ids: ['root']
}
}
});
},
/**
* @inheritdoc
* @param {Object} params the parameters
* @param {String} params.path The path of the log file
* @param {String} [params.title=params.path] The title of the tool
* @param {String} [params.limit=1000] The limit of event to display
*/
setParams: function(params)
{
params.title = params.title || params.path;
params.limit = params.limit || Ametys.plugins.coreui.log.ArchivedLogTool.DEFAULT_EVENTS_LIMIT;
this.callParent(arguments);
this.setTitle(params.title);
if (this.getLimit() >= 0)
{
this.setDescription(Ext.String.format("{{i18n PLUGINS_CORE_UI_TOOLS_ARCHIVEDLOGS_DESCRIPTION_WITH_LIMIT}}", this.getLimit(), params.title));
}
else
{
this.setDescription(Ext.String.format("{{i18n PLUGINS_CORE_UI_TOOLS_ARCHIVEDLOGS_DESCRIPTION}}", params.title));
}
this.getStore().getProxy().setExtraParam('logFileName', params.path);
this.getStore().getProxy().setExtraParam('limit', this.getLimit());
this.showOutOfDate();
},
refresh: function()
{
this.showUpToDate();
this.getStore().load();
},
getStore: function()
{
if (!this._store)
{
this._store = Ext.create('Ext.data.Store', {
model: 'Ametys.plugins.coreui.log.archivedlogtool.ArchivedLogEntry',
remoteFilter: true,
proxy: {
type: 'ametys',
methodName: 'getLogLines',
methodArguments: ['logFileName', 'filter', 'limit'],
serverCaller: this,
reader: {
type: 'json',
rootProperty: 'lines'
}
},
listeners: {
'load': {fn: this._onLoad, scope: this}
}
});
}
return this._store;
},
getColumns: function()
{
return [{
stateId: 'grid-timestamp',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_TIMESTAMP_HEADER}}",
width: 130,
sortable: false,
dataIndex: 'timestamp',
renderer: Ext.bind(this.datetimeRenderer, this)
},
{
stateId: 'grid-thread',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_THREAD_HEADER}}",
width: 150,
sortable: false,
dataIndex: 'thread',
hidden: true,
renderer: Ext.bind(this.defaultRenderer, this),
filter: {
type: 'string'
}
},
{
stateId: 'grid-level',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_LEVEL_HEADER}}",
width: 75,
sortable: false,
dataIndex: 'level',
renderer: Ext.bind(this.defaultRenderer, this),
filter: {
type: 'list',
store: Ext.create('Ext.data.Store', {
fields: ['id','text'],
data: [
{id: "DEBUG", text: 'Debug'},
{id: "INFO", text: 'Info'},
{id: "WARN", text: 'Warn'},
{id: "ERROR", text: 'Error'},
{id: "FATAL", text: 'Fatal'}
]
})
}
},
{
stateId: 'grid-category',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_CATEGORY_HEADER}}",
width: 250,
flex: 0.25,
sortable: false,
dataIndex: 'category',
renderer: Ext.bind(this.defaultRenderer, this),
filter: {
type: 'string'
}
},
{
stateId: 'grid-message',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_MESSAGE_HEADER}}",
width: 400,
sortable: false,
dataIndex: 'message',
flex: 0.5,
renderer: Ext.bind(this.defaultRenderer, this),
filter: {
type: 'string'
}
},
{
stateId: 'grid-callstack',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_SERVERLOGS_CALLSTACK_HEADER}}",
width: 100,
sortable: false,
dataIndex: 'callstack',
hidden: true,
renderer: Ext.bind(this.defaultRenderer, this),
filter: {
type: 'string'
}
}];
},
getDetailsText: function(records)
{
var record = records[0];
var data = {
timestamp: Ext.Date.format(new Date(record.get("timestamp")), "d/m H:i:s.u"),
level: record.get('level'),
category: record.get('category'),
message: Ext.String.htmlEncode(record.get('message')),
thread: record.get('thread'),
callstack: record.get('callstack') ? Ext.String.stacktraceJavaToHTML(record.get('callstack')) : null
};
return this._detailsTpl.applyTemplate(data);
},
getDockedItems: function()
{
return [{
dock: 'top',
xtype: 'component',
hidden: true,
itemId: 'moreitems-hint',
layout: 'fit',
cls: 'x-component-tool-hintmessage',
html: Ext.String.format("{{i18n PLUGINS_CORE_UI_TOOLS_ARCHIVEDLOGS_OVER_HINT}}", this.getLimit())
}];
},
getRowClass: function(record)
{
return "msg-level-" + record.get('levelCode');
},
/**
* Default renderer for the columns. Apply the coloration.
* @param {Number} value The level
* @param {Object} metadata A collection of metadata about the current cell; can be used or modified by the renderer. Recognized properties are: tdCls, tdAttr, and style
* @param {Ext.data.Model} record The record for the current row
* @private
*/
defaultRenderer: function(value, metadata, record)
{
return Ext.String.htmlEncode(value);
},
/**
* Datetime renderer for the columns. Format the timestamp into a human readable time.
* @param {Number} value The level
* @param {Object} metadata A collection of metadata about the current cell; can be used or modified by the renderer. Recognized properties are: tdCls, tdAttr, and style
* @param {Ext.data.Model} record The record for the current row
* @private
*/
datetimeRenderer: function(value, metadata, record)
{
return Ext.Date.format(new Date(value), "d/m H:i:s.u");
},
/**
* Function called after loading results
* @param {Ext.data.Store} store The store
* @param {Ext.data.Model[]} records An array of records
* @param {Boolean} successful True if the operation was successful.
* @private
*/
_onLoad: function (store, records, successful)
{
var hint = this.grid.getDockedItems("#moreitems-hint")[0];
if (hint)
{
var limit = this.getLimit();
if (limit >= 0 && records.length >= limit)
{
hint.update(Ext.String.format("{{i18n PLUGINS_CORE_UI_TOOLS_ARCHIVEDLOGS_OVER_HINT}}", this.getLimit()));
hint.show();
}
else
{
hint.hide();
}
}
},
/**
* Function to get the limit of displayed events
* @private
*/
getLimit: function ()
{
return this.getParams().limit;
}
});