mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
use codahale metrics library instead of our own
This commit is contained in:
11
pom.xml
11
pom.xml
@@ -372,6 +372,17 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.codahale.metrics</groupId>
|
||||||
|
<artifactId>metrics-core</artifactId>
|
||||||
|
<version>3.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.codahale.metrics</groupId>
|
||||||
|
<artifactId>metrics-json</artifactId>
|
||||||
|
<version>3.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|||||||
@@ -1,179 +0,0 @@
|
|||||||
package com.commafeed.backend;
|
|
||||||
|
|
||||||
import javax.ejb.Singleton;
|
|
||||||
import javax.interceptor.AroundInvoke;
|
|
||||||
import javax.interceptor.InvocationContext;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.PersistenceContext;
|
|
||||||
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
import org.hibernate.stat.Statistics;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class MetricsBean {
|
|
||||||
|
|
||||||
@PersistenceContext
|
|
||||||
EntityManager em;
|
|
||||||
|
|
||||||
private Metric lastMinute = new Metric();
|
|
||||||
private Metric thisMinute = new Metric();
|
|
||||||
|
|
||||||
private Metric lastHour = new Metric();
|
|
||||||
private Metric thisHour = new Metric();
|
|
||||||
|
|
||||||
private long minuteTimestamp;
|
|
||||||
private long hourTimestamp;
|
|
||||||
|
|
||||||
@AroundInvoke
|
|
||||||
private Object roll(InvocationContext context) throws Exception {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
if (now - minuteTimestamp > 60000) {
|
|
||||||
lastMinute = thisMinute;
|
|
||||||
thisMinute = new Metric();
|
|
||||||
minuteTimestamp = now;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now - hourTimestamp > 60000 * 60) {
|
|
||||||
lastHour = thisHour;
|
|
||||||
thisHour = new Metric();
|
|
||||||
hourTimestamp = now;
|
|
||||||
|
|
||||||
}
|
|
||||||
return context.proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void feedRefreshed() {
|
|
||||||
thisMinute.feedsRefreshed++;
|
|
||||||
thisHour.feedsRefreshed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void feedUpdated() {
|
|
||||||
thisHour.feedsUpdated++;
|
|
||||||
thisMinute.feedsUpdated++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void entryInserted() {
|
|
||||||
|
|
||||||
thisHour.entriesInserted++;
|
|
||||||
thisMinute.entriesInserted++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void entryCacheHit() {
|
|
||||||
thisHour.entryCacheHit++;
|
|
||||||
thisMinute.entryCacheHit++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void entryCacheMiss() {
|
|
||||||
thisHour.entryCacheMiss++;
|
|
||||||
thisMinute.entryCacheMiss++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pushReceived(int feedCount) {
|
|
||||||
|
|
||||||
thisHour.pushNotificationsReceived++;
|
|
||||||
thisMinute.pushNotificationsReceived++;
|
|
||||||
|
|
||||||
thisHour.pushFeedsQueued += feedCount;
|
|
||||||
thisMinute.pushFeedsQueued += feedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void threadWaited() {
|
|
||||||
thisHour.threadWaited++;
|
|
||||||
thisMinute.threadWaited++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Metric getLastMinute() {
|
|
||||||
return lastMinute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Metric getLastHour() {
|
|
||||||
return lastHour;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCacheStats() {
|
|
||||||
Session session = em.unwrap(Session.class);
|
|
||||||
SessionFactory sessionFactory = session.getSessionFactory();
|
|
||||||
Statistics statistics = sessionFactory.getStatistics();
|
|
||||||
return statistics.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Metric {
|
|
||||||
private int feedsRefreshed;
|
|
||||||
private int feedsUpdated;
|
|
||||||
private int entriesInserted;
|
|
||||||
private int threadWaited;
|
|
||||||
private int pushNotificationsReceived;
|
|
||||||
private int pushFeedsQueued;
|
|
||||||
private int entryCacheHit;
|
|
||||||
private int entryCacheMiss;
|
|
||||||
|
|
||||||
public int getFeedsRefreshed() {
|
|
||||||
return feedsRefreshed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFeedsRefreshed(int feedsRefreshed) {
|
|
||||||
this.feedsRefreshed = feedsRefreshed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFeedsUpdated() {
|
|
||||||
return feedsUpdated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFeedsUpdated(int feedsUpdated) {
|
|
||||||
this.feedsUpdated = feedsUpdated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEntriesInserted() {
|
|
||||||
return entriesInserted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntriesInserted(int entriesInserted) {
|
|
||||||
this.entriesInserted = entriesInserted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getThreadWaited() {
|
|
||||||
return threadWaited;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThreadWaited(int threadWaited) {
|
|
||||||
this.threadWaited = threadWaited;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPushNotificationsReceived() {
|
|
||||||
return pushNotificationsReceived;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPushNotificationsReceived(int pushNotificationsReceived) {
|
|
||||||
this.pushNotificationsReceived = pushNotificationsReceived;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPushFeedsQueued() {
|
|
||||||
return pushFeedsQueued;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPushFeedsQueued(int pushFeedsQueued) {
|
|
||||||
this.pushFeedsQueued = pushFeedsQueued;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEntryCacheHit() {
|
|
||||||
return entryCacheHit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntryCacheHit(int entryCacheHit) {
|
|
||||||
this.entryCacheHit = entryCacheHit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEntryCacheMiss() {
|
|
||||||
return entryCacheMiss;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntryCacheMiss(int entryCacheMiss) {
|
|
||||||
this.entryCacheMiss = entryCacheMiss;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,7 @@ import javax.persistence.EntityManager;
|
|||||||
import javax.persistence.PersistenceContext;
|
import javax.persistence.PersistenceContext;
|
||||||
|
|
||||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||||
|
import com.commafeed.backend.services.DatabaseCleaningService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains all scheduled tasks
|
* Contains all scheduled tasks
|
||||||
@@ -21,7 +22,7 @@ public class ScheduledTasks {
|
|||||||
ApplicationSettingsService applicationSettingsService;
|
ApplicationSettingsService applicationSettingsService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DatabaseCleaner cleaner;
|
DatabaseCleaningService cleaner;
|
||||||
|
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import com.codahale.metrics.Gauge;
|
||||||
|
import com.codahale.metrics.MetricRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps a {@link ThreadPoolExecutor} instance. Blocks when queue is full instead of rejecting the task. Allow priority queueing by using
|
* Wraps a {@link ThreadPoolExecutor} instance. Blocks when queue is full instead of rejecting the task. Allow priority queueing by using
|
||||||
* {@link Task} instead of {@link Runnable}
|
* {@link Task} instead of {@link Runnable}
|
||||||
@@ -19,7 +22,7 @@ public class FeedRefreshExecutor {
|
|||||||
private ThreadPoolExecutor pool;
|
private ThreadPoolExecutor pool;
|
||||||
private LinkedBlockingDeque<Runnable> queue;
|
private LinkedBlockingDeque<Runnable> queue;
|
||||||
|
|
||||||
public FeedRefreshExecutor(final String poolName, int threads, int queueCapacity) {
|
public FeedRefreshExecutor(final String poolName, int threads, int queueCapacity, MetricRegistry metrics) {
|
||||||
log.info("Creating pool {} with {} threads", poolName, threads);
|
log.info("Creating pool {} with {} threads", poolName, threads);
|
||||||
this.poolName = poolName;
|
this.poolName = poolName;
|
||||||
pool = new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS, queue = new LinkedBlockingDeque<Runnable>(queueCapacity) {
|
pool = new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS, queue = new LinkedBlockingDeque<Runnable>(queueCapacity) {
|
||||||
@@ -51,20 +54,26 @@ public class FeedRefreshExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
metrics.register(MetricRegistry.name(getClass(), poolName, "active"), new Gauge<Integer>() {
|
||||||
|
@Override
|
||||||
|
public Integer getValue() {
|
||||||
|
return pool.getActiveCount();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
metrics.register(MetricRegistry.name(getClass(), poolName, "pending"), new Gauge<Integer>() {
|
||||||
|
@Override
|
||||||
|
public Integer getValue() {
|
||||||
|
return queue.size();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(Task task) {
|
public void execute(Task task) {
|
||||||
pool.execute(task);
|
pool.execute(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getQueueSize() {
|
|
||||||
return queue.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getActiveCount() {
|
|
||||||
return pool.getActiveCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface Task extends Runnable {
|
public static interface Task extends Runnable {
|
||||||
boolean isUrgent();
|
boolean isUrgent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.apache.commons.lang.time.DateUtils;
|
import org.apache.commons.lang.time.DateUtils;
|
||||||
|
|
||||||
import com.commafeed.backend.MetricsBean;
|
import com.codahale.metrics.Meter;
|
||||||
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import com.commafeed.backend.dao.FeedDAO;
|
import com.commafeed.backend.dao.FeedDAO;
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||||
@@ -41,7 +42,7 @@ public class FeedRefreshTaskGiver {
|
|||||||
ApplicationSettingsService applicationSettingsService;
|
ApplicationSettingsService applicationSettingsService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
MetricsBean metricsBean;
|
MetricRegistry metrics;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
FeedRefreshWorker worker;
|
FeedRefreshWorker worker;
|
||||||
@@ -54,10 +55,15 @@ public class FeedRefreshTaskGiver {
|
|||||||
|
|
||||||
private ExecutorService executor;
|
private ExecutorService executor;
|
||||||
|
|
||||||
|
private Meter feedRefreshed;
|
||||||
|
private Meter threadWaited;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
backgroundThreads = applicationSettingsService.get().getBackgroundThreads();
|
backgroundThreads = applicationSettingsService.get().getBackgroundThreads();
|
||||||
executor = Executors.newFixedThreadPool(1);
|
executor = Executors.newFixedThreadPool(1);
|
||||||
|
feedRefreshed = metrics.meter(MetricRegistry.name(getClass(), "feedRefreshed"));
|
||||||
|
threadWaited = metrics.meter(MetricRegistry.name(getClass(), "threadWaited"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
@@ -88,11 +94,11 @@ public class FeedRefreshTaskGiver {
|
|||||||
try {
|
try {
|
||||||
FeedRefreshContext context = take();
|
FeedRefreshContext context = take();
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
metricsBean.feedRefreshed();
|
feedRefreshed.mark();
|
||||||
worker.updateFeed(context);
|
worker.updateFeed(context);
|
||||||
} else {
|
} else {
|
||||||
log.debug("nothing to do, sleeping for 15s");
|
log.debug("nothing to do, sleeping for 15s");
|
||||||
metricsBean.threadWaited();
|
threadWaited.mark();
|
||||||
try {
|
try {
|
||||||
Thread.sleep(15000);
|
Thread.sleep(15000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ import org.apache.commons.collections.CollectionUtils;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
|
|
||||||
import com.commafeed.backend.MetricsBean;
|
import com.codahale.metrics.Meter;
|
||||||
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import com.commafeed.backend.cache.CacheService;
|
import com.commafeed.backend.cache.CacheService;
|
||||||
import com.commafeed.backend.dao.FeedDAO;
|
import com.commafeed.backend.dao.FeedDAO;
|
||||||
import com.commafeed.backend.dao.FeedEntryDAO;
|
import com.commafeed.backend.dao.FeedEntryDAO;
|
||||||
@@ -57,7 +58,7 @@ public class FeedRefreshUpdater {
|
|||||||
ApplicationSettingsService applicationSettingsService;
|
ApplicationSettingsService applicationSettingsService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
MetricsBean metricsBean;
|
MetricRegistry metrics;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
FeedSubscriptionDAO feedSubscriptionDAO;
|
FeedSubscriptionDAO feedSubscriptionDAO;
|
||||||
@@ -71,12 +72,22 @@ public class FeedRefreshUpdater {
|
|||||||
private FeedRefreshExecutor pool;
|
private FeedRefreshExecutor pool;
|
||||||
private Striped<Lock> locks;
|
private Striped<Lock> locks;
|
||||||
|
|
||||||
|
private Meter entryCacheMiss;
|
||||||
|
private Meter entryCacheHit;
|
||||||
|
private Meter feedUpdated;
|
||||||
|
private Meter entryInserted;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
ApplicationSettings settings = applicationSettingsService.get();
|
ApplicationSettings settings = applicationSettingsService.get();
|
||||||
int threads = Math.max(settings.getDatabaseUpdateThreads(), 1);
|
int threads = Math.max(settings.getDatabaseUpdateThreads(), 1);
|
||||||
pool = new FeedRefreshExecutor("feed-refresh-updater", threads, Math.min(50 * threads, 1000));
|
pool = new FeedRefreshExecutor("feed-refresh-updater", threads, Math.min(50 * threads, 1000), metrics);
|
||||||
locks = Striped.lazyWeakLock(threads * 100000);
|
locks = Striped.lazyWeakLock(threads * 100000);
|
||||||
|
|
||||||
|
entryCacheMiss = metrics.meter(MetricRegistry.name(getClass(), "entryCacheMiss"));
|
||||||
|
entryCacheHit = metrics.meter(MetricRegistry.name(getClass(), "entryCacheHit"));
|
||||||
|
feedUpdated = metrics.meter(MetricRegistry.name(getClass(), "feedUpdated"));
|
||||||
|
entryInserted = metrics.meter(MetricRegistry.name(getClass(), "entryInserted"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
@@ -116,10 +127,10 @@ public class FeedRefreshUpdater {
|
|||||||
subscriptions = feedSubscriptionDAO.findByFeed(feed);
|
subscriptions = feedSubscriptionDAO.findByFeed(feed);
|
||||||
}
|
}
|
||||||
ok &= addEntry(feed, entry, subscriptions);
|
ok &= addEntry(feed, entry, subscriptions);
|
||||||
metricsBean.entryCacheMiss();
|
entryCacheMiss.mark();
|
||||||
} else {
|
} else {
|
||||||
log.debug("cache hit for {}", entry.getUrl());
|
log.debug("cache hit for {}", entry.getUrl());
|
||||||
metricsBean.entryCacheHit();
|
entryCacheHit.mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
currentEntries.add(cacheKey);
|
currentEntries.add(cacheKey);
|
||||||
@@ -147,7 +158,7 @@ public class FeedRefreshUpdater {
|
|||||||
// requeue asap
|
// requeue asap
|
||||||
feed.setDisabledUntil(new Date(0));
|
feed.setDisabledUntil(new Date(0));
|
||||||
}
|
}
|
||||||
metricsBean.feedUpdated();
|
feedUpdated.mark();
|
||||||
taskGiver.giveBack(feed);
|
taskGiver.giveBack(feed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +191,7 @@ public class FeedRefreshUpdater {
|
|||||||
if (locked1 && locked2) {
|
if (locked1 && locked2) {
|
||||||
boolean inserted = feedUpdateService.addEntry(feed, entry);
|
boolean inserted = feedUpdateService.addEntry(feed, entry);
|
||||||
if (inserted) {
|
if (inserted) {
|
||||||
metricsBean.entryInserted();
|
entryInserted.mark();
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -213,13 +224,4 @@ public class FeedRefreshUpdater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getQueueSize() {
|
|
||||||
return pool.getQueueSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getActiveCount() {
|
|
||||||
return pool.getActiveCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.apache.commons.lang.time.DateUtils;
|
import org.apache.commons.lang.time.DateUtils;
|
||||||
|
|
||||||
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import com.commafeed.backend.HttpGetter.NotModifiedException;
|
import com.commafeed.backend.HttpGetter.NotModifiedException;
|
||||||
import com.commafeed.backend.feeds.FeedRefreshExecutor.Task;
|
import com.commafeed.backend.feeds.FeedRefreshExecutor.Task;
|
||||||
import com.commafeed.backend.model.ApplicationSettings;
|
import com.commafeed.backend.model.ApplicationSettings;
|
||||||
@@ -37,6 +38,9 @@ public class FeedRefreshWorker {
|
|||||||
@Inject
|
@Inject
|
||||||
FeedRefreshTaskGiver taskGiver;
|
FeedRefreshTaskGiver taskGiver;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MetricRegistry metrics;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ApplicationSettingsService applicationSettingsService;
|
ApplicationSettingsService applicationSettingsService;
|
||||||
|
|
||||||
@@ -46,7 +50,7 @@ public class FeedRefreshWorker {
|
|||||||
private void init() {
|
private void init() {
|
||||||
ApplicationSettings settings = applicationSettingsService.get();
|
ApplicationSettings settings = applicationSettingsService.get();
|
||||||
int threads = settings.getBackgroundThreads();
|
int threads = settings.getBackgroundThreads();
|
||||||
pool = new FeedRefreshExecutor("feed-refresh-worker", threads, Math.min(20 * threads, 1000));
|
pool = new FeedRefreshExecutor("feed-refresh-worker", threads, Math.min(20 * threads, 1000), metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
@@ -58,14 +62,6 @@ public class FeedRefreshWorker {
|
|||||||
pool.execute(new FeedTask(context));
|
pool.execute(new FeedTask(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getQueueSize() {
|
|
||||||
return pool.getQueueSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getActiveCount() {
|
|
||||||
return pool.getActiveCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FeedTask implements Task {
|
private class FeedTask implements Task {
|
||||||
|
|
||||||
private FeedRefreshContext context;
|
private FeedRefreshContext context;
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.commafeed.backend.metrics;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
|
||||||
|
import com.codahale.metrics.MetricRegistry;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class MetricRegistryProducer {
|
||||||
|
|
||||||
|
private final MetricRegistry registry = new MetricRegistry();
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
public MetricRegistry produceMetricsRegistry() {
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.commafeed.backend.feeds;
|
package com.commafeed.backend.opml;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.commafeed.backend.feeds;
|
package com.commafeed.backend.opml;
|
||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -15,6 +15,7 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
|
|
||||||
import com.commafeed.backend.cache.CacheService;
|
import com.commafeed.backend.cache.CacheService;
|
||||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||||
|
import com.commafeed.backend.feeds.FeedUtils;
|
||||||
import com.commafeed.backend.model.FeedCategory;
|
import com.commafeed.backend.model.FeedCategory;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
import com.commafeed.backend.services.FeedSubscriptionService;
|
import com.commafeed.backend.services.FeedSubscriptionService;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.commafeed.backend;
|
package com.commafeed.backend.services;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -16,14 +16,13 @@ import com.commafeed.backend.dao.FeedEntryStatusDAO;
|
|||||||
import com.commafeed.backend.dao.FeedSubscriptionDAO;
|
import com.commafeed.backend.dao.FeedSubscriptionDAO;
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
import com.commafeed.backend.model.FeedSubscription;
|
import com.commafeed.backend.model.FeedSubscription;
|
||||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains utility methods for cleaning the database
|
* Contains utility methods for cleaning the database
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class DatabaseCleaner {
|
public class DatabaseCleaningService {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
FeedDAO feedDAO;
|
FeedDAO feedDAO;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.commafeed.backend;
|
package com.commafeed.backend.startup;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.commafeed.backend;
|
package com.commafeed.backend.startup;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@@ -15,7 +15,6 @@ import org.apache.wicket.markup.html.TransparentWebMarkupContainer;
|
|||||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||||
import org.apache.wicket.markup.html.WebPage;
|
import org.apache.wicket.markup.html.WebPage;
|
||||||
|
|
||||||
import com.commafeed.backend.StartupBean;
|
|
||||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||||
import com.commafeed.backend.dao.FeedDAO;
|
import com.commafeed.backend.dao.FeedDAO;
|
||||||
import com.commafeed.backend.dao.FeedEntryDAO;
|
import com.commafeed.backend.dao.FeedEntryDAO;
|
||||||
@@ -29,6 +28,7 @@ import com.commafeed.backend.model.User;
|
|||||||
import com.commafeed.backend.model.UserSettings;
|
import com.commafeed.backend.model.UserSettings;
|
||||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||||
import com.commafeed.backend.services.MailService;
|
import com.commafeed.backend.services.MailService;
|
||||||
|
import com.commafeed.backend.startup.StartupBean;
|
||||||
import com.commafeed.frontend.CommaFeedSession;
|
import com.commafeed.frontend.CommaFeedSession;
|
||||||
import com.commafeed.frontend.utils.WicketUtils;
|
import com.commafeed.frontend.utils.WicketUtils;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import org.apache.wicket.markup.html.WebPage;
|
import org.apache.wicket.markup.html.WebPage;
|
||||||
|
|
||||||
import com.commafeed.backend.StartupBean;
|
|
||||||
import com.commafeed.backend.services.UserService;
|
import com.commafeed.backend.services.UserService;
|
||||||
|
import com.commafeed.backend.startup.StartupBean;
|
||||||
import com.commafeed.frontend.CommaFeedSession;
|
import com.commafeed.frontend.CommaFeedSession;
|
||||||
|
|
||||||
public class DemoLoginPage extends WebPage {
|
public class DemoLoginPage extends WebPage {
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import org.apache.wicket.protocol.http.servlet.ServletWebResponse;
|
|||||||
import org.apache.wicket.request.cycle.RequestCycle;
|
import org.apache.wicket.request.cycle.RequestCycle;
|
||||||
import org.apache.wicket.util.crypt.Base64;
|
import org.apache.wicket.util.crypt.Base64;
|
||||||
|
|
||||||
|
import com.codahale.metrics.Meter;
|
||||||
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import com.commafeed.backend.dao.UserDAO;
|
import com.commafeed.backend.dao.UserDAO;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
import com.commafeed.backend.model.UserRole.Role;
|
import com.commafeed.backend.model.UserRole.Role;
|
||||||
@@ -42,6 +44,9 @@ public abstract class AbstractREST {
|
|||||||
@Context
|
@Context
|
||||||
private HttpServletResponse response;
|
private HttpServletResponse response;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MetricRegistry metrics;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserDAO userDAO;
|
private UserDAO userDAO;
|
||||||
|
|
||||||
@@ -93,10 +98,14 @@ public abstract class AbstractREST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AroundInvoke
|
@AroundInvoke
|
||||||
public Object checkSecurity(InvocationContext context) throws Exception {
|
public Object intercept(InvocationContext context) throws Exception {
|
||||||
|
Method method = context.getMethod();
|
||||||
|
handleMetric(method);
|
||||||
|
|
||||||
|
// check security
|
||||||
boolean allowed = true;
|
boolean allowed = true;
|
||||||
User user = null;
|
User user = null;
|
||||||
Method method = context.getMethod();
|
|
||||||
SecurityCheck check = method.isAnnotationPresent(SecurityCheck.class) ? method.getAnnotation(SecurityCheck.class) : method
|
SecurityCheck check = method.isAnnotationPresent(SecurityCheck.class) ? method.getAnnotation(SecurityCheck.class) : method
|
||||||
.getDeclaringClass().getAnnotation(SecurityCheck.class);
|
.getDeclaringClass().getAnnotation(SecurityCheck.class);
|
||||||
|
|
||||||
@@ -121,6 +130,11 @@ public abstract class AbstractREST {
|
|||||||
return context.proceed();
|
return context.proceed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleMetric(Method method) {
|
||||||
|
Meter callCount = metrics.meter(MetricRegistry.name(method.getDeclaringClass(), method.getName(), "callCount"));
|
||||||
|
callCount.mark();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkRole(Role requiredRole) {
|
private boolean checkRole(Role requiredRole) {
|
||||||
if (requiredRole == Role.NONE) {
|
if (requiredRole == Role.NONE) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ import javax.ws.rs.core.Response.Status;
|
|||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import com.commafeed.backend.DatabaseCleaner;
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import com.commafeed.backend.MetricsBean;
|
|
||||||
import com.commafeed.backend.StartupBean;
|
|
||||||
import com.commafeed.backend.dao.FeedDAO;
|
import com.commafeed.backend.dao.FeedDAO;
|
||||||
import com.commafeed.backend.dao.FeedDAO.DuplicateMode;
|
import com.commafeed.backend.dao.FeedDAO.DuplicateMode;
|
||||||
import com.commafeed.backend.dao.UserDAO;
|
import com.commafeed.backend.dao.UserDAO;
|
||||||
@@ -33,14 +31,17 @@ import com.commafeed.backend.model.User;
|
|||||||
import com.commafeed.backend.model.UserRole;
|
import com.commafeed.backend.model.UserRole;
|
||||||
import com.commafeed.backend.model.UserRole.Role;
|
import com.commafeed.backend.model.UserRole.Role;
|
||||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||||
|
import com.commafeed.backend.services.DatabaseCleaningService;
|
||||||
import com.commafeed.backend.services.FeedService;
|
import com.commafeed.backend.services.FeedService;
|
||||||
import com.commafeed.backend.services.PasswordEncryptionService;
|
import com.commafeed.backend.services.PasswordEncryptionService;
|
||||||
import com.commafeed.backend.services.UserService;
|
import com.commafeed.backend.services.UserService;
|
||||||
|
import com.commafeed.backend.startup.StartupBean;
|
||||||
import com.commafeed.frontend.SecurityCheck;
|
import com.commafeed.frontend.SecurityCheck;
|
||||||
import com.commafeed.frontend.model.FeedCount;
|
import com.commafeed.frontend.model.FeedCount;
|
||||||
import com.commafeed.frontend.model.UserModel;
|
import com.commafeed.frontend.model.UserModel;
|
||||||
import com.commafeed.frontend.model.request.FeedMergeRequest;
|
import com.commafeed.frontend.model.request.FeedMergeRequest;
|
||||||
import com.commafeed.frontend.model.request.IDRequest;
|
import com.commafeed.frontend.model.request.IDRequest;
|
||||||
|
import com.commafeed.frontend.rest.PrettyPrint;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
@@ -70,10 +71,10 @@ public class AdminREST extends AbstractREST {
|
|||||||
FeedDAO feedDAO;
|
FeedDAO feedDAO;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
MetricsBean metricsBean;
|
MetricRegistry metrics;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DatabaseCleaner cleaner;
|
DatabaseCleaningService cleaner;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
FeedRefreshWorker feedRefreshWorker;
|
FeedRefreshWorker feedRefreshWorker;
|
||||||
@@ -227,20 +228,8 @@ public class AdminREST extends AbstractREST {
|
|||||||
@Path("/metrics")
|
@Path("/metrics")
|
||||||
@GET
|
@GET
|
||||||
@ApiOperation(value = "Retrieve server metrics")
|
@ApiOperation(value = "Retrieve server metrics")
|
||||||
public Response getMetrics(@QueryParam("backlog") @DefaultValue("false") boolean backlog) {
|
public Response getMetrics() {
|
||||||
Map<String, Object> map = Maps.newLinkedHashMap();
|
return Response.ok(metrics).build();
|
||||||
map.put("lastMinute", metricsBean.getLastMinute());
|
|
||||||
map.put("lastHour", metricsBean.getLastHour());
|
|
||||||
if (backlog) {
|
|
||||||
map.put("backlog", taskGiver.getUpdatableCount());
|
|
||||||
}
|
|
||||||
map.put("http_active", feedRefreshWorker.getActiveCount());
|
|
||||||
map.put("http_queue", feedRefreshWorker.getQueueSize());
|
|
||||||
map.put("database_active", feedRefreshUpdater.getActiveCount());
|
|
||||||
map.put("database_queue", feedRefreshUpdater.getQueueSize());
|
|
||||||
map.put("cache", metricsBean.getCacheStats());
|
|
||||||
|
|
||||||
return Response.ok(map).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Path("/cleanup/feeds")
|
@Path("/cleanup/feeds")
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.apache.commons.io.IOUtils;
|
|||||||
import org.apache.commons.lang.ObjectUtils;
|
import org.apache.commons.lang.ObjectUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import com.commafeed.backend.StartupBean;
|
|
||||||
import com.commafeed.backend.cache.CacheService;
|
import com.commafeed.backend.cache.CacheService;
|
||||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||||
import com.commafeed.backend.dao.FeedEntryStatusDAO;
|
import com.commafeed.backend.dao.FeedEntryStatusDAO;
|
||||||
@@ -47,8 +46,6 @@ import com.commafeed.backend.feeds.FeedFetcher;
|
|||||||
import com.commafeed.backend.feeds.FeedRefreshTaskGiver;
|
import com.commafeed.backend.feeds.FeedRefreshTaskGiver;
|
||||||
import com.commafeed.backend.feeds.FeedUtils;
|
import com.commafeed.backend.feeds.FeedUtils;
|
||||||
import com.commafeed.backend.feeds.FetchedFeed;
|
import com.commafeed.backend.feeds.FetchedFeed;
|
||||||
import com.commafeed.backend.feeds.OPMLExporter;
|
|
||||||
import com.commafeed.backend.feeds.OPMLImporter;
|
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
import com.commafeed.backend.model.FeedCategory;
|
import com.commafeed.backend.model.FeedCategory;
|
||||||
import com.commafeed.backend.model.FeedEntryStatus;
|
import com.commafeed.backend.model.FeedEntryStatus;
|
||||||
@@ -56,9 +53,12 @@ import com.commafeed.backend.model.FeedSubscription;
|
|||||||
import com.commafeed.backend.model.UserRole.Role;
|
import com.commafeed.backend.model.UserRole.Role;
|
||||||
import com.commafeed.backend.model.UserSettings.ReadingMode;
|
import com.commafeed.backend.model.UserSettings.ReadingMode;
|
||||||
import com.commafeed.backend.model.UserSettings.ReadingOrder;
|
import com.commafeed.backend.model.UserSettings.ReadingOrder;
|
||||||
|
import com.commafeed.backend.opml.OPMLExporter;
|
||||||
|
import com.commafeed.backend.opml.OPMLImporter;
|
||||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||||
import com.commafeed.backend.services.FeedEntryService;
|
import com.commafeed.backend.services.FeedEntryService;
|
||||||
import com.commafeed.backend.services.FeedSubscriptionService;
|
import com.commafeed.backend.services.FeedSubscriptionService;
|
||||||
|
import com.commafeed.backend.startup.StartupBean;
|
||||||
import com.commafeed.frontend.SecurityCheck;
|
import com.commafeed.frontend.SecurityCheck;
|
||||||
import com.commafeed.frontend.model.Entries;
|
import com.commafeed.frontend.model.Entries;
|
||||||
import com.commafeed.frontend.model.Entry;
|
import com.commafeed.frontend.model.Entry;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.commafeed.frontend.rest.resources;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
@@ -22,7 +23,8 @@ import org.apache.commons.io.IOUtils;
|
|||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.commafeed.backend.MetricsBean;
|
import com.codahale.metrics.Meter;
|
||||||
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import com.commafeed.backend.dao.FeedDAO;
|
import com.commafeed.backend.dao.FeedDAO;
|
||||||
import com.commafeed.backend.feeds.FeedParser;
|
import com.commafeed.backend.feeds.FeedParser;
|
||||||
import com.commafeed.backend.feeds.FeedRefreshTaskGiver;
|
import com.commafeed.backend.feeds.FeedRefreshTaskGiver;
|
||||||
@@ -52,8 +54,13 @@ public class PubSubHubbubCallbackREST extends AbstractREST {
|
|||||||
@Inject
|
@Inject
|
||||||
ApplicationSettingsService applicationSettingsService;
|
ApplicationSettingsService applicationSettingsService;
|
||||||
|
|
||||||
@Inject
|
private Meter pushReceived;
|
||||||
MetricsBean metricsBean;
|
|
||||||
|
@PostConstruct
|
||||||
|
public void initMetrics() {
|
||||||
|
pushReceived = metrics.meter(MetricRegistry.name(getClass(), "pushReceived"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Path("/callback")
|
@Path("/callback")
|
||||||
@GET
|
@GET
|
||||||
@@ -119,7 +126,7 @@ public class PubSubHubbubCallbackREST extends AbstractREST {
|
|||||||
log.debug("pushing content to queue for {}", feed.getUrl());
|
log.debug("pushing content to queue for {}", feed.getUrl());
|
||||||
taskGiver.add(feed, false);
|
taskGiver.add(feed, false);
|
||||||
}
|
}
|
||||||
metricsBean.pushReceived(feeds.size());
|
pushReceived.mark();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Could not parse pubsub callback: " + e.getMessage());
|
log.error("Could not parse pubsub callback: " + e.getMessage());
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ import javax.ws.rs.core.Response.Status;
|
|||||||
|
|
||||||
import com.commafeed.backend.HttpGetter;
|
import com.commafeed.backend.HttpGetter;
|
||||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||||
import com.commafeed.backend.StartupBean;
|
|
||||||
import com.commafeed.backend.feeds.FeedUtils;
|
import com.commafeed.backend.feeds.FeedUtils;
|
||||||
import com.commafeed.backend.services.ApplicationPropertiesService;
|
import com.commafeed.backend.services.ApplicationPropertiesService;
|
||||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||||
|
import com.commafeed.backend.startup.StartupBean;
|
||||||
import com.commafeed.frontend.model.ServerInfo;
|
import com.commafeed.frontend.model.ServerInfo;
|
||||||
import com.wordnik.swagger.annotations.Api;
|
import com.wordnik.swagger.annotations.Api;
|
||||||
import com.wordnik.swagger.annotations.ApiOperation;
|
import com.wordnik.swagger.annotations.ApiOperation;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import javax.ws.rs.core.Response.Status;
|
|||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import com.commafeed.backend.StartupBean;
|
|
||||||
import com.commafeed.backend.dao.UserDAO;
|
import com.commafeed.backend.dao.UserDAO;
|
||||||
import com.commafeed.backend.dao.UserRoleDAO;
|
import com.commafeed.backend.dao.UserRoleDAO;
|
||||||
import com.commafeed.backend.dao.UserSettingsDAO;
|
import com.commafeed.backend.dao.UserSettingsDAO;
|
||||||
@@ -25,6 +24,7 @@ import com.commafeed.backend.model.UserSettings.ViewMode;
|
|||||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||||
import com.commafeed.backend.services.PasswordEncryptionService;
|
import com.commafeed.backend.services.PasswordEncryptionService;
|
||||||
import com.commafeed.backend.services.UserService;
|
import com.commafeed.backend.services.UserService;
|
||||||
|
import com.commafeed.backend.startup.StartupBean;
|
||||||
import com.commafeed.frontend.SecurityCheck;
|
import com.commafeed.frontend.SecurityCheck;
|
||||||
import com.commafeed.frontend.model.Settings;
|
import com.commafeed.frontend.model.Settings;
|
||||||
import com.commafeed.frontend.model.UserModel;
|
import com.commafeed.frontend.model.UserModel;
|
||||||
|
|||||||
Reference in New Issue
Block a user