Skip to content

Commit 5656e47

Browse files
authored
Merge pull request #192 from PROCOLLAB-github/dev
Grafana, логгирование, фильтрация по имени и фамилии, доработка сериалайзеров личных чатов
2 parents 9e13647 + 7aa5bed commit 5656e47

17 files changed

Lines changed: 430 additions & 55 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ coverage.xml
5858

5959
# Django stuff:
6060
*.log
61+
*.log.zip
6162
local_settings.py
6263
*.sqlite3
6364
*.sqlite3-journal

chats/serializers.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212

1313
class DirectChatListSerializer(serializers.ModelSerializer):
1414
last_message = serializers.SerializerMethodField()
15-
users = serializers.SerializerMethodField(read_only=True)
15+
opponent = serializers.SerializerMethodField()
1616

17-
@classmethod
18-
def get_users(cls, chat: ProjectChat):
19-
return UserListSerializer(chat.get_users(), many=True).data
17+
def get_opponent(self, chat: DirectChat):
18+
user = self.context.get("opponent")
19+
return UserDetailSerializer(user).data
2020

2121
@classmethod
2222
def get_last_message(cls, chat: DirectChat):
@@ -26,23 +26,23 @@ class Meta:
2626
model = DirectChat
2727
fields = [
2828
"id",
29-
"users",
29+
"opponent",
3030
"last_message",
3131
]
3232

3333

3434
class DirectChatDetailSerializer(serializers.ModelSerializer):
35-
users = serializers.SerializerMethodField(read_only=True)
35+
opponent = serializers.SerializerMethodField()
3636

37-
@classmethod
38-
def get_users(cls, chat: ProjectChat):
39-
return UserListSerializer(chat.get_users(), many=True).data
37+
def get_opponent(self, chat: DirectChat):
38+
user = self.context.get("opponent")
39+
return UserDetailSerializer(user).data
4040

4141
class Meta:
4242
model = DirectChat
4343
fields = [
4444
"id",
45-
"users",
45+
"opponent",
4646
]
4747

4848

chats/views.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ def get_queryset(self):
3636
user = self.request.user
3737
return user.direct_chats.all()
3838

39+
def get(self, request, *args, **kwargs):
40+
chats = self.get_queryset()
41+
serialized_chats = []
42+
for chat in chats:
43+
# fixme: move to function like get_user() and get_opponent()
44+
chat_id = chat.id
45+
user1_id, user2_id = map(int, chat_id.split("_"))
46+
47+
try:
48+
user1 = User.objects.get(pk=user1_id)
49+
user2 = User.objects.get(pk=user2_id)
50+
except User.DoesNotExist:
51+
# fixme: show deleted profile
52+
continue
53+
54+
if user1 == request.user:
55+
opponent = user2
56+
else: # fixme: if user1 == user2
57+
opponent = user1
58+
59+
context = {"opponent": opponent}
60+
serialized_chat = DirectChatListSerializer(chat, context=context).data
61+
serialized_chats.append(serialized_chat)
62+
return Response(serialized_chats, status=status.HTTP_200_OK)
63+
3964

4065
class ProjectChatList(ListAPIView):
4166
serializer_class = ProjectChatListSerializer
@@ -70,16 +95,17 @@ def get(self, request, *args, **kwargs) -> Response:
7095
user1 = User.objects.get(pk=user1_id)
7196
user2 = User.objects.get(pk=user2_id)
7297

73-
data = DirectChatDetailSerializer(DirectChat.get_chat(user1, user2)).data
74-
7598
if user1 == request.user:
76-
# may be is better to use serializer or return dict -
77-
# {"first_name": user2.first_name, "last_name": user2.last_name}
78-
data["name"] = f"{user2.first_name} {user2.last_name}"
79-
data["image_address"] = user2.avatar
99+
opponent = user2
80100
else:
81-
data["name"] = f"{user1.first_name} {user1.last_name}"
82-
data["image_address"] = user1.avatar
101+
opponent = user1
102+
context = {"opponent": opponent}
103+
data = DirectChatDetailSerializer(
104+
DirectChat.get_chat(user1, user2), context=context
105+
).data
106+
107+
data["name"] = f"{opponent.first_name} {opponent.last_name}"
108+
data["image_address"] = opponent.avatar
83109

84110
return Response(
85111
status=status.HTTP_200_OK,

core/log/middleware.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from loguru import logger
2+
from django.conf import settings
3+
import logging
4+
from core.log.utils import InterceptHandler
5+
6+
7+
class CustomLoguruMiddleware:
8+
def __init__(self, get_response):
9+
self.get_response = get_response
10+
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
11+
12+
if settings.DEBUG:
13+
logger.add(
14+
f"{settings.BASE_DIR}/log/debug.log",
15+
level="DEBUG",
16+
**settings.LOGURU_LOGGING,
17+
)
18+
logger.add(
19+
f"{settings.BASE_DIR}/log/info.log",
20+
level="INFO",
21+
**settings.LOGURU_LOGGING,
22+
)
23+
logger.add(
24+
f"{settings.BASE_DIR}/log/warning.log",
25+
level="WARNING",
26+
**settings.LOGURU_LOGGING,
27+
)
28+
29+
def __call__(self, request):
30+
response = self.get_response(request)
31+
logger.info(f"{request.method} {request.get_full_path()}")
32+
return response
33+
34+
def process_exception(self, request, exception):
35+
logger.warning(f"{exception} http_path={request.get_full_path()}")

core/log/utils.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import logging
2+
import sys
3+
from loguru import logger
4+
5+
6+
class InterceptHandler(logging.Handler):
7+
def emit(self, record):
8+
try:
9+
level = logger.level(record.levelname).name
10+
except ValueError:
11+
level = record.levelno
12+
13+
frame, depth = sys._getframe(6), 6
14+
while frame and frame.f_code.co_filename == logging.__file__:
15+
frame = frame.f_back
16+
depth += 1
17+
18+
logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())

docker-compose.dev-ci.yml

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,60 @@
1-
version: "3.4"
1+
version: '3.9'
2+
23
services:
3-
server:
4-
ports:
5-
- "8000:8000"
4+
web:
5+
container_name: web
66
build:
77
context: .
8-
dockerfile: Dockerfile
8+
dockerfile: ./Dockerfile
9+
image: ghcr.io/procollab-github/api:latest
10+
restart: always
11+
volumes:
12+
- log:/procollab/log
913
env_file:
1014
- .env
11-
restart: always
12-
networks:
13-
template-network:
14-
15-
networks:
16-
template-network:
17-
15+
environment:
16+
HOST: 0.0.0.0
17+
grafana:
18+
container_name: grafana
19+
image: grafana/grafana:latest
20+
ports:
21+
- "3000"
22+
volumes:
23+
- grafana-data:/var/lib/grafana
24+
- grafana-configs:/etc/grafana
25+
environment:
26+
- GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana
27+
- GF_SERVER_SERVE_FROM_SUB_PATH=true
28+
prometheus:
29+
container_name: prometheus
30+
image: prom/prometheus:v2.36.0
31+
ports:
32+
- "9090"
33+
volumes:
34+
- prom-data:/prometheus
35+
- ./prometheus:/etc/prometheus
36+
node-exporter:
37+
container_name: node-exporter
38+
image: prom/node-exporter:v1.3.1
39+
ports:
40+
- "9100"
41+
volumes:
42+
- /proc:/host/proc:ro
43+
- /sys:/host/sys:ro
44+
- /:/rootfs:ro
45+
command:
46+
- '--path.procfs=/host/proc'
47+
- '--path.sysfs=/host/sys'
48+
- '--collector.filesystem.mount-points-exclude'
49+
- '^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)'
50+
nginx:
51+
container_name: nginx
52+
build: ./nginx
53+
ports:
54+
- 8000:80
1855
volumes:
19-
db-volume:
56+
grafana-data:
57+
grafana-configs:
58+
prom-data:
59+
prom-configs:
60+
log:

docker-compose.prod-ci.yml

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,60 @@
1-
version: "3.4"
1+
version: '3.9'
2+
23
services:
3-
server:
4-
ports:
5-
- "8000:8000"
4+
web:
5+
container_name: web
6+
build:
7+
context: .
8+
dockerfile: ./Dockerfile
69
image: ghcr.io/procollab-github/api:latest
10+
restart: always
11+
volumes:
12+
- log:/procollab/log
713
env_file:
814
- .env
9-
restart: always
10-
networks:
11-
template-network:
12-
13-
networks:
14-
template-network:
15-
15+
environment:
16+
HOST: 0.0.0.0
17+
grafana:
18+
container_name: grafana
19+
image: grafana/grafana:latest
20+
ports:
21+
- "3000"
22+
volumes:
23+
- grafana-data:/var/lib/grafana
24+
- grafana-configs:/etc/grafana
25+
environment:
26+
- GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana
27+
- GF_SERVER_SERVE_FROM_SUB_PATH=true
28+
prometheus:
29+
container_name: prometheus
30+
image: prom/prometheus:v2.36.0
31+
ports:
32+
- "9090"
33+
volumes:
34+
- prom-data:/prometheus
35+
- ./prometheus:/etc/prometheus
36+
node-exporter:
37+
container_name: node-exporter
38+
image: prom/node-exporter:v1.3.1
39+
ports:
40+
- "9100"
41+
volumes:
42+
- /proc:/host/proc:ro
43+
- /sys:/host/sys:ro
44+
- /:/rootfs:ro
45+
command:
46+
- '--path.procfs=/host/proc'
47+
- '--path.sysfs=/host/sys'
48+
- '--collector.filesystem.mount-points-exclude'
49+
- '^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)'
50+
nginx:
51+
container_name: nginx
52+
build: ./nginx
53+
ports:
54+
- 8000:80
1655
volumes:
17-
db-volume:
56+
grafana-data:
57+
grafana-configs:
58+
prom-data:
59+
prom-configs:
60+
log:

docker-compose.yml

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,59 @@ version: '3.9'
22

33
services:
44
web:
5+
container_name: web
56
build:
67
context: .
78
dockerfile: ./Dockerfile
8-
ports:
9-
- "8000:8000"
109
image: ghcr.io/procollab-github/api:latest
1110
restart: always
11+
volumes:
12+
- log:/procollab/log
1213
env_file:
1314
- .env
1415
environment:
15-
HOST: 0.0.0.0
16+
HOST: 0.0.0.0
17+
grafana:
18+
container_name: grafana
19+
image: grafana/grafana:latest
20+
ports:
21+
- "3000"
22+
volumes:
23+
- grafana-data:/var/lib/grafana
24+
- grafana-configs:/etc/grafana
25+
environment:
26+
- GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana
27+
- GF_SERVER_SERVE_FROM_SUB_PATH=true
28+
prometheus:
29+
container_name: prometheus
30+
image: prom/prometheus:v2.36.0
31+
ports:
32+
- "9090"
33+
volumes:
34+
- prom-data:/prometheus
35+
- ./prometheus:/etc/prometheus
36+
node-exporter:
37+
container_name: node-exporter
38+
image: prom/node-exporter:v1.3.1
39+
ports:
40+
- "9100"
41+
volumes:
42+
- /proc:/host/proc:ro
43+
- /sys:/host/sys:ro
44+
- /:/rootfs:ro
45+
command:
46+
- '--path.procfs=/host/proc'
47+
- '--path.sysfs=/host/sys'
48+
- '--collector.filesystem.mount-points-exclude'
49+
- '^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)'
50+
nginx:
51+
container_name: nginx
52+
build: ./nginx
53+
ports:
54+
- 8000:80
55+
volumes:
56+
grafana-data:
57+
grafana-configs:
58+
prom-data:
59+
prom-configs:
60+
log:

nginx/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM nginx:1.21-alpine
2+
3+
RUN rm /etc/nginx/conf.d/default.conf
4+
COPY nginx.conf /etc/nginx/conf.d

0 commit comments

Comments
 (0)