Skip to content

Commit e6b1fd4

Browse files
Merge pull request #212 from boostcampwm-2024/dev-back
Dev back merge to main
2 parents 7bac370 + b6702c4 commit e6b1fd4

File tree

8 files changed

+83
-23
lines changed

8 files changed

+83
-23
lines changed

backend/console-server/src/log/rank/dto/get-elapsed-time-rank-response.dto.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ export class GetElapsedTimeRankResponseDto {
2525
example: [
2626
{
2727
projectName: 'test059',
28-
elapsedTime: 100,
28+
value: 100,
2929
},
3030
{
3131
projectName: 'test007',
32-
elapsedTime: 110,
32+
value: 110,
3333
},
3434
{
3535
projectName: 'test079',
36-
elapsedTime: 120,
36+
value: 120,
3737
},
3838
],
3939
})

backend/name-server/src/database/query/dau-recorder.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ export class DAURecorder implements DAURecorderInterface {
88
private clickhouseClient = ClickhouseDatabase.getInstance();
99

1010
public async recordAccess(domain: string): Promise<void> {
11-
const dateString = new Date().toLocaleDateString();
12-
const values = [{ domain: domain.toLowerCase(), date: dateString, access: 1 }];
11+
const values = [
12+
{ domain: domain.toLowerCase(), date: this.formatDate(new Date()), access: 1 },
13+
];
1314
try {
1415
await this.clickhouseClient.insert({
1516
table: 'dau',
@@ -20,4 +21,12 @@ export class DAURecorder implements DAURecorderInterface {
2021
console.error('ClickHouse Error:', error);
2122
}
2223
}
24+
25+
private formatDate(date: Date): string {
26+
const year = date.getFullYear();
27+
const month = String(date.getMonth() + 1).padStart(2, '0');
28+
const day = String(date.getDate()).padStart(2, '0');
29+
30+
return `${year}-${month}-${day}`;
31+
}
2332
}

backend/proxy-server/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"scripts": {
88
"test": "jest --config jest.config.js -ts-config=tsconfig.test.json",
99
"build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
10+
"start": "NODE_ENV=production tsx src/index.ts",
1011
"dev": "NODE_ENV=development tsx src/index.ts",
1112
"lint": "eslint src/**/*.ts",
1213
"lint:fix": "eslint src/**/*.ts --fix"

backend/proxy-server/src/app.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ export class Application {
2929
const projectCacheRepository = new ProjectCacheRepositoryRedis();
3030
const projectService = new ProjectService(projectRepository, projectCacheRepository);
3131
const proxyService = new ProxyService(projectService);
32-
const logRepository = new LogRepositoryClickhouse();
32+
const logRepository = new LogRepositoryClickhouse({
33+
maxSize: 1000,
34+
flushIntervalSecond: 5,
35+
});
3336
const logService = new LogService(logRepository);
3437

3538
const errorLogRepository = new ErrorLogRepository();

backend/proxy-server/src/database/query/log.repository.clickhouse.ts

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,80 @@ import { LogRepository } from '../../domain/log/log.repository';
44
import { HttpLogEntity } from '../../domain/log/http-log.entity';
55
import { ClickHouseClient } from '@clickhouse/client';
66
import { formatDateTime } from '../../common/utils/date.util';
7+
import { LogBufferConfig } from 'domain/config/log-buffer.config';
8+
import { FastifyLogger } from 'common/logger/fastify.logger';
9+
10+
type httpLogRecord = {
11+
method: string;
12+
path: string;
13+
host: string;
14+
status_code: number;
15+
elapsed_time: number;
16+
timestamp: string;
17+
};
718

819
export class LogRepositoryClickhouse implements LogRepository {
920
private readonly clickhouse: ClickHouseClient;
21+
private readonly config: LogBufferConfig;
22+
private logBuffer: httpLogRecord[] = [];
23+
private flushTimer: NodeJS.Timeout | null = null;
24+
private isProcessing: boolean = false;
1025

11-
constructor() {
26+
constructor(config: LogBufferConfig) {
1227
this.clickhouse = ClickhouseDatabase.getInstance();
28+
this.config = config;
29+
this.startFlushTimer();
1330
}
1431

15-
public async insertHttpLog(log: HttpLogEntity): Promise<void> {
16-
const values = [
17-
{
18-
method: log.method,
19-
path: log.path || '',
20-
host: log.host,
21-
status_code: log.statusCode,
22-
elapsed_time: Math.round(log.responseTime),
23-
timestamp: formatDateTime(new Date()),
24-
},
25-
];
32+
private startFlushTimer(): void {
33+
if (this.flushTimer) {
34+
clearInterval(this.flushTimer);
35+
}
36+
37+
this.flushTimer = setInterval(async () => {
38+
if (this.logBuffer.length > 0 && !this.isProcessing) {
39+
await this.flush();
40+
}
41+
}, this.config.flushIntervalSecond * 1000);
42+
}
43+
44+
private async flush(): Promise<void> {
45+
if (this.isProcessing || this.logBuffer.length === 0) {
46+
return;
47+
}
48+
let batchToFlush = [...this.logBuffer];
2649

50+
this.logBuffer = [];
2751
try {
52+
this.isProcessing = true;
53+
2854
await this.clickhouse.insert({
2955
table: 'http_log',
30-
values: values,
56+
values: batchToFlush,
3157
format: 'JSONEachRow',
3258
});
3359
} catch (error) {
34-
console.error('ClickHouse Error:', error);
60+
this.logBuffer = [...this.logBuffer, ...batchToFlush];
3561
throw new DatabaseQueryError(error as Error);
62+
} finally {
63+
this.isProcessing = false;
64+
}
65+
}
66+
67+
public async insertHttpLog(log: HttpLogEntity): Promise<void> {
68+
const httpLogRecord: httpLogRecord = {
69+
method: log.method,
70+
path: log.path || '',
71+
host: log.host,
72+
status_code: log.statusCode,
73+
elapsed_time: Math.round(log.responseTime),
74+
timestamp: formatDateTime(new Date()),
75+
};
76+
77+
this.logBuffer.push(httpLogRecord);
78+
79+
if (this.logBuffer.length >= this.config.maxSize) {
80+
this.flush();
3681
}
3782
}
3883
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export type LogBufferConfig = {
2+
maxSize: number;
3+
flushIntervalSecond: number;
4+
};

backend/proxy-server/src/domain/proxy/proxy.service.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ export class ProxyService {
3434

3535
return ip;
3636
} catch (error) {
37-
console.log('error: ', error);
38-
3937
if (error instanceof ProxyError) {
4038
throw error;
4139
}

backend/proxy-server/src/server/config/fastify.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const fastifyConfig = {
1010
process.env.NODE_ENV === 'development'
1111
? true
1212
: {
13-
level: process.env.LOG_LEVEL || 'info',
13+
level: process.env.LOG_LEVEL || 'warning',
1414
serializers: {
1515
req(
1616
request: FastifyRequest<

0 commit comments

Comments
 (0)