fix(public): remove db dependencies and use traditional api call to get stats
This commit is contained in:
@@ -5,8 +5,8 @@ import icoToPng from 'ico-to-png';
|
|||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
|
|
||||||
import { createHash } from '@openpanel/common/server';
|
import { createHash } from '@openpanel/common/server';
|
||||||
import { TABLE_NAMES, ch, formatClickhouseDate } from '@openpanel/db';
|
import { TABLE_NAMES, ch, chQuery, formatClickhouseDate } from '@openpanel/db';
|
||||||
import { getRedisCache } from '@openpanel/redis';
|
import { cacheable, getCache, getRedisCache } from '@openpanel/redis';
|
||||||
|
|
||||||
interface GetFaviconParams {
|
interface GetFaviconParams {
|
||||||
url: string;
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ const miscRouter: FastifyPluginCallback = (fastify, opts, done) => {
|
|||||||
handler: controller.ping,
|
handler: controller.ping,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fastify.route({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/stats',
|
||||||
|
handler: controller.stats,
|
||||||
|
});
|
||||||
|
|
||||||
fastify.route({
|
fastify.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/favicon',
|
url: '/favicon',
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const metadata: Metadata = {
|
|||||||
title: 'OpenPanel | An open-source alternative to Mixpanel',
|
title: 'OpenPanel | An open-source alternative to Mixpanel',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const experimental_ppr = true;
|
// export const experimental_ppr = true;
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
@@ -26,11 +26,7 @@ export default function HomePage() {
|
|||||||
<Testimonials />
|
<Testimonials />
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<StatsPure
|
<StatsPure projectCount={0} eventCount={0} last24hCount={0} />
|
||||||
projectCount={882}
|
|
||||||
eventCount={634_000_000}
|
|
||||||
last24hCount={7_000_000}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Stats />
|
<Stats />
|
||||||
|
|||||||
@@ -14,9 +14,13 @@ function formatStars(stars: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function GithubButton() {
|
export function GithubButton() {
|
||||||
const [stars, setStars] = useState(3_263);
|
const [stars, setStars] = useState(3_700);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getGithubRepoInfo().then((res) => setStars(res.stargazers_count));
|
getGithubRepoInfo().then((res) => {
|
||||||
|
if (res?.stargazers_count) {
|
||||||
|
setStars(res.stargazers_count);
|
||||||
|
}
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<Button variant={'secondary'} asChild>
|
<Button variant={'secondary'} asChild>
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import { TABLE_NAMES, chQuery } from '@openpanel/db';
|
|
||||||
import { cacheable } from '@openpanel/redis';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Suspense } from 'react';
|
|
||||||
import { VerticalLine } from '../line';
|
import { VerticalLine } from '../line';
|
||||||
import { PlusLine } from '../line';
|
import { PlusLine } from '../line';
|
||||||
import { HorizontalLine } from '../line';
|
import { HorizontalLine } from '../line';
|
||||||
@@ -17,26 +14,22 @@ function shortNumber(num: number) {
|
|||||||
if (num >= 1e12) return `${+(num / 1e12).toFixed(1)}T`;
|
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() {
|
export async function Stats() {
|
||||||
const { projects, last24hCount } = await getProjectsWithCount();
|
const { projectsCount, eventsCount, eventsLast24hCount } = await fetch(
|
||||||
const projectCount = projects.length;
|
`${process.env.NEXT_PUBLIC_API_URL}/misc/stats`,
|
||||||
const eventCount = projects.reduce((acc, { count }) => acc + count, 0);
|
)
|
||||||
|
.then((res) => res.json())
|
||||||
|
.catch(() => ({
|
||||||
|
projectsCount: 0,
|
||||||
|
eventsCount: 0,
|
||||||
|
eventsLast24hCount: 0,
|
||||||
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StatsPure
|
<StatsPure
|
||||||
projectCount={projectCount}
|
projectCount={projectsCount}
|
||||||
eventCount={eventCount}
|
eventCount={eventsCount}
|
||||||
last24hCount={last24hCount}
|
last24hCount={eventsLast24hCount}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
export async function getGithubRepoInfo() {
|
export async function getGithubRepoInfo() {
|
||||||
const res = await fetch(
|
try {
|
||||||
'https://api.github.com/repos/Openpanel-dev/openpanel',
|
const res = await fetch(
|
||||||
);
|
'https://api.github.com/repos/Openpanel-dev/openpanel',
|
||||||
return res.json();
|
);
|
||||||
|
return res.json();
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,18 +8,7 @@ const config = {
|
|||||||
images: {
|
images: {
|
||||||
domains: ['localhost', 'openpanel.dev'],
|
domains: ['localhost', 'openpanel.dev'],
|
||||||
},
|
},
|
||||||
// experimental: {
|
serverExternalPackages: ['@hyperdx/node-opentelemetry'],
|
||||||
// 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'],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withMDX(config);
|
export default withMDX(config);
|
||||||
|
|||||||
@@ -12,9 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hyperdx/node-opentelemetry": "^0.8.1",
|
"@hyperdx/node-opentelemetry": "^0.8.1",
|
||||||
"@number-flow/react": "0.3.5",
|
"@number-flow/react": "0.3.5",
|
||||||
"@openpanel/db": "workspace:*",
|
|
||||||
"@openpanel/nextjs": "^1.0.5",
|
"@openpanel/nextjs": "^1.0.5",
|
||||||
"@openpanel/redis": "workspace:*",
|
|
||||||
"@openpanel/sdk-info": "workspace:^",
|
"@openpanel/sdk-info": "workspace:^",
|
||||||
"@openstatus/react": "0.0.3",
|
"@openstatus/react": "0.0.3",
|
||||||
"@radix-ui/react-accordion": "1.2.3",
|
"@radix-ui/react-accordion": "1.2.3",
|
||||||
|
|||||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -548,15 +548,9 @@ importers:
|
|||||||
'@number-flow/react':
|
'@number-flow/react':
|
||||||
specifier: 0.3.5
|
specifier: 0.3.5
|
||||||
version: 0.3.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
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':
|
'@openpanel/nextjs':
|
||||||
specifier: ^1.0.5
|
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)
|
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':
|
'@openpanel/sdk-info':
|
||||||
specifier: workspace:^
|
specifier: workspace:^
|
||||||
version: link:../../packages/sdks/_info
|
version: link:../../packages/sdks/_info
|
||||||
|
|||||||
Reference in New Issue
Block a user