fix(public): remove db dependencies and use traditional api call to get stats

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-02-27 00:07:25 +01:00
parent 9d43cc49c4
commit d6f5bb7833
9 changed files with 55 additions and 53 deletions

View File

@@ -5,8 +5,8 @@ import icoToPng from 'ico-to-png';
import sharp from 'sharp';
import { createHash } from '@openpanel/common/server';
import { TABLE_NAMES, ch, formatClickhouseDate } from '@openpanel/db';
import { getRedisCache } from '@openpanel/redis';
import { TABLE_NAMES, ch, chQuery, formatClickhouseDate } from '@openpanel/db';
import { cacheable, getCache, getRedisCache } from '@openpanel/redis';
interface GetFaviconParams {
url: string;
@@ -152,3 +152,21 @@ export async function ping(
});
}
}
export async function stats(request: FastifyRequest, reply: FastifyReply) {
const res = await getCache('api:stats', 60 * 60, async () => {
const projects = await chQuery<{ project_id: string; count: number }>(
`SELECT project_id, count(*) as count from ${TABLE_NAMES.events} GROUP by project_id order by count()`,
);
const last24h = await chQuery<{ count: number }>(
`SELECT count(*) as count from ${TABLE_NAMES.events} WHERE created_at > now() - interval '24 hours'`,
);
return { projects, last24hCount: last24h[0]?.count || 0 };
});
reply.status(200).send({
projectsCount: res.projects.length,
eventsCount: res.projects.reduce((acc, { count }) => acc + count, 0),
eventsLast24hCount: res.last24hCount,
});
}

View File

@@ -8,6 +8,12 @@ const miscRouter: FastifyPluginCallback = (fastify, opts, done) => {
handler: controller.ping,
});
fastify.route({
method: 'GET',
url: '/stats',
handler: controller.stats,
});
fastify.route({
method: 'GET',
url: '/favicon',

View File

@@ -14,7 +14,7 @@ export const metadata: Metadata = {
title: 'OpenPanel | An open-source alternative to Mixpanel',
};
export const experimental_ppr = true;
// export const experimental_ppr = true;
export default function HomePage() {
return (
@@ -26,11 +26,7 @@ export default function HomePage() {
<Testimonials />
<Suspense
fallback={
<StatsPure
projectCount={882}
eventCount={634_000_000}
last24hCount={7_000_000}
/>
<StatsPure projectCount={0} eventCount={0} last24hCount={0} />
}
>
<Stats />

View File

@@ -14,9 +14,13 @@ function formatStars(stars: number) {
}
export function GithubButton() {
const [stars, setStars] = useState(3_263);
const [stars, setStars] = useState(3_700);
useEffect(() => {
getGithubRepoInfo().then((res) => setStars(res.stargazers_count));
getGithubRepoInfo().then((res) => {
if (res?.stargazers_count) {
setStars(res.stargazers_count);
}
});
}, []);
return (
<Button variant={'secondary'} asChild>

View File

@@ -1,7 +1,4 @@
import { TABLE_NAMES, chQuery } from '@openpanel/db';
import { cacheable } from '@openpanel/redis';
import Link from 'next/link';
import { Suspense } from 'react';
import { VerticalLine } from '../line';
import { PlusLine } from '../line';
import { HorizontalLine } from '../line';
@@ -17,26 +14,22 @@ function shortNumber(num: number) {
if (num >= 1e12) return `${+(num / 1e12).toFixed(1)}T`;
}
const getProjectsWithCount = cacheable(async function getProjectsWithCount() {
const projects = await chQuery<{ project_id: string; count: number }>(
`SELECT project_id, count(*) as count from ${TABLE_NAMES.events} GROUP by project_id order by count()`,
);
const last24h = await chQuery<{ count: number }>(
`SELECT count(*) as count from ${TABLE_NAMES.events} WHERE created_at > now() - interval '24 hours'`,
);
return { projects, last24hCount: last24h[0]?.count || 0 };
}, 60 * 60);
export async function Stats() {
const { projects, last24hCount } = await getProjectsWithCount();
const projectCount = projects.length;
const eventCount = projects.reduce((acc, { count }) => acc + count, 0);
const { projectsCount, eventsCount, eventsLast24hCount } = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/misc/stats`,
)
.then((res) => res.json())
.catch(() => ({
projectsCount: 0,
eventsCount: 0,
eventsLast24hCount: 0,
}));
return (
<StatsPure
projectCount={projectCount}
eventCount={eventCount}
last24hCount={last24hCount}
projectCount={projectsCount}
eventCount={eventsCount}
last24hCount={eventsLast24hCount}
/>
);
}

View File

@@ -1,6 +1,10 @@
export async function getGithubRepoInfo() {
const res = await fetch(
'https://api.github.com/repos/Openpanel-dev/openpanel',
);
return res.json();
try {
const res = await fetch(
'https://api.github.com/repos/Openpanel-dev/openpanel',
);
return res.json();
} catch (e) {
return null;
}
}

View File

@@ -8,18 +8,7 @@ const config = {
images: {
domains: ['localhost', 'openpanel.dev'],
},
// experimental: {
// ppr: 'incremental', // does not work with hyperdx?!
// },
transpilePackages: [
'@openpanel/queue',
'@openpanel/db',
'@openpanel/common',
'@openpanel/constants',
'@openpanel/redis',
'@openpanel/validation',
],
serverExternalPackages: ['@hyperdx/node-opentelemetry', 'ioredis', 'bullmq'],
serverExternalPackages: ['@hyperdx/node-opentelemetry'],
};
export default withMDX(config);

View File

@@ -12,9 +12,7 @@
"dependencies": {
"@hyperdx/node-opentelemetry": "^0.8.1",
"@number-flow/react": "0.3.5",
"@openpanel/db": "workspace:*",
"@openpanel/nextjs": "^1.0.5",
"@openpanel/redis": "workspace:*",
"@openpanel/sdk-info": "workspace:^",
"@openstatus/react": "0.0.3",
"@radix-ui/react-accordion": "1.2.3",

6
pnpm-lock.yaml generated
View File

@@ -548,15 +548,9 @@ importers:
'@number-flow/react':
specifier: 0.3.5
version: 0.3.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@openpanel/db':
specifier: workspace:*
version: link:../../packages/db
'@openpanel/nextjs':
specifier: ^1.0.5
version: 1.0.5(next@15.0.3(@opentelemetry/api@1.8.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@openpanel/redis':
specifier: workspace:*
version: link:../../packages/redis
'@openpanel/sdk-info':
specifier: workspace:^
version: link:../../packages/sdks/_info