1
0
mirror of https://github.com/essentials/Essentials.git synced 2025-08-16 03:24:31 +02:00

Prevent loops generated by logging directly to xmpp

This commit is contained in:
snowleo
2011-07-07 18:54:25 +02:00
parent a4be55f68a
commit 63ade8339b

View File

@@ -7,8 +7,10 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.logging.Handler; import java.util.logging.Handler;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.LogRecord; import java.util.logging.LogRecord;
@@ -35,10 +37,13 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
private transient XMPPConnection connection; private transient XMPPConnection connection;
private transient ChatManager chatManager; private transient ChatManager chatManager;
private final transient Map<String, Chat> chats = Collections.synchronizedMap(new HashMap<String, Chat>()); private final transient Map<String, Chat> chats = Collections.synchronizedMap(new HashMap<String, Chat>());
private final transient Set<LogRecord> logrecords = Collections.synchronizedSet(new HashSet<LogRecord>());
private final transient JavaPlugin parent; private final transient JavaPlugin parent;
private transient List<String> logUsers; private transient List<String> logUsers;
private transient Level logLevel; private transient Level logLevel;
private transient boolean ignoreLagMessages = true; private transient boolean ignoreLagMessages = true;
private transient Thread loggerThread;
private transient boolean threadrunning = true;
public XMPPManager(final JavaPlugin parent) public XMPPManager(final JavaPlugin parent)
{ {
@@ -49,17 +54,22 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
reloadConfig(); reloadConfig();
} }
public void sendMessage(final String address, final String message) public boolean sendMessage(final String address, final String message)
{ {
if (address != null && !address.isEmpty()) if (address != null && !address.isEmpty())
{ {
try try
{ {
startChat(address); startChat(address);
final Chat chat = chats.get(address); final Chat chat;
synchronized (chats)
{
chat = chats.get(address);
}
if (chat != null) if (chat != null)
{ {
chat.sendMessage(message.replaceAll("§[0-9a-f]", "")); chat.sendMessage(message.replaceAll("§[0-9a-f]", ""));
return true;
} }
} }
catch (XMPPException ex) catch (XMPPException ex)
@@ -67,6 +77,7 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
disableChat(address); disableChat(address);
} }
} }
return false;
} }
@Override @Override
@@ -91,13 +102,13 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
} }
} }
private void connect() private boolean connect()
{ {
final String server = config.getString("xmpp.server"); final String server = config.getString("xmpp.server");
if (server == null || server.equals("example.com")) if (server == null || server.equals("example.com"))
{ {
LOGGER.log(Level.WARNING, "config broken for xmpp"); LOGGER.log(Level.WARNING, "config broken for xmpp");
return; return false;
} }
final int port = config.getInt("xmpp.port", 5222); final int port = config.getInt("xmpp.port", 5222);
final String serviceName = config.getString("xmpp.servicename", server); final String serviceName = config.getString("xmpp.servicename", server);
@@ -119,19 +130,31 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
connection.getRoster().setSubscriptionMode(SubscriptionMode.accept_all); connection.getRoster().setSubscriptionMode(SubscriptionMode.accept_all);
chatManager = connection.getChatManager(); chatManager = connection.getChatManager();
chatManager.addChatListener(this); chatManager.addChatListener(this);
return true;
} }
catch (XMPPException ex) catch (XMPPException ex)
{ {
LOGGER.log(Level.WARNING, "Failed to connect to server: " + server, ex); LOGGER.log(Level.WARNING, "Failed to connect to server: " + server, ex);
return false;
} }
} }
public final void disconnect() public final void disconnect()
{ {
if (loggerThread != null)
{
loggerThread.interrupt();
}
if (chatManager != null)
{
chatManager.removeChatListener(this);
chatManager = null;
}
if (connection != null) if (connection != null)
{ {
connection.disconnect(new Presence(Presence.Type.unavailable)); connection.disconnect(new Presence(Presence.Type.unavailable));
} }
} }
@Override @Override
@@ -151,14 +174,18 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
@Override @Override
public final void reloadConfig() public final void reloadConfig()
{ {
LOGGER.removeHandler(this);
config.load(); config.load();
synchronized (chats) synchronized (chats)
{ {
disconnect(); disconnect();
chats.clear(); chats.clear();
connect(); if (!connect())
{
return;
}
startLoggerThread();
} }
LOGGER.removeHandler(this);
if (config.getBoolean("log-enabled", false)) if (config.getBoolean("log-enabled", false))
{ {
LOGGER.addHandler(this); LOGGER.addHandler(this);
@@ -187,14 +214,9 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
} }
if (logRecord.getLevel().intValue() >= logLevel.intValue()) if (logRecord.getLevel().intValue() >= logLevel.intValue())
{ {
for (String user : logUsers) synchronized (logrecords)
{ {
startChat(user); logrecords.add(logRecord);
final Chat chat = chats.get(user);
if (chat != null)
{
chat.sendMessage(String.format("[" + logRecord.getLevel().getLocalizedName() + "] " + logRecord.getMessage(), logRecord.getParameters()));
}
} }
} }
} }
@@ -217,6 +239,73 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager
// Ignore this // Ignore this
} }
private void startLoggerThread()
{
loggerThread = new Thread(new Runnable()
{
@Override
public void run()
{
final Set<LogRecord> copy = new HashSet<LogRecord>();
final Set<String> failedUsers = new HashSet<String>();
while (threadrunning)
{
synchronized (logrecords)
{
if (!logrecords.isEmpty())
{
copy.addAll(logrecords);
logrecords.clear();
}
}
if (!copy.isEmpty())
{
for (String user : logUsers)
{
try
{
XMPPManager.this.startChat(user);
for (LogRecord logRecord : copy)
{
final String message = String.format("[" + logRecord.getLevel().getLocalizedName() + "] " + logRecord.getMessage(), logRecord.getParameters());
if (!XMPPManager.this.sendMessage(user, message))
{
failedUsers.add(user);
break;
}
}
}
catch (XMPPException ex)
{
failedUsers.add(user);
LOGGER.removeHandler(XMPPManager.this);
LOGGER.log(Level.SEVERE, "Failed to deliver log message! Disabling logging to XMPP.", ex);
}
}
logUsers.removeAll(failedUsers);
if (logUsers.isEmpty())
{
LOGGER.removeHandler(XMPPManager.this);
threadrunning = false;
}
copy.clear();
}
try
{
Thread.sleep(2000);
}
catch (InterruptedException ex)
{
threadrunning = false;
}
}
LOGGER.removeHandler(XMPPManager.this);
}
});
loggerThread.start();
}
private void startChat(final String address) throws XMPPException private void startChat(final String address) throws XMPPException
{ {
if (chatManager == null) if (chatManager == null)