/*
* Copyright 2015 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.
*/
/**
* This tool does display the logs of Ametys.log.Logger.
* @private
*/
Ext.define("Ametys.plugins.coreui.system.consolelog.ConsoleLogTool",
{
extend: "Ametys.plugins.coreui.log.AbstractLogTool",
statics: {
/**
* This action find the unique instance of the log tool, and removes all the entries
*/
removeAll: function()
{
Ametys.log.LoggerFactory.getStore().removeAll();
},
/**
* Get the root log level to toggle the controller
* @param {Ametys.ribbon.element.RibbonUIController} controller The controller of this log level
*/
getRootLogLevel: function(controller)
{
var level = parseInt(controller.getInitialConfig("log-level"));
controller.toggle(Ametys.log.LoggerFactory.getLoggerFor('').getLogLevel() == level);
},
/**
* Change the main log level defined in configuration "log-level"
* @param {Ametys.ribbon.element.RibbonUIController} controller The controller of this log level
* @param {Boolean} state The controller state
*/
setRootLogLevel: function(controller, state)
{
var idsToUntoggle = controller.getInitialConfig("untoggle").split(",");
Ext.Array.each(idsToUntoggle, function(id) {
Ametys.ribbon.RibbonManager.getUI(id).toggle(false);
});
controller.toggle(true);
var level = parseInt(controller.getInitialConfig("log-level"));
Ametys.log.LoggerFactory.getLoggerFor('').setLogLevel(level);
},
/**
* @private
* @property {Function} _dateRenderer The internal real date renderer
*/
_dateRenderer: Ext.util.Format.dateRenderer(Ext.Date.patterns.ShortDateTime),
/**
* @private
* Renderer for the date with color
* @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
*/
dateRenderer: function(value, metadata, record)
{
return Ametys.plugins.coreui.system.consolelog.ConsoleLogTool._dateRenderer.apply(Ametys.plugins.coreui.system.consolelog.ConsoleLogTool, arguments);
},
/**
* @private
* Renderer for the stacktrace with color
* @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
*/
stacktraceRendered: function(value, metadata, record)
{
return Ext.String.stacktraceToHTML(value, 1);
}
},
constructor: function(config)
{
this.callParent(arguments);
this._detailsTpl = new Ext.XTemplate(
"<tpl if='date'><b>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_DATE_TEXT}}</b> {date}<br /></tpl>",
"<tpl if='level'><b>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_LEVEL_TEXT}}</b> {level}<br /></tpl>",
"<tpl if='category'><b>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_CATEGORY_TEXT}}</b> {category}<br /></tpl>",
"<tpl if='message'><b>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_MESSAGE_TEXT}}</b> {message}<br /></tpl>",
"<tpl if='details'><br /><b>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_DETAILS_TEXT}}</b><br />{details}</tpl>",
"<tpl if='stacktrace'><br />",
"<div class=\"json-array json-closed\">",
"<span class=\"json-char\" onclick=\"Ametys.tool.ToolsManager.getTool('" + this.getId() + "').openTrace(this)\"></span> ",
"<b>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_STACKTRACE_TEXT}}</b><br/>",
"</div></tpl>"
);
},
getRowClass: function(record)
{
return "msg-level-" + record.get('level');
},
/**
* Renderer for the level column
* @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
* @private
*/
levelRenderer: function(value, metadata)
{
var imgSrc = Ametys.CONTEXT_PATH + this.getInitialConfig("icon-level-" + value);
switch (value)
{
case Ametys.log.Logger.Entry.LEVEL_DEBUG: return "<img src=\"" + imgSrc + "\"/>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_LEVEL_0}}";
case Ametys.log.Logger.Entry.LEVEL_INFO: return "<img src=\"" + imgSrc + "\"/>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_LEVEL_1}}";
case Ametys.log.Logger.Entry.LEVEL_WARN: return "<img src=\"" + imgSrc + "\"/>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_LEVEL_2}}";
case Ametys.log.Logger.Entry.LEVEL_ERROR: return "<img src=\"" + imgSrc + "\"/>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_LEVEL_3}}";
default:
case Ametys.log.Logger.Entry.LEVEL_FATAL: return "<img src=\"" + imgSrc + "\"/>{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_LEVEL_4}}";
}
},
getStore: function()
{
return Ametys.log.LoggerFactory.getStore();
},
getColumns: function()
{
return [
{
stateId: 'grid-date',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_DATE}}",
width: 120,
sortable: true,
renderer: Ametys.plugins.coreui.system.consolelog.ConsoleLogTool.dateRenderer,
dataIndex: 'date'
},
{
stateId: 'grid-level',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_LEVEL}}",
width: 80,
sortable: true,
renderer: Ext.bind(this.levelRenderer, this),
dataIndex: 'level',
hideable: false,
filter: {
type: 'list',
store: Ext.create('Ext.data.Store', {
fields: ['id','text'],
data: [
{id: 0, text: 'Debug'},
{id: 1, text: 'Info'},
{id: 2, text: 'Warn'},
{id: 3, text: 'Error'},
{id: 4, text: 'Fatal'}
]
})
}
},
{
stateId: 'grid-category',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_CATEGORY}}",
width: 200,
sortable: true,
dataIndex: 'category',
filter: {
type: 'string'
}
},
{
stateId: 'grid-message',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_MESSAGE}}",
flex: 0.5,
sortable: true,
dataIndex: 'message',
hideable: false,
filter: {
type: 'string'
}
},
{
stateId: 'grid-details',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_DETAILS}}",
flex: 1,
sortable: true,
dataIndex: 'details',
hidden: true,
filter: {
type: 'string'
}
},
{
stateId: 'grid-stacktrace',
header: "{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_COL_STACKTRACE}}",
flex: 1,
hidden: true,
renderer: Ametys.plugins.coreui.system.consolelog.ConsoleLogTool.stacktraceRendered,
dataIndex: 'stacktrace',
filter: {
type: 'string'
}
}
];
},
getDetailsText: function(records)
{
var record = records[0];
var data = {
date: Ext.Date.format(record.get("date"), Ext.Date.patterns.ShortDateTime),
level: record.get("level"),
category: record.get("category"),
message: record.get("message"),
details: record.get("details"),
stacktrace: Ext.String.stacktraceToHTML(record.get("stacktrace"))
};
return this._detailsTpl.applyTemplate(data);
},
getType: function()
{
return Ametys.tool.Tool.TYPE_DEVELOPER;
},
/**
* Load and display the stacktrace of the currently selected message
* @param {Object} span The dom element that triggered the open trace
*/
openTrace: function (span)
{
var parent = Ext.get(span.parentNode);
if (!parent.hasCls('json-closed'))
{
return;
}
parent.removeCls('json-closed');
parent.removeCls('json-array');
var records = this.grid.getSelectionModel().getSelection();
if (records.length > 0)
{
parent.child('b').setHtml("{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_STACKTRACE_TEXT_LOADING}}");
var record = records[0];
var callstack = record.get("stacktrace");
console.info(callstack);
var div = document.createElement('div');
Ext.get(div).setHtml(Ext.String.stacktraceToHTML(callstack));
parent.appendChild(div);
Ametys.plugins.coreui.system.devmode.StacktraceHelper.unminifyStacktrace(callstack, Ext.bind(this._openTraceCb, this, [callstack, parent], true));
}
},
/**
* Callback after unminifying the stacktrace
* @param {String} response The unminified callstack, or null
* @param {String} originalCallstack The callstack before processing
* @param {Ext.dom.Element} domElement The element that displays the stacktrace
*/
_openTraceCb: function (response, originalCallstack, domElement)
{
domElement.child('b').setHtml("{{i18n PLUGINS_CORE_UI_TOOLS_CONSOLELOGTOOL_STACKTRACE_TEXT}}");
if (response)
{
domElement.child('div').setHtml(Ext.String.stacktraceToHTML(response));
}
}
}
);