added a 'stats' table which records some peer statistics twice every

hour. The table can be shown with
http://localhost:8090/Tables_p.html?table=stats

The entries have the following meaning: 
aM: activeLastMonth
aW: activeLastWeek
aD: activeLastDay
aH: activeLastHour
cC: countConnected (Active Senior)
cD: countDisconnected (Passive Senior)
cP: countPotential (Junior)
cR: count of the RWI entries
cI: size of the index (number of documents)

The entry keys are abbreviated to reduce the space in the table as the
name is written again for every row.

This is the beginning of a 'yacystats' micro-alternative als built-in
function in YaCy. Graphics may follow after some time if enough test
data is available.
pull/1/head
Michael Peter Christen 11 years ago
parent a11bc10629
commit ad35d9294f

@ -36,6 +36,7 @@ import net.yacy.cora.util.NumberTools;
public class GenericFormatter extends AbstractFormatter implements DateFormatter { public class GenericFormatter extends AbstractFormatter implements DateFormatter {
public static final String PATTERN_SHORT_DAY = "yyyyMMdd"; public static final String PATTERN_SHORT_DAY = "yyyyMMdd";
public static final String PATTERN_SHORT_MINUTE = "yyyyMMddHHmm";
public static final String PATTERN_SHORT_SECOND = "yyyyMMddHHmmss"; public static final String PATTERN_SHORT_SECOND = "yyyyMMddHHmmss";
public static final String PATTERN_SHORT_MILSEC = "yyyyMMddHHmmssSSS"; public static final String PATTERN_SHORT_MILSEC = "yyyyMMddHHmmssSSS";
public static final String PATTERN_RFC1123_SHORT = "EEE, dd MMM yyyy"; public static final String PATTERN_RFC1123_SHORT = "EEE, dd MMM yyyy";
@ -43,6 +44,7 @@ public class GenericFormatter extends AbstractFormatter implements DateFormatter
public static final String PATTERN_SIMPLE = "yyyy/MM/dd HH:mm:ss"; public static final String PATTERN_SIMPLE = "yyyy/MM/dd HH:mm:ss";
public static final SimpleDateFormat FORMAT_SHORT_DAY = new SimpleDateFormat(PATTERN_SHORT_DAY, Locale.US); public static final SimpleDateFormat FORMAT_SHORT_DAY = new SimpleDateFormat(PATTERN_SHORT_DAY, Locale.US);
public static final SimpleDateFormat FORMAT_SHORT_MINUTE = new SimpleDateFormat(PATTERN_SHORT_MINUTE, Locale.US);
public static final SimpleDateFormat FORMAT_SHORT_SECOND = new SimpleDateFormat(PATTERN_SHORT_SECOND, Locale.US); public static final SimpleDateFormat FORMAT_SHORT_SECOND = new SimpleDateFormat(PATTERN_SHORT_SECOND, Locale.US);
public static final SimpleDateFormat FORMAT_SHORT_MILSEC = new SimpleDateFormat(PATTERN_SHORT_MILSEC, Locale.US); public static final SimpleDateFormat FORMAT_SHORT_MILSEC = new SimpleDateFormat(PATTERN_SHORT_MILSEC, Locale.US);
public static final SimpleDateFormat FORMAT_RFC1123_SHORT = new SimpleDateFormat(PATTERN_RFC1123_SHORT, Locale.US); public static final SimpleDateFormat FORMAT_RFC1123_SHORT = new SimpleDateFormat(PATTERN_RFC1123_SHORT, Locale.US);
@ -65,6 +67,7 @@ public class GenericFormatter extends AbstractFormatter implements DateFormatter
public static final long time_day = 24 * time_hour; public static final long time_day = 24 * time_hour;
public static final GenericFormatter SHORT_DAY_FORMATTER = new GenericFormatter(FORMAT_SHORT_DAY, time_minute); public static final GenericFormatter SHORT_DAY_FORMATTER = new GenericFormatter(FORMAT_SHORT_DAY, time_minute);
public static final GenericFormatter SHORT_MINUTE_FORMATTER = new GenericFormatter(FORMAT_SHORT_MINUTE, time_second);
public static final GenericFormatter SHORT_SECOND_FORMATTER = new GenericFormatter(FORMAT_SHORT_SECOND, time_second); public static final GenericFormatter SHORT_SECOND_FORMATTER = new GenericFormatter(FORMAT_SHORT_SECOND, time_second);
public static final GenericFormatter SHORT_MILSEC_FORMATTER = new GenericFormatter(FORMAT_SHORT_MILSEC, 1); public static final GenericFormatter SHORT_MILSEC_FORMATTER = new GenericFormatter(FORMAT_SHORT_MILSEC, 1);
public static final GenericFormatter RFC1123_SHORT_FORMATTER = new GenericFormatter(FORMAT_RFC1123_SHORT, time_minute); public static final GenericFormatter RFC1123_SHORT_FORMATTER = new GenericFormatter(FORMAT_RFC1123_SHORT, time_minute);

@ -189,7 +189,7 @@ public class WorkTables extends Tables {
Data data = new Data(); Data data = new Data();
data.put(TABLE_API_COL_TYPE, UTF8.getBytes(type)); data.put(TABLE_API_COL_TYPE, UTF8.getBytes(type));
data.put(TABLE_API_COL_COMMENT, UTF8.getBytes(comment)); data.put(TABLE_API_COL_COMMENT, UTF8.getBytes(comment));
byte[] date = UTF8.getBytes(GenericFormatter.SHORT_MILSEC_FORMATTER.format()); byte[] date = ASCII.getBytes(GenericFormatter.SHORT_MILSEC_FORMATTER.format());
data.put(TABLE_API_COL_DATE_RECORDING, date); data.put(TABLE_API_COL_DATE_RECORDING, date);
data.put(TABLE_API_COL_DATE_LAST_EXEC, date); data.put(TABLE_API_COL_DATE_LAST_EXEC, date);
data.put(TABLE_API_COL_URL, UTF8.getBytes(apiurl)); data.put(TABLE_API_COL_URL, UTF8.getBytes(apiurl));

@ -413,18 +413,18 @@ public final class SeedDB implements AlternativeDomainNames {
} }
/** /**
* count the number of peers that had been seed within the time limit * count the number of peers that had been seen within the given time limit
* @param limit the time limit in minutes. 1440 minutes is a day * @param limitMinutes the time limit in minutes. 1440 minutes is a day
* @return the number of peers seen in the given time * @return the number of peers seen in the given time
*/ */
public int sizeActiveSince(final long limit) { public int sizeActiveSince(final long limitMinutes) {
int c = this.seedActiveDB.size(); int c = this.seedActiveDB.size();
Seed seed; Seed seed;
Iterator<Seed> i = seedsSortedDisconnected(false, Seed.LASTSEEN); Iterator<Seed> i = seedsSortedDisconnected(false, Seed.LASTSEEN);
while (i.hasNext()) { while (i.hasNext()) {
seed = i.next(); seed = i.next();
if (seed != null) { if (seed != null) {
if (Math.abs((System.currentTimeMillis() - seed.getLastSeenUTC()) / 1000 / 60) > limit) break; if (Math.abs((System.currentTimeMillis() - seed.getLastSeenUTC()) / 1000 / 60) > limitMinutes) break;
c++; c++;
} }
} }
@ -432,7 +432,7 @@ public final class SeedDB implements AlternativeDomainNames {
while (i.hasNext()) { while (i.hasNext()) {
seed = i.next(); seed = i.next();
if (seed != null) { if (seed != null) {
if (Math.abs((System.currentTimeMillis() - seed.getLastSeenUTC()) / 1000 / 60) > limit) break; if (Math.abs((System.currentTimeMillis() - seed.getLastSeenUTC()) / 1000 / 60) > limitMinutes) break;
c++; c++;
} }
} }

@ -58,6 +58,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -155,6 +156,7 @@ import net.yacy.document.parser.audioTagParser;
import net.yacy.document.parser.pdfParser; import net.yacy.document.parser.pdfParser;
import net.yacy.document.parser.html.Evaluation; import net.yacy.document.parser.html.Evaluation;
import net.yacy.gui.Tray; import net.yacy.gui.Tray;
import net.yacy.kelondro.blob.BEncodedHeap;
import net.yacy.kelondro.blob.Tables; import net.yacy.kelondro.blob.Tables;
import net.yacy.kelondro.data.meta.URIMetadataNode; import net.yacy.kelondro.data.meta.URIMetadataNode;
import net.yacy.kelondro.data.word.Word; import net.yacy.kelondro.data.word.Word;
@ -271,6 +273,7 @@ public final class Switchboard extends serverSwitch {
public SeedDB peers; public SeedDB peers;
public WorkTables tables; public WorkTables tables;
public Tray tray; public Tray tray;
private long lastStats = 0; // time when the last row was written to the stats table
public WorkflowProcessor<IndexingQueueEntry> indexingDocumentProcessor; public WorkflowProcessor<IndexingQueueEntry> indexingDocumentProcessor;
public WorkflowProcessor<IndexingQueueEntry> indexingCondensementProcessor; public WorkflowProcessor<IndexingQueueEntry> indexingCondensementProcessor;
@ -2356,6 +2359,26 @@ public final class Switchboard extends serverSwitch {
} }
} }
// write statistics
if (System.currentTimeMillis() - this.lastStats > 1500000 /*25min, should cause 2 entries every hour at least*/) try {
BEncodedHeap statTable = this.tables.getHeap("stats");
Map<String, byte[]> entry = new LinkedHashMap<>();
if (this.isP2PMode()) {
entry.put("aM", ASCII.getBytes(Integer.toString(this.peers.sizeActiveSince(30 * 1440)))); // activeLastMonth
entry.put("aW", ASCII.getBytes(Integer.toString(this.peers.sizeActiveSince(7 * 1440)))); // activeLastWeek
entry.put("aD", ASCII.getBytes(Integer.toString(this.peers.sizeActiveSince(1440)))); // activeLastDay
entry.put("aH", ASCII.getBytes(Integer.toString(this.peers.sizeActiveSince(60)))); // activeLastHour
entry.put("cC", ASCII.getBytes(Integer.toString(this.peers.sizeConnected()))); // countConnected (Active Senior)
entry.put("cD", ASCII.getBytes(Integer.toString(this.peers.sizeDisconnected()))); // countDisconnected (Passive Senior)
entry.put("cP", ASCII.getBytes(Integer.toString(this.peers.sizePotential()))); // countPotential (Junior)
entry.put("cR", ASCII.getBytes(Long.toString(this.index.RWICount()))); // count of the RWI entries
}
entry.put("cI", ASCII.getBytes(Long.toString(this.index.fulltext().collectionSize()))); // size of the index (number of documents)
byte[] pk = ASCII.getBytes(GenericFormatter.SHORT_MINUTE_FORMATTER.format()); // the primary key is the date, the maximum length is 12 characters which is sufficient for up-to-minute accuracy
statTable.put(pk, entry);
this.lastStats = System.currentTimeMillis();
} catch (IOException e) {}
// execute api actions; this must be done after postprocessing because // execute api actions; this must be done after postprocessing because
// these actions may also influence the search index/ call optimize steps // these actions may also influence the search index/ call optimize steps
execAPIActions(); execAPIActions();

Loading…
Cancel
Save