Exception managing with LSim Catch them all
La LSim Library permet, si es vol, informar de les excepcions i altres missatges de logging que es produeixin durant l’execució d’un experiment.
D’aquesta manera, incorpora els mètodes lsim.log(message)
i lsim.logException(LSimExceptionMessage)
.
A continuació veurem com utilitzar el mètode lsim.logException(LSimExceptionMessage)
.
ExceptionManager
Primer de tot cal tenir una implementació de la interfície ExceptionManager
.
package dispatcher.application;
import edu.uoc.dpcs.lsim.exceptions.LSimExceptionMessage;
/**
* Interface for Exception Managers
*
* @author Manel
*
*/
public interface ExceptionManager {
/**
* This method will be called when sendException is called by an LSim
* component. Some implementation examples can be found on lsim-logging
* project
*
* @param object
*/
public void sendException(String id, LSimExceptionMessage exceptionMsg);
}
LSim proporciona dues implementacions que es poden utilitzar si es desitja.
DummyExceptionManager
que escriu al log local els missatges que rep.RemoteExceptionManager
que envia a un servidor determinat la excepció. La implementació d’aquest servidor (RemoteMessageManagerMain
) també està disponible al jarlsim-logging
.
Implementació del RemoteExceptionManager
:
package lsim.exceptions.remote;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import dispatcher.application.ExceptionManager;
import edu.uoc.connectorLayer.sender.Sender;
import edu.uoc.dpcs.lsim.exceptions.LSimExceptionMessage;
public class RemoteExceptionManager implements ExceptionManager {
private Logger logger = LoggerFactory.getLogger(RemoteExceptionManager.class);
private String host;
private String port;
public RemoteExceptionManager() {
}
@Override
public void sendException(String id, LSimExceptionMessage exceptionMsg) {
logger.info("Somebody wants to send an exception: " + exceptionMsg);
Sender send = new Sender(null);
try {
send.sendMessage(exceptionMsg, Sender.Mode.CLOSE_AFTER, host, Integer.parseInt(port));
} catch (Exception e) {
logger.error("Error sending exception: " + e.getMessage());
}
}
public void setHost(String host) {
this.host = host;
}
public void setPort(String port) {
this.port = port;
}
}
Instruccions per utilitzar el servidor RemoteMessageManager
Hem preparat un zip amb tot el necessari per executar el servidor. Descarrega’l i descomprimeix-lo.
El funcionament del servidor es pot definir modificant el fitxer config.properties que conté el zip. En aquest fitxer hi ha dues propietats:
-
port: per indicar el port on escoltarà el servidor.
-
handler per indicar la classe que rebrà els missatges. Hi ha definida la classe
lsim.exceptions.remote.ConsoleMessageHandler
que escriu al log els missatges que rep.
Especificació de l’experiment
Cal indicar a l’especficació en xml de l’experiment quin ExceptionManager
farem servir. A continuacíó tenim un exemple de com definir el RemoteExceptionManager
que hem vist. A l’apartat ExceptionManager definim la classe que implementa l’ExceptionManager
i les propietats d’aquest.
?xml version="1.0" encoding="UTF-8" ?>
<Specification>
<experimentId>test-app</experimentId>
<Coordinators>
<num>1</num>
<codeRef>lsim.LSimDispatcherHandler::http://localhost:8080/lsim-frontend/experiments/files/manel/testapp.zip$testapp.zip/coordinator::coordinator.sh
</codeRef>
<timeInit>5</timeInit>
<timeEval>1</timeEval>
<param>2</param>
</Coordinators>
<ExceptionManager>
<class>lsim.exceptions.remote.RemoteExceptionManager</class>
<properties>
<property name="host">localhost</property>
<property name="port">9989</property>
</properties>
</ExceptionManager>
<Evaluators>
<Evaluator>
<codeRef>lsim.LSimDispatcherHandler::http://localhost:8080/lsim-frontend/experiments/files/manel/testapp.zip$testapp.zip/partial_evaluator::partial_evaluator.sh
...
</Evaluators>
<Workers>
...
</Workers>
</Specification>
Crides a la llibreria
Finalment, només cal fer les crides al mètode logException(LSimExceptionMessage)
de la llibreria per tal d’informar de les excepcions:
...
try {
for (int i = 0; i < n; i++) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
int valueFromApp = Integer.parseInt(inFromClient.readLine().trim());
total += valueFromApp;
lsim.sendResult("checkServer", new ResultHandler(valueFromApp));
}
System.out.println("Total: " + total);
welcomeSocket.close();
} catch (IOException e) {
lsim.logException(new LSimExceptionMessage("IO exception reading socket", e, null));
e.printStackTrace();
}
...