diff --git a/solr/webapp/web/css/styles/logging.css b/solr/webapp/web/css/styles/logging.css index a1eef10d608..40e0bc36730 100644 --- a/solr/webapp/web/css/styles/logging.css +++ b/solr/webapp/web/css/styles/logging.css @@ -1,3 +1,17 @@ +#content #logging #navigation +{ + width: 8%; +} + +#content #logging #navigation .viewer a { background-image: url( ../../img/ico/document-text.png ); } +#content #logging #navigation .level a { background-image: url( ../../img/ico/gear.png ); } + +#content #logging #frame +{ + float: right; + width: 90%; +} + #content #logging .loader { background-position: 0 50%; @@ -17,6 +31,120 @@ margin-left: 10px; } +#content #logging #viewer +{ + position: relative; +} + +#content #logging #viewer #state +{ + background-position: 0 50%; + color: #c0c0c0; + margin-top: 20px; + padding-left: 21px; +} + +#content #logging #viewer table +{ + border-collapse: collapse; + width: 100%; +} + +#content #logging #viewer th, +#content #logging #viewer td a, +#content #logging #viewer tbody .trace td +{ + padding: 3px 10px; +} + +#content #logging #viewer td +{ + vertical-align: top; +} + +#content #logging #viewer td a +{ + display: block; +} + +#content #logging #viewer thead th +{ + font-weight: bold; + text-align: left; +} + +#content #logging #viewer tbody td, +#content #logging #viewer tfoot td +{ + border-top: 1px solid #f0f0f0; +} + +#content #logging #viewer thead th.message +{ + width:100%; +} + +#content #logging #viewer tbody td.span a +{ + padding-left: 0; + padding-right: 0; +} + +#content #logging #viewer tbody span +{ + display: block; + padding-left: 10px; + padding-right: 10px; +} + +#content #logging #viewer tbody .level-info .level span { background-color: #ebf5eb; } +#content #logging #viewer tbody .level-warning span { background-color: #d5dd00; } +#content #logging #viewer tbody .level-severe span { background-color: #c43c35; color: #fff; } + +#content #logging #viewer tbody .has-trace a +{ + cursor: pointer; +} + +#content #logging #viewer tbody .has-trace a:hover +{ + color: #008; +} + +#content #logging #viewer tbody .has-trace .message a +{ + background-image: url( ../../img/ico/information.png ); + background-position: 100% 50%; + display: block; + padding-right: 21px; +} + +#content #logging #viewer tbody .has-trace.open .message a +{ + background-image: url( ../../img/ico/information-white.png ); +} + +#content #logging #viewer tbody .trace +{ + display: none; +} + +#content #logging #viewer tbody .trace td +{ + border-top: 0; + color: #c0c0c0; +} + +#content #logging #viewer .has-data tfoot +{ + display: none; +} + +#content #logging #viewer tfoot td +{ + color: #c0c0c0; +} + #content #logging .jstree > li { margin-left: 0; diff --git a/solr/webapp/web/js/scripts/app.js b/solr/webapp/web/js/scripts/app.js index 0920f85ecf6..00f3b9a97ca 100644 --- a/solr/webapp/web/js/scripts/app.js +++ b/solr/webapp/web/js/scripts/app.js @@ -82,6 +82,12 @@ var sammy = $.sammy {}, function( context ) { + if( app.timeout ) + { + console.debug( 'Clearing Timeout #' + app.timeout ); + clearTimeout( app.timeout ); + } + var menu_wrapper = $( '#menu-wrapper' ); $( 'li[id].active', menu_wrapper ) @@ -140,6 +146,8 @@ var solr_admin = function( app_config ) this.menu_element = $( '#menu-selector' ); this.config = config; + this.timeout = null; + this.run = function() { $.ajax diff --git a/solr/webapp/web/js/scripts/logging.js b/solr/webapp/web/js/scripts/logging.js index ac3419341ae..6fbb93cb350 100644 --- a/solr/webapp/web/js/scripts/logging.js +++ b/solr/webapp/web/js/scripts/logging.js @@ -16,6 +16,8 @@ */ var loglevel_path = null; +var frame_element = null; + var logging_handler = function( response, text_status, xhr ) { var self = this; @@ -248,6 +250,136 @@ var logging_handler = function( response, text_status, xhr ) }; +var format_time = function( time ) +{ + time = time ? new Date( time ) : new Date(); + return '' + time.toTimeString().split( ' ' ).shift().esc() + ''; +} + +var load_logging_viewer = function() +{ + var table = $( 'table', frame_element ); + var state = $( '#state', frame_element ); + var since = table.data( 'latest' ) || 0; + var sticky_mode = null; + + $.ajax + ( + { + url : loglevel_path + '?wt=json&since=' + since, + dataType : 'json', + beforeSend : function( xhr, settings ) + { + // initial request + if( 0 === since ) + { + sticky_mode = true; + } + + // state element is in viewport + else if( state.position().top <= $( window ).scrollTop() + $( window ).height() - ( $( 'body' ).height() - state.position().top ) ) + { + sticky_mode = true; + } + + else + { + sticky_mode = false; + } + }, + success : function( response, text_status, xhr ) + { + var docs = response.history.docs; + var docs_count = docs.length; + + var table = $( 'table', frame_element ); + + $( 'h2 span', frame_element ) + .text( response.watcher.esc() ); + + state + .html( 'Last Check: ' + format_time() ); + + app.timeout = setTimeout + ( + load_logging_viewer, + 10000 + ); + + if( 0 === docs_count ) + { + table.trigger( 'update' ); + return false; + } + + var content = ''; + + for( var i = 0; i < docs_count; i++ ) + { + var doc = docs[i]; + var has_trace = 'undefined' !== typeof( doc.trace ); + + doc.logger = '' + doc.logger.split( '.' ).pop().esc() + ''; + + var classes = [ 'level-' + doc.level.toLowerCase().esc() ]; + if( has_trace ) + { + classes.push( 'has-trace' ); + } + + content += '' + "\n"; + content += '' + format_time( doc.time ) + '' + "\n"; + content += '' + doc.level.esc() + '' + "\n"; + content += '' + doc.logger + '' + "\n"; + content += '' + doc.message.replace( /,/g, ',​' ).esc() + '' + "\n"; + content += '' + "\n"; + + if( has_trace ) + { + content += '' + "\n"; + + // (1) with colspan + content += '
' + doc.trace.esc() + '
' + "\n"; + + // (2) without colspan + //content += '   '; + //content += '' + doc.trace.esc().replace( /\n/g, '
' ) + '' + "\n"; + + content += '' + "\n"; + } + + } + + content += ''; + + $( 'table', frame_element ) + .append( content ); + + table + .data( 'latest', response.info.last ) + .removeClass( 'has-data' ) + .trigger( 'update' ); + + if( sticky_mode ) + { + $( 'body' ) + .animate + ( + { scrollTop: state.position().top }, + 1000 + ); + } + }, + error : function( xhr, text_status, error_thrown) + { + }, + complete : function( xhr, text_status ) + { + } + } + ); +} + // #/~logging sammy.get ( @@ -257,22 +389,121 @@ sammy.get var core_basepath = $( 'li[data-basepath]', app.menu_element ).attr( 'data-basepath' ); loglevel_path = core_basepath + '/admin/logging'; var content_element = $( '#content' ); - - content_element - .html( '
' ); - $.ajax + $.get ( + 'tpl/logging.html', + function( template ) { - url : loglevel_path + '?wt=json', - dataType : 'json', - context : $( '#logging', content_element ), - beforeSend : function( xhr, settings ) - { - this - .html( '
Loading ...
' ); - }, - success : logging_handler + content_element + .html( template ); + + $( '#navigation a[href="' + context.path + '"]', content_element ) + .parent().addClass( 'current' ); + + frame_element = $( '#frame', content_element ); + frame_element + .html + ( + '
' + "\n" + + '
' + "\n" + + '

 

' + "\n" + + '
' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '' + "\n" + + '
TimeLevelLoggerMessage
No Events available
' + "\n" + + '
 
' + "\n" + + '
' + ); + + var table = $( 'table', frame_element ); + + table + .die( 'update' ) + .live + ( + 'update', + function( event ) + { + var table = $( this ); + var tbody = $( 'tbody', table ); + + 0 !== tbody.size() + ? table.addClass( 'has-data' ) + : table.removeClass( 'has-data' ); + + return false; + } + ); + + load_logging_viewer(); + + $( '.has-trace a', table ) + .die( 'click' ) + .live + ( + 'click', + function( event ) + { + $( this ).closest( 'tr' ) + .toggleClass( 'open' ) + .next().toggle(); + + return false; + } + ); + } + ); + } +); + +// #/~logging/level +sammy.get +( + /^#\/~(logging)\/level$/, + function( context ) + { + var core_basepath = $( 'li[data-basepath]', app.menu_element ).attr( 'data-basepath' ); + loglevel_path = core_basepath + '/admin/logging'; + var content_element = $( '#content' ); + + $.get + ( + 'tpl/logging.html', + function( template ) + { + content_element + .html( template ); + + $( '#navigation a[href="' + context.path + '"]', content_element ) + .parent().addClass( 'current' ); + + $.ajax + ( + { + url : loglevel_path + '?wt=json', + dataType : 'json', + context : $( '#frame', content_element ), + beforeSend : function( xhr, settings ) + { + this + .html( '
Loading ...
' ); + }, + success : logging_handler + } + ); } ); } diff --git a/solr/webapp/web/tpl/logging.html b/solr/webapp/web/tpl/logging.html new file mode 100644 index 00000000000..494d622e3a5 --- /dev/null +++ b/solr/webapp/web/tpl/logging.html @@ -0,0 +1,32 @@ + +
+ +
+ +
+ + + +