mirror of
https://github.com/matrix-org/matrix-hookshot.git
synced 2025-03-10 21:19:13 +00:00
Add feeds failing metric (#681)
* Track failing feeds in a metric * Update docs * changelog
This commit is contained in:
parent
05b23127d8
commit
d12a05d0fa
1
changelog.d/681.misc
Normal file
1
changelog.d/681.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add `feed_failing` metric to track the number of feeds failing to be read or parsed.
|
@ -43,6 +43,7 @@ Below is the generated list of Prometheus metrics for Hookshot.
|
|||||||
|--------|------|--------|
|
|--------|------|--------|
|
||||||
| feed_count | The number of RSS feeds that hookshot is subscribed to | |
|
| feed_count | The number of RSS feeds that hookshot is subscribed to | |
|
||||||
| feed_fetch_ms | The time taken for hookshot to fetch all feeds | |
|
| feed_fetch_ms | The time taken for hookshot to fetch all feeds | |
|
||||||
|
| feed_failing | The number of RSS feeds that hookshot is failing to read | reason |
|
||||||
## process
|
## process
|
||||||
| Metric | Help | Labels |
|
| Metric | Help | Labels |
|
||||||
|--------|------|--------|
|
|--------|------|--------|
|
||||||
|
@ -26,6 +26,7 @@ export class Metrics {
|
|||||||
|
|
||||||
public readonly feedsCount = new Gauge({ name: "feed_count", help: "The number of RSS feeds that hookshot is subscribed to", labelNames: [], registers: [this.registry]});
|
public readonly feedsCount = new Gauge({ name: "feed_count", help: "The number of RSS feeds that hookshot is subscribed to", labelNames: [], registers: [this.registry]});
|
||||||
public readonly feedFetchMs = new Gauge({ name: "feed_fetch_ms", help: "The time taken for hookshot to fetch all feeds", labelNames: [], registers: [this.registry]});
|
public readonly feedFetchMs = new Gauge({ name: "feed_fetch_ms", help: "The time taken for hookshot to fetch all feeds", labelNames: [], registers: [this.registry]});
|
||||||
|
public readonly feedsFailing = new Gauge({ name: "feed_failing", help: "The number of RSS feeds that hookshot is failing to read", labelNames: ["reason"], registers: [this.registry]});
|
||||||
|
|
||||||
|
|
||||||
constructor(private registry: Registry = register) {
|
constructor(private registry: Registry = register) {
|
||||||
|
@ -104,6 +104,11 @@ export class FeedReader {
|
|||||||
private seenEntries: Map<string, string[]> = new Map();
|
private seenEntries: Map<string, string[]> = new Map();
|
||||||
// A set of last modified times for each url.
|
// A set of last modified times for each url.
|
||||||
private cacheTimes: Map<string, { etag?: string, lastModified?: string}> = new Map();
|
private cacheTimes: Map<string, { etag?: string, lastModified?: string}> = new Map();
|
||||||
|
|
||||||
|
// Reason failures to url map.
|
||||||
|
private feedsFailingHttp = new Set();
|
||||||
|
private feedsFailingParsing = new Set();
|
||||||
|
|
||||||
static readonly seenEntriesEventType = "uk.half-shot.matrix-hookshot.feed.reader.seenEntries";
|
static readonly seenEntriesEventType = "uk.half-shot.matrix-hookshot.feed.reader.seenEntries";
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -199,6 +204,8 @@ export class FeedReader {
|
|||||||
// We don't want to wait forever for the feed.
|
// We don't want to wait forever for the feed.
|
||||||
timeout: this.config.pollTimeoutSeconds * 1000,
|
timeout: this.config.pollTimeoutSeconds * 1000,
|
||||||
});
|
});
|
||||||
|
// Clear any HTTP failures
|
||||||
|
this.feedsFailingHttp.delete(url);
|
||||||
|
|
||||||
// Store any entity tags/cache times.
|
// Store any entity tags/cache times.
|
||||||
if (res.headers.ETag) {
|
if (res.headers.ETag) {
|
||||||
@ -208,6 +215,8 @@ export class FeedReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const feed = await this.parser.parseString(res.data);
|
const feed = await this.parser.parseString(res.data);
|
||||||
|
this.feedsFailingParsing.delete(url);
|
||||||
|
|
||||||
let initialSync = false;
|
let initialSync = false;
|
||||||
let seenGuids = this.seenEntries.get(url);
|
let seenGuids = this.seenEntries.get(url);
|
||||||
if (!seenGuids) {
|
if (!seenGuids) {
|
||||||
@ -268,6 +277,9 @@ export class FeedReader {
|
|||||||
if (err.response?.status === StatusCodes.NOT_MODIFIED) {
|
if (err.response?.status === StatusCodes.NOT_MODIFIED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
this.feedsFailingHttp.add(url);
|
||||||
|
} else {
|
||||||
|
this.feedsFailingParsing.add(url);
|
||||||
}
|
}
|
||||||
const error = err instanceof Error ? err : new Error(`Unknown error ${err}`);
|
const error = err instanceof Error ? err : new Error(`Unknown error ${err}`);
|
||||||
const feedError = new FeedError(url.toString(), error, fetchKey);
|
const feedError = new FeedError(url.toString(), error, fetchKey);
|
||||||
@ -275,6 +287,10 @@ export class FeedReader {
|
|||||||
this.queue.push<FeedError>({ eventName: 'feed.error', sender: 'FeedReader', data: feedError});
|
this.queue.push<FeedError>({ eventName: 'feed.error', sender: 'FeedReader', data: feedError});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Metrics.feedsFailing.set({ reason: "http" }, this.feedsFailingHttp.size );
|
||||||
|
Metrics.feedsFailing.set({ reason: "parsing" }, this.feedsFailingParsing.size);
|
||||||
|
|
||||||
if (seenEntriesChanged) await this.saveSeenEntries();
|
if (seenEntriesChanged) await this.saveSeenEntries();
|
||||||
|
|
||||||
const elapsed = Date.now() - fetchingStarted;
|
const elapsed = Date.now() - fetchingStarted;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user