fix(worker): avoid creating new loggers

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-09-24 22:13:15 +02:00
parent 0391552ef7
commit 66a49c53cf
5 changed files with 73 additions and 88 deletions

View File

@@ -92,28 +92,6 @@ const startServer = async () => {
const ignoreLog = ['/healthcheck', '/metrics', '/misc']; const ignoreLog = ['/healthcheck', '/metrics', '/misc'];
const ignoreMethods = ['OPTIONS']; const ignoreMethods = ['OPTIONS'];
fastify.addHook('onRequest', (request, reply, done) => {
if (ignoreMethods.includes(request.method)) {
return done();
}
if (ignoreLog.some((path) => request.url.startsWith(path))) {
return done();
}
if (request.url.includes('trpc')) {
request.log.info('request incoming', {
url: request.url.split('?')[0],
method: request.method,
input: getTrpcInput(request),
});
} else {
request.log.info('request incoming', {
url: request.url,
method: request.method,
});
}
done();
});
fastify.addHook('onResponse', (request, reply, done) => { fastify.addHook('onResponse', (request, reply, done) => {
if (ignoreMethods.includes(request.method)) { if (ignoreMethods.includes(request.method)) {
return done(); return done();
@@ -133,6 +111,8 @@ const startServer = async () => {
url: request.url, url: request.url,
method: request.method, method: request.method,
responseTime: reply.elapsedTime, responseTime: reply.elapsedTime,
headers: request.headers,
body: request.body,
}); });
} }
done(); done();

View File

@@ -84,12 +84,27 @@ async function start() {
}); });
worker.on('failed', (job) => { worker.on('failed', (job) => {
if (job) {
logger.error('job failed', { logger.error('job failed', {
worker: worker.name, worker: worker.name,
data: job?.data, data: job.data,
error: job?.failedReason, error: job.failedReason,
options: job?.opts, options: job.opts,
}); });
}
});
worker.on('completed', (job) => {
if (job) {
logger.info('job completed', {
worker: worker.name,
data: job.data,
duration:
job.processedOn && job.finishedOn
? job.finishedOn - job.processedOn
: undefined,
});
}
}); });
worker.on('ioredis:close', () => { worker.on('ioredis:close', () => {

View File

@@ -1,14 +1,16 @@
import type { Job } from 'bullmq'; import type { Job } from 'bullmq';
import { last } from 'ramda'; import { last } from 'ramda';
import { logger as baseLogger } from '@/utils/logger';
import { getTime } from '@openpanel/common'; import { getTime } from '@openpanel/common';
import { import {
type IServiceEvent,
TABLE_NAMES, TABLE_NAMES,
createEvent, createEvent,
eventBuffer, eventBuffer,
getEvents, getEvents,
} from '@openpanel/db'; } from '@openpanel/db';
import { createLogger } from '@openpanel/logger'; import type { ILogger } from '@openpanel/logger';
import type { EventsQueuePayloadCreateSessionEnd } from '@openpanel/queue'; import type { EventsQueuePayloadCreateSessionEnd } from '@openpanel/queue';
async function getCompleteSession({ async function getCompleteSession({
@@ -32,65 +34,62 @@ async function getCompleteSession({
return getEvents(sql); return getEvents(sql);
} }
async function getCompleteSessionWithSessionStart({
projectId,
sessionId,
logger,
}: {
projectId: string;
sessionId: string;
logger: ILogger;
}): Promise<ReturnType<typeof getEvents>> {
const intervals = [6, 12, 24, 72];
for (const hoursInterval of intervals) {
const events = await getCompleteSession({
projectId,
sessionId,
hoursInterval,
});
if (events.find((event) => event.name === 'session_start')) {
return events;
}
logger.warn(`Checking last ${hoursInterval} hours for session_start`);
}
return [];
}
export async function createSessionEnd( export async function createSessionEnd(
job: Job<EventsQueuePayloadCreateSessionEnd>, job: Job<EventsQueuePayloadCreateSessionEnd>,
) { ) {
const logger = createLogger({ const logger = baseLogger.child({
name: 'job:create-session-end',
}).child({
payload: job.data.payload, payload: job.data.payload,
jobId: job.id, jobId: job.id,
}); });
const payload = job.data.payload; const payload = job.data.payload;
const lastScreenView = await eventBuffer.getLastScreenView({
const [lastScreenView, eventsInDb] = await Promise.all([
eventBuffer.getLastScreenView({
projectId: payload.projectId, projectId: payload.projectId,
profileId: payload.profileId || payload.deviceId, profileId: payload.profileId || payload.deviceId,
}); }),
getCompleteSessionWithSessionStart({
const eventsInBuffer = lastScreenView
? [lastScreenView]
: await eventBuffer.findMany(
(item) => item.session_id === payload.sessionId,
);
if (lastScreenView) {
logger.info('found last screen view in buffer');
} else if (eventsInBuffer.length > 0) {
logger.info('found events in buffer');
} else {
logger.info('no events in buffer');
}
let eventsInDb = await getCompleteSession({
projectId: payload.projectId, projectId: payload.projectId,
sessionId: payload.sessionId, sessionId: payload.sessionId,
hoursInterval: 12, logger,
}); }),
]);
// If session_start does not exist, try to find it the last 24 hours
if (!eventsInDb.find((event) => event.name === 'session_start')) {
logger.warn('Checking last 24 hours for session_start');
eventsInDb = await getCompleteSession({
projectId: payload.projectId,
sessionId: payload.sessionId,
hoursInterval: 24,
});
}
// If session_start does not exist, try to find it the last 72 hours
if (!eventsInDb.find((event) => event.name === 'session_start')) {
logger.warn('Checking last 72 hours for session_start');
eventsInDb = await getCompleteSession({
projectId: payload.projectId,
sessionId: payload.sessionId,
hoursInterval: 72,
});
}
// sort last inserted first // sort last inserted first
const events = [...eventsInBuffer, ...eventsInDb].sort( const events = [lastScreenView, ...eventsInDb]
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(), .filter((event): event is IServiceEvent => !!event)
.sort(
(a, b) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
); );
events.map((event, index) => { events.map((event, index) => {

View File

@@ -4,11 +4,11 @@ import type { Job } from 'bullmq';
import { omit } from 'ramda'; import { omit } from 'ramda';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { logger } from '@/utils/logger';
import { getTime, isSameDomain, parsePath } from '@openpanel/common'; import { getTime, isSameDomain, parsePath } from '@openpanel/common';
import type { IServiceCreateEventPayload } from '@openpanel/db'; import type { IServiceCreateEventPayload } from '@openpanel/db';
import { createEvent } from '@openpanel/db'; import { createEvent } from '@openpanel/db';
import { getLastScreenViewFromProfileId } from '@openpanel/db/src/services/event.service'; import { getLastScreenViewFromProfileId } from '@openpanel/db/src/services/event.service';
import { createLogger } from '@openpanel/logger';
import { findJobByPrefix, sessionsQueue } from '@openpanel/queue'; import { findJobByPrefix, sessionsQueue } from '@openpanel/queue';
import type { import type {
EventsQueuePayloadCreateSessionEnd, EventsQueuePayloadCreateSessionEnd,
@@ -19,10 +19,6 @@ import { getRedisQueue } from '@openpanel/redis';
const GLOBAL_PROPERTIES = ['__path', '__referrer']; const GLOBAL_PROPERTIES = ['__path', '__referrer'];
export const SESSION_TIMEOUT = 1000 * 60 * 30; export const SESSION_TIMEOUT = 1000 * 60 * 30;
const logger = createLogger({
name: 'job:incoming-event',
});
const getSessionEndJobId = (projectId: string, deviceId: string) => const getSessionEndJobId = (projectId: string, deviceId: string) =>
`sessionEnd:${projectId}:${deviceId}`; `sessionEnd:${projectId}:${deviceId}`;

View File

@@ -3,9 +3,7 @@ import winston from 'winston';
export { winston }; export { winston };
export type ILogger = winston.Logger & { export type ILogger = winston.Logger;
noop: (message: string) => (error: unknown) => void;
};
const logLevel = process.env.LOG_LEVEL ?? 'info'; const logLevel = process.env.LOG_LEVEL ?? 'info';
@@ -61,8 +59,5 @@ export function createLogger({ name }: { name: string }): ILogger {
), ),
}); });
return Object.assign(logger, { return logger;
noop: (message: string) => (error: unknown) =>
logger.error(`noop: ${message}`, error),
});
} }