🔀」 merge(ELK): added ELK stack for ELK module (closes #24)

This commit is contained in:
Adam
2025-07-26 15:35:44 +02:00
committed by GitHub
27 changed files with 202 additions and 273 deletions

View File

@ -13,7 +13,7 @@ set dotenv-load
# To launch all apis
@apis:
node src/dev.js
node src/start.js
# To launch the front end
@front:

4
docker/ELK/compose.yml Normal file
View File

@ -0,0 +1,4 @@
include:
- ./logstash/compose.yml
- ./kibana/compose.yml
- ./elasticsearch/compose.yml

View File

@ -0,0 +1,4 @@
FROM docker.elastic.co/elasticsearch/elasticsearch-wolfi:9.0.4
COPY --chown=elasticsearch:elasticsearch elasticsearch.yml /usr/share/elasticsearch/config/
COPY --chown=elasticsearch:elasticsearch jvm.options /usr/share/elasticsearch/config/jvm.options.d/custom.options

View File

@ -0,0 +1,10 @@
services:
elasticsearch:
container_name: transcendence-elasticsearch
build:
dockerfile: Dockerfile
context: .
environment:
- LOG_LEVEL=info
networks:
- elk

View File

@ -0,0 +1,9 @@
cluster.name: docker-cluster
node.name: transcendence-elasticsearch
discovery.type: single-node
xpack.security.enabled: false
network.host: 0.0.0.0

View File

@ -0,0 +1,2 @@
-Xms1g
-Xmx1g

View File

@ -0,0 +1,3 @@
FROM docker.elastic.co/kibana/kibana-wolfi:9.0.4
COPY --chmod=777 kibana.yml /etc/kibana/kibana.yml

View File

@ -0,0 +1,12 @@
services:
kibana:
container_name: transcendence-kibana
build:
dockerfile: Dockerfile
context: .
ports:
- ${ELK_PORT}:5601
environment:
- LOG_LEVEL=info
networks:
- elk

View File

@ -0,0 +1,6 @@
server.name: kibana
server.host: "0.0.0.0"
elasticsearch.hosts: ["https://transcendence-elasticsearch:9200"]
telemetry.enabled: false

View File

@ -0,0 +1,6 @@
FROM docker.elastic.co/logstash/logstash-wolfi:9.0.4
RUN rm -f /usr/share/logstash/pipeline/logstash.conf
COPY --chmod=777 pipeline/ /usr/share/logstash/pipeline/
COPY --chmod=777 config/ /usr/share/logstash/config/

View File

@ -0,0 +1,15 @@
services:
logstash:
container_name: transcendence-logstash
build:
dockerfile: Dockerfile
context: .
volumes:
- log-user:/var/log/user-api
- log-auth:/var/log/auth-api
- log-nginx:/var/log/nginx
environment:
- LOG_LEVEL=info
networks:
- elk
- logstash

View File

@ -0,0 +1,2 @@
api:
environment: production

View File

@ -0,0 +1,27 @@
input {
file {
path => "/var/log/user-api/log.log"
start_position => "beginning"
tags => [ "api", "user" ]
}
file {
path => "/var/log/auth-api/log.log"
start_position => "beginning"
tags => [ "api", "auth" ]
}
file {
path => "/var/log/nginx/log.log"
start_position => "beginning"
tags => [ "nginx", "front" ]
}
file {
path => "/var/log/nginx/err.log"
start_position => "beginning"
tags => [ "nginx", "front", "error" ]
}
}
output {
elasticsearch { hosts => ["transcendence-elasticsearch:9200"] }
stdout { codec => rubydebug }
}

View File

@ -24,5 +24,7 @@ EXPOSE 3000
RUN mkdir /db
STOPSIGNAL SIGINT
ENV LOG_TARGET=/var/log/log.log
RUN touch /var/log/log.log
CMD [ "node", "/app/src/start.js" ]

View File

@ -6,6 +6,7 @@ services:
context: ../../
volumes:
- db-user:/db
- log-user:/var/log
networks:
- front
- back
@ -13,6 +14,7 @@ services:
environment:
- TZ=Europe/Paris
- API_TARGET=user
- LOG_FILE_PATH=/var/log/log.log
- JWT_SECRET=${JWT_SECRET}
restart: unless-stopped
auth-api:
@ -22,12 +24,17 @@ services:
context: ../../
volumes:
- db-auth:/db
- log-auth:/var/log
networks:
- front
- back
- prom-exporter
environment:
- TZ=Europe/Paris
- GOOGLE_CALLBACK_URL=${GOOGLE_CALLBACK_URL}
- GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
- GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
- API_TARGET=auth
- LOG_FILE_PATH=/var/log/log.log
- JWT_SECRET=${JWT_SECRET}
restart: unless-stopped

View File

@ -6,3 +6,4 @@ include:
- ./monitoring/compose.yml
- ./api-base/compose.yml
- ./front/compose.yml
- ./ELK/compose.yml

View File

@ -25,5 +25,11 @@ COPY --chmod=755 docker/front/entry/ssl-cert.sh /docker-entrypoint.d/ssl-cert.s
COPY --from=builder /app/dist /usr/share/nginx/html
USER root
RUN mkdir -p /var/log/front
RUN touch /var/log/front/err.log /var/log/front/log.log
RUN chmod -R 777 /var/log/front
USER nginx
EXPOSE 80 443
STOPSIGNAL SIGINT

View File

@ -6,8 +6,9 @@ services:
context: ../../
ports:
- ${OUT_PORT}:443
volumes:
- log-nginx:/var/log/front
environment:
- SERVER_NAME=localhost
- TZ=Europe/Paris
depends_on:
user-api:

View File

@ -1,4 +1,7 @@
server {
error_log /var/log/front/err.log warn;
access_log /var/log/front/log.log;
listen 443 ssl;
server_name example.com; # Replace with your domain or handle env vars externally

View File

@ -24,7 +24,7 @@ scrape_configs:
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'nodejs'
static_configs:
- targets: ['transcendence-api-auth:3000']
- targets: ['transcendence-api-user:3000']
# - job_name: 'nodejs'
# static_configs:
# - targets: ['transcendence-api-auth:3000']
# - targets: ['transcendence-api-user:3000']

View File

@ -7,3 +7,7 @@ networks:
name: transcendence-prom
prom-exporter:
name: transcendence-prom-exporter
elk:
name: transcendence-elk
logstash:
name: transcendence-logstash

View File

@ -5,3 +5,9 @@ volumes:
name: transcendence-api-auth-db
db-user:
name: transcendence-api-user-db
log-auth:
name: transcendence-api-auth-log
log-user:
name: transcendence-api-user-log
log-nginx:
name: transcendence-front-log

View File

@ -9,7 +9,8 @@
"better-sqlite3": "^12.2.0",
"fastify": "^5.4.0",
"fastify-cli": "^7.4.0",
"google-auth-library": "^10.1.0",
"pino": "^9.7.0",
"pino-logstash": "^1.0.0",
"prom-client": "^15.1.3",
"solhint": "^6.0.0"
},

191
pnpm-lock.yaml generated
View File

@ -35,9 +35,12 @@ importers:
fastify-cli:
specifier: ^7.4.0
version: 7.4.0
google-auth-library:
specifier: ^10.1.0
version: 10.1.0
pino:
specifier: ^9.7.0
version: 9.7.0
pino-logstash:
specifier: ^1.0.0
version: 1.0.0
prom-client:
specifier: ^15.1.3
version: 15.1.3
@ -512,10 +515,6 @@ packages:
abstract-logging@2.0.1:
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
agent-base@7.1.4:
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
engines: {node: '>= 14'}
ajv-errors@1.0.1:
resolution: {integrity: sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==}
peerDependencies:
@ -597,9 +596,6 @@ packages:
resolution: {integrity: sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ==}
engines: {node: 20.x || 22.x || 23.x || 24.x}
bignumber.js@9.3.1:
resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==}
bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
@ -615,9 +611,6 @@ packages:
brace-expansion@2.0.2:
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
@ -692,22 +685,9 @@ packages:
typescript:
optional: true
data-uri-to-buffer@4.0.1:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
dateformat@4.6.3:
resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
debug@4.4.1:
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
@ -788,9 +768,6 @@ packages:
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
engines: {node: '>=6'}
extend@3.0.2:
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
fast-copy@3.0.2:
resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==}
@ -857,10 +834,6 @@ packages:
picomatch:
optional: true
fetch-blob@3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
file-uri-to-path@1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
@ -889,10 +862,6 @@ packages:
resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
engines: {node: '>= 6'}
formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
fs-constants@1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
@ -911,14 +880,6 @@ packages:
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
gaxios@7.1.1:
resolution: {integrity: sha512-Odju3uBUJyVCkW64nLD4wKLhbh93bh6vIg/ZIXkWiLPBrdgtc65+tls/qml+un3pr6JqYVFDZbbmLDQT68rTOQ==}
engines: {node: '>=18'}
gcp-metadata@7.0.1:
resolution: {integrity: sha512-UcO3kefx6dCcZkgcTGgVOTFb7b1LlQ02hY1omMjjrrBzkajRMCFgYOjs7J71WqnuG1k2b+9ppGL7FsOfhZMQKQ==}
engines: {node: '>=18'}
generify@4.2.0:
resolution: {integrity: sha512-b4cVhbPfbgbCZtK0dcUc1lASitXGEAIqukV5DDAyWm25fomWnV+C+a1yXvqikcRZXHN2j0pSDyj3cTfzq8pC7Q==}
hasBin: true
@ -943,14 +904,6 @@ packages:
engines: {node: '>=12'}
deprecated: Glob versions prior to v9 are no longer supported
google-auth-library@10.1.0:
resolution: {integrity: sha512-GspVjZj1RbyRWpQ9FbAXMKjFGzZwDKnUHi66JJ+tcjcu5/xYAP1pdlWotCuIkMwjfVsxxDvsGZXGLzRt72D0sQ==}
engines: {node: '>=18'}
google-logging-utils@1.1.1:
resolution: {integrity: sha512-rcX58I7nqpu4mbKztFeOAObbomBbHU2oIb/d3tJfF3dizGSApqtSwYJigGCooHdnMyQBIw8BrWyK96w3YXgr6A==}
engines: {node: '>=14'}
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
@ -965,10 +918,6 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
gtoken@8.0.0:
resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==}
engines: {node: '>=18'}
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
@ -995,10 +944,6 @@ packages:
resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==}
engines: {node: '>=10.19.0'}
https-proxy-agent@7.0.6:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
@ -1055,9 +1000,6 @@ packages:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
json-bigint@1.0.0:
resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==}
json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
@ -1080,12 +1022,6 @@ packages:
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
engines: {node: '>=0.10.0'}
jwa@2.0.1:
resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
jws@4.0.0:
resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==}
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@ -1236,9 +1172,6 @@ packages:
mnemonist@0.40.3:
resolution: {integrity: sha512-Vjyr90sJ23CKKH/qPAgUKicw/v6pRoamxIEDFOF8uSgFME7DqPRpHgRTejWVjkdGg5dXj0/NyxZHZ9bcjH+2uQ==}
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -1255,15 +1188,6 @@ packages:
resolution: {integrity: sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==}
engines: {node: ^18 || ^20 || >= 21}
node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
deprecated: Use your platform's native DOMException instead
node-fetch@3.3.2:
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
node-gyp-build@4.8.4:
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
hasBin: true
@ -1328,6 +1252,9 @@ packages:
pino-abstract-transport@2.0.0:
resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
pino-logstash@1.0.0:
resolution: {integrity: sha512-v8UCUxGROClKZW6mB0GumsfCi3gnmupMNDzh86TX9Oab9ijDjIW3vJdMjlcNaAyJK9GiJxUdLtI6amzLhpuARg==}
pino-pretty@13.0.0:
resolution: {integrity: sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==}
hasBin: true
@ -1634,10 +1561,6 @@ packages:
walker@1.0.8:
resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
web-streams-polyfill@3.3.3:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
engines: {node: '>= 8'}
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
@ -1970,8 +1893,6 @@ snapshots:
abstract-logging@2.0.1: {}
agent-base@7.1.4: {}
ajv-errors@1.0.1(ajv@6.12.6):
dependencies:
ajv: 6.12.6
@ -2057,8 +1978,6 @@ snapshots:
bindings: 1.5.0
prebuild-install: 7.1.3
bignumber.js@9.3.1: {}
bindings@1.5.0:
dependencies:
file-uri-to-path: 1.0.0
@ -2077,8 +1996,6 @@ snapshots:
dependencies:
balanced-match: 1.0.2
buffer-equal-constant-time@1.0.1: {}
buffer@5.7.1:
dependencies:
base64-js: 1.5.1
@ -2150,14 +2067,8 @@ snapshots:
optionalDependencies:
typescript: 5.8.3
data-uri-to-buffer@4.0.1: {}
dateformat@4.6.3: {}
debug@4.4.1:
dependencies:
ms: 2.1.3
decompress-response@6.0.0:
dependencies:
mimic-response: 3.1.0
@ -2253,8 +2164,6 @@ snapshots:
expand-template@2.0.3: {}
extend@3.0.2: {}
fast-copy@3.0.2: {}
fast-decode-uri-component@1.0.1: {}
@ -2352,11 +2261,6 @@ snapshots:
optionalDependencies:
picomatch: 4.0.2
fetch-blob@3.2.0:
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 3.3.3
file-uri-to-path@1.0.0: {}
find-my-way@9.3.0:
@ -2381,10 +2285,6 @@ snapshots:
hasown: 2.0.2
mime-types: 2.1.35
formdata-polyfill@4.0.10:
dependencies:
fetch-blob: 3.2.0
fs-constants@1.0.0: {}
fs-extra@11.3.0:
@ -2400,22 +2300,6 @@ snapshots:
function-bind@1.1.2: {}
gaxios@7.1.1:
dependencies:
extend: 3.0.2
https-proxy-agent: 7.0.6
node-fetch: 3.3.2
transitivePeerDependencies:
- supports-color
gcp-metadata@7.0.1:
dependencies:
gaxios: 7.1.1
google-logging-utils: 1.1.1
json-bigint: 1.0.0
transitivePeerDependencies:
- supports-color
generify@4.2.0:
dependencies:
isbinaryfile: 4.0.10
@ -2453,20 +2337,6 @@ snapshots:
minimatch: 5.1.6
once: 1.4.0
google-auth-library@10.1.0:
dependencies:
base64-js: 1.5.1
ecdsa-sig-formatter: 1.0.11
gaxios: 7.1.1
gcp-metadata: 7.0.1
google-logging-utils: 1.1.1
gtoken: 8.0.0
jws: 4.0.0
transitivePeerDependencies:
- supports-color
google-logging-utils@1.1.1: {}
gopd@1.2.0: {}
got@12.6.1:
@ -2487,13 +2357,6 @@ snapshots:
graceful-fs@4.2.11: {}
gtoken@8.0.0:
dependencies:
gaxios: 7.1.1
jws: 4.0.0
transitivePeerDependencies:
- supports-color
has-flag@4.0.0: {}
has-symbols@1.1.0: {}
@ -2515,13 +2378,6 @@ snapshots:
quick-lru: 5.1.1
resolve-alpn: 1.2.1
https-proxy-agent@7.0.6:
dependencies:
agent-base: 7.1.4
debug: 4.4.1
transitivePeerDependencies:
- supports-color
ieee754@1.2.1: {}
ignore@5.3.2: {}
@ -2560,10 +2416,6 @@ snapshots:
dependencies:
argparse: 2.0.1
json-bigint@1.0.0:
dependencies:
bignumber.js: 9.3.1
json-buffer@3.0.1: {}
json-parse-even-better-errors@2.3.1: {}
@ -2584,17 +2436,6 @@ snapshots:
jsonpointer@5.0.1: {}
jwa@2.0.1:
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
jws@4.0.0:
dependencies:
jwa: 2.0.1
safe-buffer: 5.2.1
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@ -2711,8 +2552,6 @@ snapshots:
dependencies:
obliterator: 2.0.5
ms@2.1.3: {}
nanoid@3.3.11: {}
napi-build-utils@2.0.0: {}
@ -2723,14 +2562,6 @@ snapshots:
node-addon-api@8.4.0: {}
node-domexception@1.0.0: {}
node-fetch@3.3.2:
dependencies:
data-uri-to-buffer: 4.0.1
fetch-blob: 3.2.0
formdata-polyfill: 4.0.10
node-gyp-build@4.8.4: {}
normalize-url@8.0.2: {}
@ -2785,6 +2616,8 @@ snapshots:
dependencies:
split2: 4.2.0
pino-logstash@1.0.0: {}
pino-pretty@13.0.0:
dependencies:
colorette: 2.0.20
@ -3128,8 +2961,6 @@ snapshots:
dependencies:
makeerror: 1.0.12
web-streams-polyfill@3.3.3: {}
wrappy@1.0.2: {}
xtend@4.0.2: {}

View File

@ -1,6 +1,5 @@
import fastifyJWT from '@fastify/jwt';
import fastifyCookie from '@fastify/cookie';
import client from 'prom-client';
import { register } from './register.js';
import { login } from './login.js';
@ -14,7 +13,6 @@ import { totpVerify } from './totpVerify.js';
const saltRounds = 10;
export const appName = process.env.APP_NAME || 'knl_meowscendence';
const collectDefaultMetrics = client.collectDefaultMetrics
authDB.prepareDB();
@ -24,29 +22,6 @@ authDB.prepareDB();
*/
export default async function(fastify, options) {
collectDefaultMetrics({ labels: { service: "auth-api" } })
client.register.setDefaultLabels({ service: "auth-api" })
const httpRequestCounter = new client.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
})
fastify.addHook('onResponse', (req, res, done) => {
httpRequestCounter.inc({
method: req.method,
route: req.routerPath || req.url,
status_code: res.statusCode,
})
done()
})
fastify.get('/metrics', async (req, reply) => {
reply
.header('Content-Type', client.register.contentType)
.send(await client.register.metrics())
})
fastify.register(fastifyJWT, {
secret: process.env.JWT_SECRET || '123456789101112131415161718192021',
cookie: {

View File

@ -1,10 +1,8 @@
import fastifyJWT from '@fastify/jwt';
import fastifyCookie from '@fastify/cookie';
import Database from 'better-sqlite3';
import client from 'prom-client';
var env = process.env.NODE_ENV || 'development';
const collectDefaultMetrics = client.collectDefaultMetrics
let database;
@ -58,31 +56,6 @@ const deleteFriends = database.prepare('DELETE FROM friends WHERE username = ?;'
* @param {import('fastify').FastifyPluginOptions} options
*/
export default async function(fastify, options) {
collectDefaultMetrics({ labels: { service: "auth-api" } })
client.register.setDefaultLabels({ service: "auth-api" })
const httpRequestCounter = new client.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
})
fastify.addHook('onResponse', (req, res, done) => {
httpRequestCounter.inc({
method: req.method,
route: req.routerPath || req.url,
status_code: res.statusCode,
})
done()
})
fastify.get('/metrics', async (req, reply) => {
reply
.header('Content-Type', client.register.contentType)
.send(await client.register.metrics())
})
fastify.register(fastifyJWT, {
secret: process.env.JWT_SECRET || '123456789101112131415161718192021',
cookie: {

View File

@ -1,52 +1,71 @@
import Fastify from 'fastify';
import authApi from './api/auth/default.js';
import userApi from './api/user/default.js';
import fs from 'fs';
import path from 'path';
const loggerOption = {
transport: {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'HH:MM:ss',
ignore: 'pid,hostname'
}
}
const isProduction = process.env.NODE_ENV === 'production';
const logFilePath = process.env.LOG_FILE_PATH || './logs/api.log';
const loggerOption = () => {
if (!isProduction) {
return {
transport: {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'HH:MM:ss',
ignore: 'pid,hostname',
},
},
};
} else {
// Make sure the directory exists
const logDir = path.dirname(logFilePath);
fs.mkdirSync(logDir, { recursive: true });
const logStream = fs.createWriteStream(logFilePath, { flags: 'a' }); // append mode
return {
level: 'info',
stream: logStream,
};
}
};
function sigHandle(signal) {
process.exit(0);
}
process.on('SIGINT', sigHandle);
async function start() {
const target = process.env.API_TARGET || 'all';
const servers = [];
if (target === 'auth' || target === 'all') {
const auth = Fastify({ logger: loggerOption });
const auth = Fastify({ logger: loggerOption('auth') });
auth.register(authApi);
if (target !== 'all') {
await auth.listen({ port: 3000, host: '0.0.0.0' });
console.log('Auth API listening on http://0.0.0.0:3000');
}
else {
await auth.listen({ port: 3001, host: '127.0.0.1'});
console.log('Auth API listening on http://localhost:3001');
}
const port = target === 'all' ? 3001 : 3000;
const host = target === 'all' ? '127.0.0.1' : '0.0.0.0';
await auth.listen({ port, host });
console.log(`Auth API listening on http://${host}:${port}`);
servers.push(auth);
}
if (target === 'user' || target === 'all') {
const user = Fastify({ logger: loggerOption });
const user = Fastify({ logger: loggerOption('user') });
user.register(userApi);
if (target !== 'all') {
await user.listen({ port: 3000, host: '0.0.0.0' });
console.log('User API listening on http://0.0.0.0:3000');
}
else {
await user.listen({ port: 3002, host: '127.0.0.1'});
console.log('User API listening on http://localhost:3002');
}
const port = target === 'all' ? 3002 : 3000;
const host = target === 'all' ? '127.0.0.1' : '0.0.0.0';
await user.listen({ port, host });
console.log(`User API listening on http://${host}:${port}`);
servers.push(user);
}
// Graceful shutdown on SIGINT
process.on('SIGINT', async () => {
console.log('SIGINT received, closing servers...');
await Promise.all(servers.map((srv) => srv.close()));
process.exit(0);
});
}
start().catch(console.error);
start().catch((err) => {
console.error(err);
process.exit(1);
});