try debug event controller

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-03-07 20:22:22 +01:00
parent 6c109dde0e
commit 6a6ccfdb42
2 changed files with 70 additions and 31 deletions

View File

@@ -1,3 +1,4 @@
import { logger, logInfo } from '@/utils/logger';
import { getClientIp, parseIp } from '@/utils/parseIp'; import { getClientIp, parseIp } from '@/utils/parseIp';
import { getReferrerWithQuery, parseReferrer } from '@/utils/parseReferrer'; import { getReferrerWithQuery, parseReferrer } from '@/utils/parseReferrer';
import { isUserAgentSet, parseUserAgent } from '@/utils/parseUserAgent'; import { isUserAgentSet, parseUserAgent } from '@/utils/parseUserAgent';
@@ -61,6 +62,21 @@ function isSameDomain(url1: string | undefined, url2: string | undefined) {
} }
} }
async function withTiming<T>(name: string, promise: T) {
try {
const start = Date.now();
const res = await promise;
const end = Date.now();
if (end - start > 1000) {
logInfo(`${name} took too long: ${end - start}ms`);
}
return res;
} catch (error) {
logger.error(error, `Failed to execute ${name}`);
throw error;
}
}
export async function postEvent( export async function postEvent(
request: FastifyRequest<{ request: FastifyRequest<{
Body: PostEventPayload; Body: PostEventPayload;
@@ -109,8 +125,11 @@ export async function postEvent(
const isServerEvent = !ip && !origin && !isUserAgentSet(ua); const isServerEvent = !ip && !origin && !isUserAgentSet(ua);
if (isServerEvent) { if (isServerEvent) {
const [event] = await getEvents( const [event] = await withTiming(
`SELECT * FROM events WHERE name = 'screen_view' AND profile_id = '${profileId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1` 'Get last event (server-event)',
getEvents(
`SELECT * FROM events WHERE name = 'screen_view' AND profile_id = '${profileId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`
)
); );
eventsQueue.add('event', { eventsQueue.add('event', {
@@ -153,10 +172,10 @@ export async function postEvent(
return reply.status(200).send(''); return reply.status(200).send('');
} }
const [geo, eventsJobs] = await Promise.all([ const [geo, eventsJobs] = await withTiming(
parseIp(ip), 'Get geo and job from queue',
eventsQueue.getJobs(['delayed']), Promise.all([parseIp(ip), eventsQueue.getJobs(['delayed'])])
]); );
// find session_end job // find session_end job
const sessionEndJobCurrentDeviceId = findJobByPrefix( const sessionEndJobCurrentDeviceId = findJobByPrefix(
@@ -200,8 +219,11 @@ export async function postEvent(
); );
} }
const [sessionStartEvent] = await getEvents( const [sessionStartEvent] = await withTiming(
`SELECT * FROM events WHERE name = 'session_start' AND device_id = '${deviceId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1` 'Get session start event',
getEvents(
`SELECT * FROM events WHERE name = 'session_start' AND device_id = '${deviceId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`
)
); );
request.log.info( request.log.info(
@@ -272,26 +294,36 @@ export async function postEvent(
}, },
'duration is wrong' 'duration is wrong'
); );
} else {
// Skip update duration if it's wrong
// Seems like request is not in right order
await withTiming(
'Update previous job with duration',
job.updateData({
type: 'createEvent',
payload: {
...prevEvent,
duration,
},
})
);
} }
await job.updateData({
type: 'createEvent', await withTiming('Promote previous job', job.promote());
payload: {
...prevEvent,
duration,
},
});
await job.promote();
} }
} }
if (createSessionStart) { if (createSessionStart) {
// We do not need to queue session_start // We do not need to queue session_start
await createEvent({ await withTiming(
...payload, 'Create session start event',
name: 'session_start', createEvent({
// @ts-expect-error ...payload,
createdAt: toISOString(getTime(payload.createdAt) - 100), name: 'session_start',
}); // @ts-expect-error
createdAt: toISOString(getTime(payload.createdAt) - 100),
})
);
} }
const options: JobsOptions = {}; const options: JobsOptions = {};
@@ -302,13 +334,16 @@ export async function postEvent(
request.log.info(payload, 'queue event'); request.log.info(payload, 'queue event');
// Queue current event // Queue current event
eventsQueue.add( await withTiming(
'event', 'Add current to event queue',
{ eventsQueue.add(
type: 'createEvent', 'event',
payload, {
}, type: 'createEvent',
options payload,
},
options
)
); );
reply.status(202).send(deviceId); reply.status(202).send(deviceId);

View File

@@ -1,5 +1,7 @@
import type { FastifyRequest } from 'fastify'; import type { FastifyRequest } from 'fastify';
import { logger } from './logger';
interface RemoteIpLookupResponse { interface RemoteIpLookupResponse {
country: string | undefined; country: string | undefined;
city: string | undefined; city: string | undefined;
@@ -41,7 +43,9 @@ export async function parseIp(ip?: string): Promise<GeoLocation> {
} }
try { try {
const geo = await fetch(`${process.env.GEO_IP_HOST}/${ip}`); const geo = await fetch(`${process.env.GEO_IP_HOST}/${ip}`, {
signal: AbortSignal.timeout(2000),
});
const res = (await geo.json()) as RemoteIpLookupResponse; const res = (await geo.json()) as RemoteIpLookupResponse;
return { return {
@@ -51,7 +55,7 @@ export async function parseIp(ip?: string): Promise<GeoLocation> {
continent: res.continent, continent: res.continent,
}; };
} catch (e) { } catch (e) {
console.log('Failed to parse ip', e); logger.error('Failed to fetch geo location for ip', e);
return geo; return geo;
} }
} }