Skip to content

Commit

Permalink
Merge pull request #87 from boostcampwm-2024/dev-back
Browse files Browse the repository at this point in the history
[BE] main으로 머지
  • Loading branch information
sjy2335 authored Nov 14, 2024
2 parents 1aa73dc + 61b15c8 commit e72bc04
Show file tree
Hide file tree
Showing 89 changed files with 123 additions and 8,242 deletions.
13 changes: 13 additions & 0 deletions backend/console-server/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ services:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- /etc/letsencrypt:/etc/letsencrypt
depends_on:
- server-blue
- server-green
networks:
- app-network

server-blue:
image: ghcr.io/boostcampwm-2024/web35-watchducks/backend/console-server:latest
Expand All @@ -24,6 +28,8 @@ services:
interval: 10s
timeout: 2s
retries: 5
networks:
- app-network

server-green:
image: ghcr.io/boostcampwm-2024/web35-watchducks/backend/console-server:latest
Expand All @@ -39,3 +45,10 @@ services:
interval: 10s
timeout: 2s
retries: 5
networks:
- app-network

networks:
app-network:
name: app-network
driver: bridge
16 changes: 16 additions & 0 deletions backend/console-server/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,24 @@ http {
server server-green:3002 backup;
}

# http를 https로 리디렉션
server {
listen 80;
server_name watchducks-test.store;

location / {
return 301 https://$host$request_uri;
}
}

server {
listen 443 ssl;
server_name watchducks-test.store;

ssl_certificate /etc/letsencrypt/live/watchducks-test.store/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/watchducks-test.store/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

location / {
proxy_pass http://console_server;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const metricExpressions: Record<string, MetricFunction> = {
max: (metric: string) => `max(${metric}) as ${metric}`,
p95: (metric: string) => `quantile(0.95)(${metric}) as ${metric}`,
p99: (metric: string) => `quantile(0.99)(${metric}) as ${metric}`,
rate: (metric: string) => `(sum(${metric}) / count(*)) * 100 as ${metric}_rate`,
};

export type MetricAggregationType = keyof typeof metricExpressions;
34 changes: 30 additions & 4 deletions backend/console-server/src/log/log.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,34 @@ export class LogController {
async trafficRank() {
return await this.logService.trafficRank();
}
}

// 1. 기수 내 전체 프로젝트
// 2. 기수 내 총 트래픽
// 4. 기수 내 응답 성공률
@Get('/response-rate')
@HttpCode(HttpStatus.OK)
@ApiOperation({
summary: '기수 내 응답 성공률',
description: '요청받은 기수의 기수 내 응답 성공률를 반환합니다.',
})
@ApiResponse({
status: 200,
description: '기수 내 응답 성공률이 성공적으로 반환됨.',
type: ProjectResponseDto,
})
async responseSuccessRate() {
return await this.logService.responseSuccessRate();
}

@Get('/traffic')
@HttpCode(HttpStatus.OK)
@ApiOperation({
summary: '기수 내 총 트래픽',
description: '요청받은 기수의 기수 내 총 트래픽를 반환합니다.',
})
@ApiResponse({
status: 200,
description: '기수 내 총 트래픽가 정상적으로 반환됨.',
type: ProjectResponseDto,
})
async trafficByGeneration() {
return await this.logService.trafficByGeneration();
}
}
32 changes: 32 additions & 0 deletions backend/console-server/src/log/log.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,36 @@ export class LogRepository {

return await this.clickhouse.query(query, params);
}

async findResponseSuccessRate() {
const { query, params } = new TimeSeriesQueryBuilder()
.metrics([
{
name: 'is_error',
aggregation: 'rate',
},
])
.from('http_log')
.build();

const result = await this.clickhouse.query(query, params);
return {
success_rate: 100 - (result as Array<{ is_error_rate: number }>)[0].is_error_rate,
};
}

async findTrafficByGeneration() {
const { query, params } = new TimeSeriesQueryBuilder()
.metrics([
{
name: '*',
aggregation: 'count',
},
])
.from('http_log')
.build();

const result = await this.clickhouse.query(query, params);
return result[0];
}
}
12 changes: 12 additions & 0 deletions backend/console-server/src/log/log.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,16 @@ export class LogService {

return result.slice(0, 4);
}

async responseSuccessRate() {
const result = await this.logRepository.findResponseSuccessRate();

return result;
}

async trafficByGeneration() {
const result = await this.logRepository.findTrafficByGeneration();

return result;
}
}
6 changes: 5 additions & 1 deletion backend/console-server/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);

app.useGlobalPipes(new ValidationPipe());
app.useGlobalPipes(
new ValidationPipe({
transform: true,
}),
);
app.setGlobalPrefix('api');
app.enableCors();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@ import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';

export class CountProjectByGenerationResponseDto {
@ApiProperty({
example: '5',
description: '부스트캠프 기수',
})
@Type(() => Number)
generation: number;

@ApiProperty({
example: '42',
description: '해당 기수의 프로젝트 총 개수',
Expand Down
2 changes: 2 additions & 0 deletions backend/console-server/src/project/dto/create-project.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IsEmail, IsIP, IsNotEmpty, IsNumber, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';

export class CreateProjectDto {
@ApiProperty({
Expand Down Expand Up @@ -38,6 +39,7 @@ export class CreateProjectDto {
example: 9,
description: '부스트캠프 기수',
})
@Type(() => Number)
@IsNumber()
@IsNotEmpty()
generation: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';

export class FindByGenerationResponseDto {
@ApiProperty({
example: 'watchducks',
})
@IsNotEmpty()
@Expose()
name: string;
}
1 change: 0 additions & 1 deletion backend/console-server/src/project/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export class ProjectService {
});

return plainToInstance(CountProjectByGenerationResponseDto, {
generation: generation,
count: count,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class DNSResponseBuilder {
name: question.name,
type: 'A',
class: 'IN',
ttl: 300,
ttl: 10,
data: this.config.proxyServerIp,
},
];
Expand Down
File renamed without changes.
Loading

0 comments on commit e72bc04

Please sign in to comment.