/** * StatusServlet * Copyright 27.02.2015 by Michael Peter Christen, @0rb1t3r * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in the file lgpl21.txt * If not, see <http://www.gnu.org/licenses/>. */ package org.loklak.api.admin; import java.io.IOException; import java.util.Date; import java.util.Enumeration; import java.util.List; import javax.servlet.http.HttpServletResponse; import org.elasticsearch.search.sort.SortOrder; import org.json.JSONObject; import org.loklak.Caretaker; import org.loklak.LoklakServer; import org.loklak.data.DAO; import org.loklak.data.IncomingMessageBuffer; import org.loklak.http.ClientConnection; import org.loklak.objects.QueryEntry; import org.loklak.server.APIException; import org.loklak.server.APIHandler; import org.loklak.server.AbstractAPIHandler; import org.loklak.server.Authorization; import org.loklak.server.BaseUserRole; import org.loklak.server.Query; import org.loklak.tools.OS; import org.loklak.tools.UTF8; import org.loklak.tools.storage.JSONObjectWithDefault; public class StatusService extends AbstractAPIHandler implements APIHandler { private static final long serialVersionUID = 8578478303032749879L; @Override public String getAPIPath() { return "/api/status.json"; } @Override public BaseUserRole getMinimalBaseUserRole() { return BaseUserRole.ANONYMOUS; } @Override public JSONObject getDefaultPermissions(BaseUserRole baseUserRole) { return null; } public static JSONObject status(final String protocolhostportstub) throws IOException { final String urlstring = protocolhostportstub + "/api/status.json"; byte[] response = ClientConnection.downloadPeer(urlstring); if (response == null || response.length == 0) return new JSONObject(); JSONObject json = new JSONObject(UTF8.String(response)); return json; } @Override public JSONObject serviceImpl(Query post, HttpServletResponse response, Authorization rights, JSONObjectWithDefault permissions) throws APIException { if (post.isLocalhostAccess() && OS.canExecUnix && post.get("upgrade", "").equals("true")) { Caretaker.upgrade(); // it's a hack to add this here, this may disappear anytime } final String backend = DAO.getConfig("backend", ""); final boolean backend_push = DAO.getConfig("backend.push.enabled", false); JSONObject backend_status = null; JSONObject backend_status_index_sizes = null; if (backend.length() > 0 && !backend_push) try { backend_status = StatusService.status(backend); backend_status_index_sizes = backend_status == null ? null : (JSONObject) backend_status.get("index_sizes"); } catch (IOException e) {} long backend_messages = backend_status_index_sizes == null ? 0 : ((Number) backend_status_index_sizes.get("messages")).longValue(); long backend_users = backend_status_index_sizes == null ? 0 : ((Number) backend_status_index_sizes.get("users")).longValue(); long local_messages = DAO.countLocalMessages(); long local_users = DAO.countLocalUsers(); post.setResponse(response, "application/javascript"); // generate json Runtime runtime = Runtime.getRuntime(); JSONObject json = new JSONObject(true); JSONObject system = new JSONObject(true); system.put("assigned_memory", runtime.maxMemory()); system.put("used_memory", runtime.totalMemory() - runtime.freeMemory()); system.put("available_memory", runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory()); system.put("cores", runtime.availableProcessors()); system.put("threads", Thread.activeCount()); system.put("runtime", System.currentTimeMillis() - Caretaker.startupTime); system.put("time_to_restart", Caretaker.upgradeTime - System.currentTimeMillis()); system.put("load_system_average", OS.getSystemLoadAverage()); system.put("load_system_cpu", OS.getSystemCpuLoad()); system.put("load_process_cpu", OS.getProcessCpuLoad()); system.put("server_threads", LoklakServer.getServerThreads()); system.put("server_uri", LoklakServer.getServerURI()); JSONObject index = new JSONObject(true); long countLocalMinMessagesCreated = DAO.countLocalMessages(60000L, true); long countLocalMinMessagesTimestamp = DAO.countLocalMessages(60000L, false); long countLocal10MMessagesCreated = DAO.countLocalMessages(600000L, true); long countLocal10MMessagesTimestamp = DAO.countLocalMessages(600000L, false); long countLocalHourMessagesCreated = DAO.countLocalMessages(3600000L, true); long countLocalHourMessagesTimestamp = DAO.countLocalMessages(3600000L, false); long countLocalDayMessagesCreated = DAO.countLocalMessages(86400000L, true); long countLocalDayMessagesTimestamp = DAO.countLocalMessages(86400000L, false); long countLocalWeekMessagesCreated = DAO.countLocalMessages(604800000L, true); long countLocalWeekMessagesTimestamp = DAO.countLocalMessages(604800000L, false); float mps1mC = countLocalMinMessagesCreated / 60f; float mps1mT = countLocalMinMessagesTimestamp / 60f; float mps10mC = countLocal10MMessagesCreated / 600f; float mps10mT = countLocal10MMessagesTimestamp / 600f; float mps1hC = countLocalHourMessagesCreated / 3600f; float mps1hT = countLocalHourMessagesTimestamp / 3600f; float mps1dC = countLocalDayMessagesCreated / 86400f; float mps1dT = countLocalDayMessagesTimestamp / 86400f; float mps1wC = countLocalWeekMessagesCreated / 604800f; float mps1wT = countLocalWeekMessagesTimestamp / 604800f; index.put("mps1mC", mps1mC); index.put("mps1mT", mps1mT); index.put("mps10mC", mps10mC); index.put("mps10mT", mps10mT); index.put("mps1hC", mps1hC); index.put("mps1hT", mps1hT); index.put("mps1dC", mps1dC); index.put("mps1dT", mps1dT); index.put("mps1wC", mps1wC); index.put("mps1wT", mps1wT); index.put("mps", (int) // best of 1d, 1h and 10m Math.max( Math.max(mps1dC, Math.max(mps1hC, Math.max(mps10mC, mps1mC))), Math.max(mps1dT, Math.max(mps1hT, Math.max(mps10mT, mps1mT))) )); JSONObject messages = new JSONObject(true); messages.put("size", local_messages + backend_messages); messages.put("size_local", local_messages); messages.put("size_local_minute_created_at", countLocalMinMessagesCreated); messages.put("size_local_minute_timestamp", countLocalMinMessagesTimestamp); messages.put("size_local_10minutes_created_at", countLocal10MMessagesCreated); messages.put("size_local_10minutes_timestamp", countLocal10MMessagesTimestamp); messages.put("size_local_hour_created_at", countLocalHourMessagesCreated); messages.put("size_local_hour_timestamp", countLocalHourMessagesTimestamp); messages.put("size_local_day_created_at", countLocalDayMessagesCreated); messages.put("size_local_day_timestamp", countLocalDayMessagesTimestamp); messages.put("size_local_week_created_at", countLocalWeekMessagesCreated); messages.put("size_local_week_timestamp", countLocalWeekMessagesTimestamp); messages.put("size_backend", backend_messages); messages.put("stats", DAO.messages.getStats()); JSONObject queue = new JSONObject(true); queue.put("size", IncomingMessageBuffer.getMessageQueueSize()); queue.put("maxSize", IncomingMessageBuffer.getMessageQueueMaxSize()); queue.put("clients", IncomingMessageBuffer.getMessageQueueClients()); messages.put("queue", queue); JSONObject users = new JSONObject(true); users.put("size", local_users + backend_users); users.put("size_local", local_users); users.put("size_backend", backend_users); users.put("stats", DAO.users.getStats()); JSONObject queries = new JSONObject(true); queries.put("size", DAO.countLocalQueries()); queries.put("stats", DAO.queries.getStats()); JSONObject accounts = new JSONObject(true); accounts.put("size", DAO.countLocalAccounts()); JSONObject user = new JSONObject(true); user.put("size", DAO.user_dump.size()); JSONObject followers = new JSONObject(true); followers.put("size", DAO.followers_dump.size()); JSONObject following = new JSONObject(true); following.put("size", DAO.following_dump.size()); index.put("messages", messages); index.put("users", users); index.put("queries", queries); index.put("accounts", accounts); index.put("user", user); index.put("followers", followers); index.put("following", following); if (DAO.getConfig("retrieval.queries.enabled", false)) { List<QueryEntry> queryList = DAO.SearchLocalQueries("", 1000, "retrieval_next", "date", SortOrder.ASC, null, new Date(), "retrieval_next"); index.put("queries_pending", queryList.size()); } JSONObject client_info = new JSONObject(true); client_info.put("RemoteHost", post.getClientHost()); client_info.put("IsLocalhost", post.isLocalhostAccess() ? "true" : "false"); JSONObject request_header = new JSONObject(true); Enumeration<String> he = post.getRequest().getHeaderNames(); while (he.hasMoreElements()) { String h = he.nextElement(); request_header.put(h, post.getRequest().getHeader(h)); } client_info.put("request_header", request_header); json.put("system", system); json.put("index", index); json.put("client_info", client_info); return json; } public static void main(String[] args) { try { JSONObject json = status("http://loklak.org"); JSONObject index_sizs = (JSONObject) json.get("index_sizes"); System.out.println(json.toString()); System.out.println(index_sizs.toString()); } catch (IOException e) { e.printStackTrace(); } } }