Add file tailer. Tail your server.log and send output to user or channel.

This commit is contained in:
cnaude 2015-11-15 17:25:26 -07:00
parent 2c65df64bf
commit 9b7c0d4deb
5 changed files with 156 additions and 6 deletions

View File

@ -103,7 +103,13 @@
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
<version>1.9</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- Following dependency is provided by CraftBukkit -->

View File

@ -0,0 +1,113 @@
/*
* Copyright (C) 2014 cnaude
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.cnaude.purpleirc;
import java.io.File;
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListener;
import org.apache.commons.io.input.TailerListenerAdapter;
/**
*
* @author Chris Naude Poll the command queue and dispatch to Bukkit
*/
public class LogTailer {
private final PurpleIRC plugin;
private final PurpleBot ircBot;
private final String target;
private final boolean ctcp;
private static final int SLEEP = 500;
private final File file;
private Tailer tailer;
private Thread thread;
private TailerListener listener;
/**
*
* @param plugin
* @param ircBot
* @param target
* @param ctcp
* @param fileName
*/
public LogTailer(final PurpleBot ircBot, final PurpleIRC plugin, final String target, final boolean ctcp, final String fileName) {
this.plugin = plugin;
this.ircBot = ircBot;
this.target = target;
this.ctcp = ctcp;
this.file = new File(fileName);
if (file.exists()) {
startWatcher();
} else {
plugin.logError("No such file: " + fileName);
}
}
private void startWatcher() {
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
@Override
public void run() {
plugin.logInfo("Tailing file: " + file.getName());
listener = new MyTailerListener();
tailer = new Tailer(file, listener, SLEEP);
thread = new Thread(tailer);
thread.setDaemon(true); // optional
thread.start();
}
}, 0);
}
public class MyTailerListener extends TailerListenerAdapter {
@Override
public void handle(String line) {
if (ctcp) {
blockingCTCPMessage(target, line);
} else {
blockingIRCMessage(target, line);
}
}
}
private void blockingIRCMessage(final String target, final String message) {
if (!ircBot.isConnected()) {
return;
}
plugin.logDebug("[blockingIRCMessage] About to send IRC message to " + target + ": " + message);
ircBot.bot.sendIRC().message(target, message);
plugin.logDebug("[blockingIRCMessage] Message sent to " + target + ": " + message);
}
private void blockingCTCPMessage(final String target, final String message) {
if (!ircBot.isConnected()) {
return;
}
plugin.logDebug("[blockingCTCPMessage] About to send IRC message to " + target + ": " + message);
ircBot.bot.sendIRC().ctcpResponse(target, message);
plugin.logDebug("[blockingCTCPMessage] Message sent to " + target + ": " + message);
}
protected void stopTailer() {
if (tailer != null) {
plugin.logInfo("Stoping tailer.");
tailer.stop();
}
}
}

View File

@ -59,6 +59,7 @@ import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import me.botsko.prism.actionlibs.QueryParameters;
import me.botsko.prism.events.BlockStateChange;
import org.apache.commons.io.input.Tailer;
import org.bukkit.Achievement;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
@ -188,6 +189,11 @@ public final class PurpleBot {
public CaseInsensitiveMap<String> linkRequests;
public CaseInsensitiveMap<Collection<String>> remotePlayers;
public CaseInsensitiveMap<CaseInsensitiveMap<String>> remoteServerInfo;
private LogTailer tailer;
private boolean tailerEnabled;
private String tailerFile;
private String tailerRecipient;
private boolean tailerCtcp;
/**
*
@ -275,6 +281,9 @@ public final class PurpleBot {
}
public void buildBot(boolean reload) {
if (tailer != null) {
tailer.stopTailer();
}
Configuration.Builder configBuilder = new Configuration.Builder()
.setName(botNick)
.setLogin(botLogin)
@ -354,6 +363,15 @@ public final class PurpleBot {
plugin.logInfo("Auto-connect is disabled. To connect: /irc connect " + bot.getNick());
}
plugin.logDebug("Max line length: " + configBuilder.getMaxLineLength());
if (tailerEnabled && !tailerFile.isEmpty() && !tailerRecipient.isEmpty()) {
tailer = new LogTailer(this, plugin, tailerRecipient, tailerCtcp, tailerFile);
}
}
protected void stopTailer() {
if (tailer != null) {
tailer.stopTailer();
}
}
private void addListeners() {
@ -777,6 +795,12 @@ public final class PurpleBot {
plugin.logInfo(" No command recipients defined.");
}
// load tailer settings
tailerEnabled = config.getBoolean("file-tailer.enabled", false);
tailerFile = config.getString("file-tailer.file", "server.log");
tailerRecipient = config.getString("file-tailer.recipient", "");
tailerCtcp = config.getBoolean("file-tailer.ctcp", false);
// build command notify ignore list
for (String command : config.getStringList("command-notify.ignore")) {
if (!channelCmdNotifyIgnore.contains(command)) {

View File

@ -346,6 +346,7 @@ public class PurpleIRC extends JavaPlugin {
logInfo("Disconnecting IRC bots.");
for (PurpleBot ircBot : ircBots.values()) {
commandQueue.cancel();
ircBot.stopTailer();
ircBot.saveConfig(getServer().getConsoleSender());
ircBot.quit();
}

View File

@ -66,6 +66,12 @@ command-notify:
- example
ignore:
- /example
# File tailer
file-tailer:
enabled: false
file: 'server.log'
recipient: '#minecraft-test'
ctcp: false
# Messaging flood control (game and IRC)
flood-control:
# Enable or disable flood control