1 11 12 package org.jivesoftware.messenger.audit.spi; 13 14 import org.dom4j.DocumentFactory; 15 import org.dom4j.Element; 16 import org.jivesoftware.messenger.Session; 17 import org.jivesoftware.messenger.audit.AuditManager; 18 import org.jivesoftware.messenger.audit.Auditor; 19 import org.jivesoftware.util.LocaleUtils; 20 import org.jivesoftware.util.Log; 21 import org.xmpp.packet.IQ; 22 import org.xmpp.packet.Message; 23 import org.xmpp.packet.Packet; 24 import org.xmpp.packet.Presence; 25 26 import java.io.*; 27 import java.util.Date ; 28 import java.util.Queue ; 29 import java.util.Timer ; 30 import java.util.TimerTask ; 31 import java.util.concurrent.LinkedBlockingQueue ; 32 33 public class AuditorImpl implements Auditor { 34 35 private AuditManager auditManager; 36 private File currentAuditFile; 37 private Writer writer; 38 private org.jivesoftware.util.XMLWriter xmlWriter; 39 private int maxSize; 40 private long maxCount; 41 private int logTimeout; 42 private boolean closed = false; 43 46 private String logDir; 47 48 51 private Queue <AuditPacket> logQueue = new LinkedBlockingQueue <AuditPacket>(); 52 53 56 private Timer timer = new Timer ("Auditor"); 57 private SaveQueuedPacketsTask saveQueuedPacketsTask; 58 59 public AuditorImpl(AuditManager manager) { 60 auditManager = manager; 61 } 62 63 public void audit(Packet packet, Session session) { 64 if (auditManager.isEnabled()) { 65 if (packet instanceof Message) { 66 if (auditManager.isAuditMessage()) { 67 writePacket(packet, session); 68 } 69 } 70 else if (packet instanceof Presence) { 71 if (auditManager.isAuditPresence()) { 72 writePacket(packet, session); 73 } 74 } 75 else if (packet instanceof IQ) { 76 if (auditManager.isAuditIQ()) { 77 writePacket(packet, session); 78 } 79 } 80 } 81 } 82 83 public void stop() { 84 timer.cancel(); 86 saveQueuedPackets(); 88 close(); 89 } 90 91 private void close() { 92 if (xmlWriter != null) { 93 try { 94 xmlWriter.flush(); 95 writer.write("</jive>"); 96 xmlWriter.close(); 97 writer = null; 98 } 99 catch (Exception e) { 100 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 101 } 102 } 103 } 104 105 private void writePacket(Packet packet, Session session) { 106 if (!closed) { 107 logQueue.add(new AuditPacket(packet.createCopy(), session)); 109 } 110 } 111 112 private void prepareAuditFile() throws IOException { 113 if (currentAuditFile == null || currentAuditFile.length() > maxSize) { 114 rotateFiles(); 115 } 116 } 117 118 protected void setMaxValues(int size, int count) { 119 maxSize = size * 1024*1024; 120 maxCount = count; 121 } 122 123 public void setLogTimeout(int newTimeout) { 124 if (saveQueuedPacketsTask != null) { 126 saveQueuedPacketsTask.cancel(); 127 } 128 this.logTimeout = newTimeout; 129 saveQueuedPacketsTask = new SaveQueuedPacketsTask(); 131 timer.schedule(saveQueuedPacketsTask, logTimeout, logTimeout); 132 133 } 134 135 public void setLogDir(String logDir) { 136 this.logDir = logDir; 137 } 138 139 public int getQueuedPacketsNumber() { 140 return logQueue.size(); 141 } 142 143 private void rotateFiles() throws IOException { 144 close(); 145 int i; 146 for (i = 0; maxCount < 1 || i < maxCount; i++) { 148 currentAuditFile = new File(logDir, "jive.audit-" + i + ".log"); 149 if (!currentAuditFile.exists()) { 150 break; 151 } 152 } 153 if (i != 0) { 157 if (i == maxCount) { 158 currentAuditFile.delete(); 163 } 164 for (i--; i >= 0; i--) { 166 String previousName = "jive.audit-" + i + ".log"; 167 File previousFile = new File(logDir, previousName); 168 previousFile.renameTo(currentAuditFile); 169 currentAuditFile = new File(logDir, previousName); 170 } 171 } 172 173 writer = new OutputStreamWriter(new FileOutputStream(currentAuditFile), "UTF-8"); 174 writer.write("<jive xmlns=\"http://www.jivesoftware.org\">"); 175 xmlWriter = new org.jivesoftware.util.XMLWriter(writer); 176 } 177 178 181 private class SaveQueuedPacketsTask extends TimerTask { 182 public void run() { 183 try { 184 saveQueuedPackets(); 185 } 186 catch (Throwable e) { 187 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 188 } 189 } 190 } 191 192 private void saveQueuedPackets() { 193 int batchSize = logQueue.size(); 194 for (int index = 0; index < batchSize; index++) { 195 AuditPacket auditPacket = logQueue.poll(); 196 if (auditPacket != null) { 197 try { 198 prepareAuditFile(); 199 xmlWriter.write(auditPacket.getElement()); 200 } 201 catch (IOException e) { 202 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 203 logQueue.add(auditPacket); 205 } 206 } 207 } 208 try { 209 if (xmlWriter != null) { 210 xmlWriter.flush(); 211 } 212 } 213 catch (IOException ioe) { 214 215 } 216 } 217 218 225 private static class AuditPacket { 226 227 private static DocumentFactory docFactory = DocumentFactory.getInstance(); 228 229 private Element element; 230 231 public AuditPacket(Packet packet, Session session) { 232 element = docFactory.createElement("packet", "http://www.jivesoftware.org"); 233 if (session.getStreamID() != null) { 234 element.addAttribute("streamID", session.getStreamID().toString()); 235 } 236 switch (session.getStatus()) { 237 case Session.STATUS_AUTHENTICATED: 238 element.addAttribute("status", "auth"); 239 break; 240 case Session.STATUS_CLOSED: 241 element.addAttribute("status", "closed"); 242 break; 243 case Session.STATUS_CONNECTED: 244 element.addAttribute("status", "connected"); 245 packet.setFrom((String ) null); 250 break; 251 case Session.STATUS_STREAMING: 252 element.addAttribute("status", "stream"); 253 break; 254 default: 255 element.addAttribute("status", "unknown"); 256 break; 257 } 258 element.addAttribute("timestamp", new Date ().toString()); 259 element.add(packet.getElement()); 260 } 261 262 267 public Element getElement() { 268 return element; 269 } 270 } 271 } | Popular Tags |