data endpoint for entity 90008 (aka. a website)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add metrics for fake and real visits

dusk 5b517c06 985bc052

+63 -15
+3 -1
src/hooks.server.ts
··· 3 3 import { steamUpdateNowPlaying } from '$lib/steam'; 4 4 import { updateCommits } from '$lib/activity'; 5 5 import { cancelJob, scheduleJob, scheduledJobs } from 'node-schedule'; 6 + import { sendAllMetrics } from '$lib/metrics'; 6 7 7 8 const UPDATE_LAST_JOB_NAME = 'update steam game, lastfm track, bsky posts, git activity'; 8 9 ··· 19 20 steamUpdateNowPlaying(), 20 21 lastFmUpdateNowPlaying(), 21 22 updateLastPosts(), 22 - updateCommits() 23 + updateCommits(), 24 + sendAllMetrics() // send all metrics every minute 23 25 ]); 24 26 } catch (err) { 25 27 console.log(`error while running ${UPDATE_LAST_JOB_NAME} job: ${err}`);
+56 -14
src/lib/metrics.ts
··· 3 3 import { pushMetrics } from 'prometheus-remote-write'; 4 4 import { get, writable } from 'svelte/store'; 5 5 6 - export const pushMetric = async (metrics: Record<string, number>) => { 6 + export const pushMetric = async ( 7 + metrics: Record<string, number>, 8 + labels: Record<string, string> = {} 9 + ) => { 7 10 const result = await pushMetrics(metrics, { 8 11 url: env.PROMETHEUS_URL, 9 12 labels: { 10 - service: 'website' 13 + service: 'website', 14 + ...labels 11 15 } 12 16 }); 13 17 if (result.status != 204) { ··· 15 19 } 16 20 }; 17 21 18 - const bounceCountFile = `${env.WEBSITE_DATA_DIR}/bouncecount`; 19 - const bounceCount = writable( 20 - parseInt(existsSync(bounceCountFile) ? readFileSync(bounceCountFile).toString() : '0') 21 - ); 22 + export const sendAllMetrics = async () => { 23 + try { 24 + await pushMetric({ 25 + gazesys_pet_bounce_total: bounceCount.get(), 26 + gazesys_visit_fake_total: fakeVisitCount.get(), 27 + gazesys_visit_real_total: legitVisitCount.get() 28 + }); 29 + } catch (error) { 30 + console.log(`failed to push metrics: ${error}`); 31 + } 32 + }; 22 33 23 - export const incrementBounceCount = () => { 24 - let currentBounceCount = get(bounceCount); 25 - // increment current and write to the store 26 - currentBounceCount += 1; 27 - bounceCount.set(currentBounceCount); 28 - // write the bounce count to a file so we can load it later again 29 - writeFileSync(bounceCountFile, currentBounceCount.toString()); 30 - return currentBounceCount; 34 + /** 35 + * Creates a persistent counter that is stored in a file 36 + * @param fileName The name of the file to store the count in 37 + * @param initialValue The initial value if the file doesn't exist 38 + * @returns An object with methods to get, increment, and set the count 39 + */ 40 + export const createFileCounter = (fileName: string, initialValue: number = 0) => { 41 + const filePath = `${env.WEBSITE_DATA_DIR}/${fileName}`; 42 + const counter = writable( 43 + parseInt(existsSync(filePath) ? readFileSync(filePath).toString() : initialValue.toString()) 44 + ); 45 + 46 + const saveToFile = (value: number) => { 47 + writeFileSync(filePath, value.toString()); 48 + return value; 49 + }; 50 + 51 + return { 52 + get: () => get(counter), 53 + increment: (amount: number = 1) => { 54 + const currentValue = get(counter) + amount; 55 + counter.set(currentValue); 56 + return saveToFile(currentValue); 57 + }, 58 + set: (value: number) => { 59 + counter.set(value); 60 + return saveToFile(value); 61 + }, 62 + subscribe: counter.subscribe 63 + }; 31 64 }; 65 + 66 + export const bounceCount = createFileCounter('bouncecount'); 67 + export const incrementBounceCount = bounceCount.increment; 68 + 69 + export const legitVisitCount = createFileCounter('legitvisitcount'); 70 + export const incrementLegitVisitCount = legitVisitCount.increment; 71 + 72 + export const fakeVisitCount = createFileCounter('fakevisitcount'); 73 + export const incrementFakeVisitCount = fakeVisitCount.increment;
+4
src/routes/+layout.server.ts
··· 1 + import { incrementFakeVisitCount, incrementLegitVisitCount, pushMetric } from '$lib/metrics.js'; 1 2 import { testUa } from '$lib/robots.js'; 2 3 import { addLastVisitor, incrementVisitCount, notifyDarkVisitors } from '$lib/visits.js'; 3 4 import { error } from '@sveltejs/kit'; ··· 12 13 13 14 // block any requests if the user agent is disallowed by our robots txt 14 15 if ((await testUa(url.toString(), request.headers.get('user-agent') ?? '')) === false) { 16 + pushMetric({ gazesys_visit_fake_total: incrementFakeVisitCount() }); 15 17 throw error(403, 'get a better user agent silly'); 18 + } else { 19 + pushMetric({ gazesys_visit_real_total: incrementLegitVisitCount() }); 16 20 } 17 21 18 22 const lastVisitors = addLastVisitor(request, cookies);