/* * Jitsi Videobridge, OpenSource video conferencing. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jitsi.videobridge.log; import org.jitsi.service.configuration.*; import org.jitsi.util.*; import org.json.simple.*; import java.io.*; import java.net.*; import java.util.*; import java.util.concurrent.*; import org.slf4j.*; import org.slf4j.Logger; import org.jivesoftware.openfire.security.SecurityAuditManager; import org.jivesoftware.util.*; import org.xmpp.packet.*; /** * Allows logging of {@link org.jitsi.videobridge.log.Event}s using an * <tt>Openfire</tt> instance. * */ public class OpenfireEventService implements LoggingService { private static final Logger Log = LoggerFactory.getLogger(OpenfireEventService.class); /** * The <tt>Executor</tt> which is to perform the task of sending data to * <tt>Openfire</tt>. */ private final Executor executor = ExecutorUtils.newCachedThreadPool(true, OpenfireEventService.class.getName()); /** * Initializes a new <tt>OpenfireEventService</tt> instance, by reading * its configuration from <tt>cfg</tt>. * @param cfg the <tt>ConfigurationService</tt> to use. * * @throws Exception if initialization fails */ OpenfireEventService() throws Exception { Log.info("Initialized OpenfireEventService"); } /** * Logs an <tt>Event</tt> to an <tt>InfluxDB</tt> database. This method * returns without blocking, the blocking operations are performed in * by a thread from {@link #executor}. * * @param e the <tt>Event</tt> to log. */ @SuppressWarnings("unchecked") @Override public void logEvent(final Event e) { // The following is a sample JSON message in the format used by InfluxDB // [ // { // "name": "series_name", // "columns": ["column1", "column2"], // "points": [["value1", 1234]] // } // ] if ("focus_created".equals(e.getName())) return; JSONObject jsonObject = new JSONObject(); jsonObject.put("name", e.getName()); JSONArray columns = new JSONArray(); JSONArray point = new JSONArray(); if (e.useLocalTime()) { columns.add("time"); point.add(System.currentTimeMillis()); } Collections.addAll(columns, e.getColumns()); Collections.addAll(point, e.getValues()); jsonObject.put("columns", columns); JSONArray points = new JSONArray(); points.add(point); jsonObject.put("points", points); JSONArray jsonArray = new JSONArray(); jsonArray.add(jsonObject); // TODO: this is probably a good place to optimize by grouping multiple // events in a single POST message and/or multiple points for events // of the same type together). final String jsonString = jsonArray.toJSONString(); executor.execute(new Runnable() { @Override public void run() { sendPost(e.getName(), jsonString); } }); } /** * Sends the string <tt>s</tt> as the contents of an HTTP POST request to * {@link #url}. * @param s the content of the POST request. */ private void sendPost(final String summary, final String detail) { try { String focusUsername = "focus"; String focusUserJid = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.focus.user.jid"); if (focusUserJid != null) { focusUsername = (new JID(focusUserJid)).getNode(); } Log.info("OpenfireEventService sendPost " + focusUsername + " " + detail); SecurityAuditManager.getInstance().logEvent(focusUsername, summary, detail); } catch (Exception e) { Log.error("Failed to send event to Openfire: " + e); } } }