Skip to content

Commit

Permalink
feat: stats and graphs (#1035)
Browse files Browse the repository at this point in the history
Co-authored-by: takaro-ci-bot[bot] <138661031+takaro-ci-bot[bot]@users.noreply.github.com>
  • Loading branch information
niekcandaele and takaro-ci-bot[bot] authored Jun 8, 2024
1 parent 62a9ce7 commit 26ca998
Show file tree
Hide file tree
Showing 25 changed files with 1,136 additions and 251 deletions.
12 changes: 6 additions & 6 deletions containers/prometheus/prometheus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ global:
evaluation_interval: 15s # By default, scrape targets every 15 seconds.

scrape_configs:
- job_name: "prometheus"
- job_name: 'prometheus'
static_configs:
- targets: ["localhost:9090"]
- targets: ['localhost:9090']

- job_name: "api"
- job_name: 'api'
static_configs:
- targets: ["takaro:3000"]
- targets: ['takaro:3000']

- job_name: "app-agent"
- job_name: 'pushgateway'
static_configs:
- targets: ["takaro:3001"]
- targets: ['pushgateway:9091']
87 changes: 0 additions & 87 deletions docker-compose.observability.yml

This file was deleted.

15 changes: 0 additions & 15 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,21 +168,6 @@ services:
- 8025:8025
logging:
driver: none

grafana_agent:
image: grafana/agent:v0.38.1
command: ["run", "--server.http.listen-addr=0.0.0.0:12345", "/etc/agent/config.river"]
volumes:
- ./containers/grafana/agent/config.river:/etc/agent/config.river
- /tmp/agent:/tmp/agent
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "4689:12345"
environment:
AGENT_MODE: "flow"
GRAFANA_CLOUD_TEMPO_URL: ${GRAFANA_CLOUD_TEMPO_URL}
GRAFANA_CLOUD_API_USER: ${GRAFANA_CLOUD_API_USER}
GRAFANA_CLOUD_API_KEY: ${GRAFANA_CLOUD_API_KEY}

networks:
takaro:
Expand Down
51 changes: 51 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,57 @@ services:
driver: none
networks:
- takaro

prometheus:
image: prom/prometheus:v2.52.0
networks:
- takaro
container_name: prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
ports:
- 9090:9090
volumes:
- ./containers/prometheus:/etc/prometheus
- ./_data/prometheus:/prometheus
pushgateway:
image: prom/pushgateway
container_name: pushgateway
ports:
- "9091:9091"
networks:
- takaro

grafana:
image: grafana/grafana:9.3.6
networks:
- takaro
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_AUTH_DISABLE_LOGIN_FORM=true
- GF_FEATURE_TOGGLES_ENABLE=traceqlEditor
volumes:
- ./_data/grafana:/var/lib/grafana
ports:
- '13007:3000'

tempo:
image: grafana/tempo:latest
command: ['-config.file=/etc/tempo.yaml']
volumes:
- ./containers/tempo/tempo.yaml:/etc/tempo.yaml
- ./_data/tempo:/tmp/tempo
networks:
- takaro
ports:
# - "14268:14268" # jaeger ingest
- '3200:3200' # tempo
- '4317:4317' # otlp grpc
# - "4318:4318" # otlp http
# - "9411:9411" # zipkin

networks:
takaro:
external:
Expand Down
18 changes: 18 additions & 0 deletions packages/app-api/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ interface IHttpConfig extends IBaseConfig {
refreshOlderThanMs: number;
refreshBatchSize: number;
};
metrics: {
prometheusUrl: string;
pushgatewayUrl: string;
};
}

const configSchema = {
Expand Down Expand Up @@ -200,6 +204,20 @@ const configSchema = {
env: 'STEAM_REFRESH_BATCH_SIZE',
},
},
metrics: {
prometheusUrl: {
doc: 'The URL of the Prometheus server',
format: String,
default: 'http://prometheus:9090',
env: 'PROMETHEUS_URL',
},
pushgatewayUrl: {
doc: 'The URL of the Prometheus pushgateway',
format: String,
default: 'http://pushgateway:9091',
env: 'PUSHGATEWAY_URL',
},
},
};

export const config = new Config<IHttpConfig & IQueuesConfig & IDbConfig & Pick<IAuthConfig, 'kratos' | 'hydra'>>([
Expand Down
69 changes: 69 additions & 0 deletions packages/app-api/src/controllers/StatsController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { IsDateString, IsISO8601, IsOptional, IsUUID, ValidateNested } from 'class-validator';
import { APIOutput, apiResponse } from '@takaro/http';
import { AuthenticatedRequest, AuthService } from '../service/AuthService.js';
import { Get, JsonController, UseBefore, Req, QueryParams } from 'routing-controllers';
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { Type } from 'class-transformer';
import { PERMISSIONS } from '@takaro/auth';
import { StatsOutputDTO, StatsService } from '../service/StatsService.js';
import { TakaroDTO } from '@takaro/util';

class StatsOutputDTOAPI extends APIOutput<StatsOutputDTO> {
@ValidateNested()
@Type(() => StatsOutputDTO)
declare data: StatsOutputDTO;
}

class BaseStatsInputDTO extends TakaroDTO<BaseStatsInputDTO> {
@IsISO8601()
@IsDateString()
@IsOptional()
startDate?: string;
@IsOptional()
@IsDateString()
@IsISO8601()
endDate?: string;
}

class PogStatsInputDTO extends BaseStatsInputDTO {
@IsUUID('4')
gameServerId!: string;
@IsUUID('4')
playerId!: string;
}

class PlayersOnlineInputDTO extends BaseStatsInputDTO {
@IsOptional()
@IsUUID('4')
gameServerId?: string;
}

@OpenAPI({
security: [{ domainAuth: [] }],
})
@JsonController()
export class StatsController {
@UseBefore(AuthService.getAuthMiddleware([PERMISSIONS.READ_GAMESERVERS, PERMISSIONS.READ_PLAYERS]))
@ResponseSchema(StatsOutputDTOAPI)
@Get('/stats/ping')
async getPingStats(@Req() req: AuthenticatedRequest, @QueryParams() query: PogStatsInputDTO) {
const service = new StatsService(req.domainId);
return apiResponse(await service.getPing(query.playerId, query.gameServerId, query.startDate, query.endDate));
}

@UseBefore(AuthService.getAuthMiddleware([PERMISSIONS.READ_GAMESERVERS, PERMISSIONS.READ_PLAYERS]))
@ResponseSchema(StatsOutputDTOAPI)
@Get('/stats/currency')
async getCurrencyStats(@Req() req: AuthenticatedRequest, @QueryParams() query: PogStatsInputDTO) {
const service = new StatsService(req.domainId);
return apiResponse(await service.getCurrency(query.playerId, query.gameServerId, query.startDate, query.endDate));
}

@UseBefore(AuthService.getAuthMiddleware([PERMISSIONS.READ_GAMESERVERS, PERMISSIONS.READ_PLAYERS]))
@ResponseSchema(StatsOutputDTOAPI)
@Get('/stats/players-online')
async getPlayerOnlineStats(@Req() req: AuthenticatedRequest, @QueryParams() query: PlayersOnlineInputDTO) {
const service = new StatsService(req.domainId);
return apiResponse(await service.getPlayersOnline(query.gameServerId, query.startDate, query.endDate));
}
}
Loading

0 comments on commit 26ca998

Please sign in to comment.