Add dinosaur wet metrics
This commit is contained in:
@@ -27,12 +27,14 @@
|
|||||||
"@nestjs/jwt": "^10.1.1",
|
"@nestjs/jwt": "^10.1.1",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
"@nestjs/swagger": "^7.1.11",
|
"@nestjs/swagger": "^7.1.11",
|
||||||
|
"@willsoto/nestjs-prometheus": "^6.0.0",
|
||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"cache-manager": "^5.2.3",
|
"cache-manager": "^5.2.3",
|
||||||
"hbs": "^4.2.0",
|
"hbs": "^4.2.0",
|
||||||
"minio": "^7.1.3",
|
"minio": "^7.1.3",
|
||||||
"open-graph-scraper": "^6.3.0",
|
"open-graph-scraper": "^6.3.0",
|
||||||
|
"prom-client": "^15.0.0",
|
||||||
"ramda": "^0.29.0",
|
"ramda": "^0.29.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
|
@@ -13,6 +13,7 @@ import { IrcbotModule } from './ircbot/ircbot.module';
|
|||||||
import { IrcbotService } from './ircbot/ircbot.service';
|
import { IrcbotService } from './ircbot/ircbot.service';
|
||||||
import { DinosaurwetModule } from './dinosaurwet/dinosaurwet.module';
|
import { DinosaurwetModule } from './dinosaurwet/dinosaurwet.module';
|
||||||
import { OgScraperModule } from './ogscraper/ogscraper.module';
|
import { OgScraperModule } from './ogscraper/ogscraper.module';
|
||||||
|
import { PrometheusModule } from '@willsoto/nestjs-prometheus';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -20,6 +21,11 @@ import { OgScraperModule } from './ogscraper/ogscraper.module';
|
|||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
load: [configuration],
|
load: [configuration],
|
||||||
}),
|
}),
|
||||||
|
PrometheusModule.register({
|
||||||
|
defaultLabels: {
|
||||||
|
app: 'us.dev api',
|
||||||
|
},
|
||||||
|
}),
|
||||||
CacheModule.register({ isGlobal: true }),
|
CacheModule.register({ isGlobal: true }),
|
||||||
ParkioModule,
|
ParkioModule,
|
||||||
IswordModule,
|
IswordModule,
|
||||||
|
@@ -10,8 +10,9 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { AuthGuard } from './auth.guard';
|
import { AuthGuard } from './auth.guard';
|
||||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
@ApiTags('auth')
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(private authService: AuthService) {}
|
constructor(private authService: AuthService) {}
|
||||||
@@ -24,8 +25,8 @@ export class AuthController {
|
|||||||
|
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
@Post('hash')
|
@Post('hash')
|
||||||
hash(@Body() hashDto: {pass: string, rounds?: number}) {
|
hash(@Body() hashDto: { pass: string; rounds?: number }) {
|
||||||
return this.authService.hash(hashDto.pass, hashDto.rounds)
|
return this.authService.hash(hashDto.pass, hashDto.rounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
|
@@ -2,6 +2,9 @@ import { Controller, Get, Res } from '@nestjs/common';
|
|||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { identity, prop } from 'ramda';
|
import { identity, prop } from 'ramda';
|
||||||
import * as xml from 'xml';
|
import * as xml from 'xml';
|
||||||
|
import { InjectMetric } from '@willsoto/nestjs-prometheus';
|
||||||
|
import { Gauge } from 'prom-client';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
const episodeFiles: [number, string][] = [
|
const episodeFiles: [number, string][] = [
|
||||||
[27544345, '01-Into-the-Big-Wet.mp3'],
|
[27544345, '01-Into-the-Big-Wet.mp3'],
|
||||||
@@ -60,6 +63,34 @@ const buildFeeds = (
|
|||||||
episodes: Episode[],
|
episodes: Episode[],
|
||||||
pubDateFn: (index: number) => Date = () => startDate,
|
pubDateFn: (index: number) => Date = () => startDate,
|
||||||
) => {
|
) => {
|
||||||
|
const episodeItems = episodes
|
||||||
|
.filter((episode: Episode, index: number) => pubDateFn(index) <= new Date())
|
||||||
|
.map(({ title, url, length, fakeReleaseDate }, index) => ({
|
||||||
|
item: [
|
||||||
|
{ title },
|
||||||
|
{ guid: url },
|
||||||
|
{ pubDate: pubDateFn(index).toUTCString() },
|
||||||
|
{
|
||||||
|
'itunes:image': {
|
||||||
|
_attr: {
|
||||||
|
href: dinosaurImage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ 'itunes:episode': index + 1 },
|
||||||
|
{
|
||||||
|
enclosure: [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
url,
|
||||||
|
type: 'audio/mpeg',
|
||||||
|
length,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}));
|
||||||
const feedObject = {
|
const feedObject = {
|
||||||
rss: [
|
rss: [
|
||||||
{
|
{
|
||||||
@@ -100,48 +131,24 @@ const buildFeeds = (
|
|||||||
'A recreation of Dinosaur Wet as an RSS feed for listeners-with-licenses enjoyment.',
|
'A recreation of Dinosaur Wet as an RSS feed for listeners-with-licenses enjoyment.',
|
||||||
},
|
},
|
||||||
{ language: 'en-US' },
|
{ language: 'en-US' },
|
||||||
...episodes
|
...episodeItems,
|
||||||
.filter(
|
|
||||||
(episode: Episode, index: number) =>
|
|
||||||
pubDateFn(index) <= new Date(),
|
|
||||||
)
|
|
||||||
.map(({ title, url, length, fakeReleaseDate }, index) => ({
|
|
||||||
item: [
|
|
||||||
{ title },
|
|
||||||
{ guid: url },
|
|
||||||
{ pubDate: pubDateFn(index).toUTCString() },
|
|
||||||
{
|
|
||||||
'itunes:image': {
|
|
||||||
_attr: {
|
|
||||||
href: dinosaurImage,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ 'itunes:episode': index + 1 },
|
|
||||||
{
|
|
||||||
enclosure: [
|
|
||||||
{
|
|
||||||
_attr: {
|
|
||||||
url,
|
|
||||||
type: 'audio/mpeg',
|
|
||||||
length,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})),
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const feed = '<?xml version="1.0" encoding="UTF-8"?>' + xml(feedObject);
|
const feed = '<?xml version="1.0" encoding="UTF-8"?>' + xml(feedObject);
|
||||||
return feed;
|
return { feed, episodeItems };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ApiTags('dinosaurwet')
|
||||||
@Controller('dinosaurwet')
|
@Controller('dinosaurwet')
|
||||||
export class DinosaurwetController {
|
export class DinosaurwetController {
|
||||||
|
constructor(
|
||||||
|
@InjectMetric('weekly_count') public weeklyCount: Gauge<string>,
|
||||||
|
@InjectMetric('daily_count') public dailyCount: Gauge<string>,
|
||||||
|
) {}
|
||||||
|
|
||||||
@Get('')
|
@Get('')
|
||||||
getAllAtOnce(@Res() response: Response) {
|
getAllAtOnce(@Res() response: Response) {
|
||||||
response.header('Content-Type', 'application/xml');
|
response.header('Content-Type', 'application/xml');
|
||||||
@@ -158,7 +165,8 @@ export class DinosaurwetController {
|
|||||||
(index: number) =>
|
(index: number) =>
|
||||||
new Date(new Date(startDate).setDate(startDate.getDate() + index)),
|
new Date(new Date(startDate).setDate(startDate.getDate() + index)),
|
||||||
);
|
);
|
||||||
return response.send(feed);
|
this.dailyCount.set(feed.episodeItems.length);
|
||||||
|
return response.send(feed.feed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('weekly')
|
@Get('weekly')
|
||||||
@@ -170,6 +178,7 @@ export class DinosaurwetController {
|
|||||||
(index: number) =>
|
(index: number) =>
|
||||||
new Date(new Date(startDate).setDate(startDate.getDate() + index * 7)),
|
new Date(new Date(startDate).setDate(startDate.getDate() + index * 7)),
|
||||||
);
|
);
|
||||||
return response.send(feed);
|
this.weeklyCount.set(feed.episodeItems.length);
|
||||||
|
return response.send(feed.feed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,29 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { DinosaurwetController } from './dinosaurwet.controller';
|
import { DinosaurwetController } from './dinosaurwet.controller';
|
||||||
|
import {
|
||||||
|
PrometheusModule,
|
||||||
|
makeGaugeProvider,
|
||||||
|
} from '@willsoto/nestjs-prometheus';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
controllers: [DinosaurwetController]
|
imports: [
|
||||||
|
PrometheusModule.register({
|
||||||
|
customMetricPrefix: 'dinosaurwet',
|
||||||
|
defaultMetrics: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
controllers: [DinosaurwetController],
|
||||||
|
providers: [
|
||||||
|
makeGaugeProvider({
|
||||||
|
name: 'daily_count',
|
||||||
|
help: 'The current daily Dinosaur Wet episode count',
|
||||||
|
}),
|
||||||
|
makeGaugeProvider({
|
||||||
|
name: 'weekly_count',
|
||||||
|
help: 'The current weekly Dinosaur Wet episode count',
|
||||||
|
}),
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class DinosaurwetModule {}
|
export class DinosaurwetModule {}
|
||||||
|
30
yarn.lock
30
yarn.lock
@@ -849,6 +849,11 @@
|
|||||||
consola "^2.15.0"
|
consola "^2.15.0"
|
||||||
node-fetch "^2.6.1"
|
node-fetch "^2.6.1"
|
||||||
|
|
||||||
|
"@opentelemetry/api@^1.4.0":
|
||||||
|
version "1.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.6.0.tgz#de2c6823203d6f319511898bb5de7e70f5267e19"
|
||||||
|
integrity sha512-OWlrQAnWn9577PhVgqjUvMr1pg57Bc4jv0iL4w0PRuOSRvq67rvHW9Ie/dZVMvCzhSCB+UxhcY/PmCmFj33Q+g==
|
||||||
|
|
||||||
"@pkgr/utils@^2.3.1":
|
"@pkgr/utils@^2.3.1":
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc"
|
resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc"
|
||||||
@@ -1370,6 +1375,11 @@
|
|||||||
"@webassemblyjs/ast" "1.11.6"
|
"@webassemblyjs/ast" "1.11.6"
|
||||||
"@xtuc/long" "4.2.2"
|
"@xtuc/long" "4.2.2"
|
||||||
|
|
||||||
|
"@willsoto/nestjs-prometheus@^6.0.0":
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@willsoto/nestjs-prometheus/-/nestjs-prometheus-6.0.0.tgz#6ef4d5d5dfb04ebe982aab6f3a7893974e89a669"
|
||||||
|
integrity sha512-Krmda5CT9xDPjab8Eqdqiwi7xkZSX60A5rEGVLEDjUG6J6Rw5SCZ/BPaRk+MxNGWzUrRkM7K5FtTg38vWIOt1Q==
|
||||||
|
|
||||||
"@xtuc/ieee754@^1.2.0":
|
"@xtuc/ieee754@^1.2.0":
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||||
@@ -1668,6 +1678,11 @@ binary-extensions@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||||
|
|
||||||
|
bintrees@1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.2.tgz#49f896d6e858a4a499df85c38fb399b9aff840f8"
|
||||||
|
integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==
|
||||||
|
|
||||||
bl@^4.1.0:
|
bl@^4.1.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
|
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
|
||||||
@@ -4621,6 +4636,14 @@ process-nextick-args@~2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||||
|
|
||||||
|
prom-client@^15.0.0:
|
||||||
|
version "15.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-15.0.0.tgz#067da874a2aa5d2e21bd5cdba9f24a8178bdab6a"
|
||||||
|
integrity sha512-UocpgIrKyA2TKLVZDSfm8rGkL13C19YrQBAiG3xo3aDFWcHedxRxI3z+cIcucoxpSO0h5lff5iv/SXoxyeopeA==
|
||||||
|
dependencies:
|
||||||
|
"@opentelemetry/api" "^1.4.0"
|
||||||
|
tdigest "^0.1.1"
|
||||||
|
|
||||||
prompts@^2.0.1:
|
prompts@^2.0.1:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
|
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
|
||||||
@@ -5230,6 +5253,13 @@ tar@^6.1.11:
|
|||||||
mkdirp "^1.0.3"
|
mkdirp "^1.0.3"
|
||||||
yallist "^4.0.0"
|
yallist "^4.0.0"
|
||||||
|
|
||||||
|
tdigest@^0.1.1:
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.2.tgz#96c64bac4ff10746b910b0e23b515794e12faced"
|
||||||
|
integrity sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==
|
||||||
|
dependencies:
|
||||||
|
bintrees "1.0.2"
|
||||||
|
|
||||||
terser-webpack-plugin@^5.3.7:
|
terser-webpack-plugin@^5.3.7:
|
||||||
version "5.3.9"
|
version "5.3.9"
|
||||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1"
|
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1"
|
||||||
|
Reference in New Issue
Block a user