[img_assist | nid = 40327 | title = | desc = | link = none | align = left | width = 100 | height = 29]
Log4Play — это игра! Модуль Framework, предоставляющий приложение
log4j, которое публикует записи журнала в EventStream. Теоретически вы можете использовать его из любого Java-приложения, которое использует log4j, но я протестировал его только с Play! Рамочное приложение.
Log4Play предоставляет пользовательский интерфейс, который использует WebSocket для создания живого потока сообщений журнала. Пользовательский интерфейс позволяет вам
отслеживать журналы вашего приложения без необходимости входа в реальный ящик . Я работал над этим с
Deepthi Rallabandiс кем я работаю над проектом Accenture; Я только что представил ее, чтобы Играть! Было приятно удивиться тому, как быстро она прогрессирует, что еще раз подтверждает,
насколько продуктивна игра! есть . В один прекрасный день она перешла от того, чтобы ничего не знать о WebSockets и не так уж много опыта в Web, к полноценному приложению на основе WebSockets с Play !. Она использовала мою
предыдущую статью о WebSockets, чтобы провести ее через этот процесс. Итак, позвольте мне перейти к реализации.
Сначала мы создали приложение Log4J.
public class PlayWebSocketLogAppender extends WriterAppender implements Appender {
/**
* Publish log event to WebSocket Stream
*
* @see org.apache.log4j.WriterAppender#append(org.apache.log4j.spi.LoggingEvent)
*/
@Override
public void append(LoggingEvent event) {
LogStream.publish(new Log4PlayEvent(event));
}
}
Затем мы создали плагин для автоматического добавления appender в log4j, поэтому вам не нужно изменять конфигурацию log4j. PlayPlugin позволяет вам настроить поведение фреймворка, я настоятельно рекомендую вам просмотреть исходный код.
public class Log4PlayPlugin extends PlayPlugin {
/**
* On application start.
*/
@Override
public void onApplicationStart() {
// Add appender that will stream log messages as Log4PlayEvent instances
// through WebSocket (Log4Play.WebSocket.stream)
PlayWebSocketLogAppender appender = new PlayWebSocketLogAppender();
Logger.log4j.addAppender(appender);
// Add routes for the UI
Router.addRoute("GET", "/@logs", "Log4Play.index");
Router.addRoute("WS", "/@logs/stream", "Log4Play.WebSocket.stream");
}
}
Затем мы создали поток событий, который будет получать сообщения журнала от appender.
public abstract class LogStream {
/** The stream. */
public static final ArchivedEventStream<log4playevent> stream = new ArchivedEventStream<log4playevent>(50);
/**
* Gets the stream.
*
* @return the stream
*/
public static EventStream<log4playevent> getStream() {
return stream.eventStream();
}
/**
* Publish.
*
* @param event
* the event
*/
public static void publish(Log4PlayEvent event) {
stream.publish(event);
}
}
Обратите внимание на то, как мы используем
ArchivedEventStream, который мы можем использовать для отображения x номеров сообщений, как только пользователь загрузит пользовательский интерфейс, вместо того, чтобы видеть пустую страницу, на которой затем будут отображаться сообщения журнала по мере их появления с этого момента. В этом главное отличие
ArchivedEventStream от
EventStream, которое я использовал в своей первой статье о
WebSockets — WebSockets с Play Framework 1.2 в действии! ,
Затем мы определили WebSocketController, который прослушивает сообщения, сброшенные в потоке событий, и передает их клиенту.
public class Log4Play extends Controller {
/**
* Index.
*/
public static void index() {
render();
}
/**
* The Class WebSocket.
*/
public static class WebSocket extends WebSocketController {
/**
* Index.
*/
public static void index() {
EventStream<play.modules.log4play.log4playevent> loggingStream = play.modules.log4play.LogStream.getStream();
while (inbound.isOpen()) {
try {
Promise<play.modules.log4play.log4playevent> promise = loggingStream.nextEvent();
play.modules.log4play.Log4PlayEvent event = await(promise);
outbound.sendJson(event);
} catch (Throwable t) {
Logger.error(play.modules.log4play.ExceptionUtil.getStackTrace(t));
}
}
}
}
}
Разница между этой реализацией и реализацией из моей предыдущей статьи заключается в том, что в этом случае объект JSON отправляется в представление вместо простой строки.
Затем на стороне просмотра мы использовали Knockout.js .
// Define Knockout.js Observable
var viewModel = {};
viewModel.details = ko.observable();
ko.applyBindings(viewModel);
viewModel.details("Log Events will start showing up here...");
// Create a socket
var socket = new WebSocket('@@{Log4Play.WebSocket.index()}');
// Display a message
var data = "";
var display = function(json) {
var event = JSON.parse(json);
if ( event != null && json != null ) {
var checkLevel = document.getElementById("log4play_level_" + event.level);
if ( checkLevel != null && checkLevel.checked == true ) {
var item = event.level + ' - ' + event.category + ' - ' + event.date + ' - ' + event.message;
data = item + data;
viewModel.details(data);
}
}
}
// Message received on the socket
socket.onmessage = function(event) {
display(event.data);
}
Установка
Под
зависимостями.yml :
require: – play → log4play 0.0.1
По
маршрутам :
WS /logstream Log4Play.WebSocket.index GET /@logs Log4Play.index GET /public_log4play/ staticDir:public_log4play
Демонстрация в режиме
реального времени Демонстрация в режиме реального времени доступна по адресу
http://log4play.mashup.fm:9030/@logs . Как только вы включите модуль в своем приложении, вы должны иметь такой же доступный интерфейс в / @ logs.
Исходный код
Исходный код доступен на Github по адресу
https://github.com/feliperazeek/log4play .
Статья изначально размещена по адресу
http://geeks.aretotally.in/log4play-log4j-ui-mashed-up-with-play-framework-knockout-js-and-websockets .