mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Merge branch 'dev/api_logging' of github.com:makeplane/plane into dev/api_logging
This commit is contained in:
commit
58d82313cc
1
.gitignore
vendored
1
.gitignore
vendored
@ -51,6 +51,7 @@ staticfiles
|
|||||||
mediafiles
|
mediafiles
|
||||||
.env
|
.env
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
logs/
|
||||||
|
|
||||||
node_modules/
|
node_modules/
|
||||||
assets/dist/
|
assets/dist/
|
||||||
|
@ -63,4 +63,3 @@ WEB_URL="http://localhost"
|
|||||||
|
|
||||||
# Gunicorn Workers
|
# Gunicorn Workers
|
||||||
GUNICORN_WORKERS=2
|
GUNICORN_WORKERS=2
|
||||||
|
|
||||||
|
@ -1,26 +1,27 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
import zoneinfo
|
import logging
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
import zoneinfo
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import IntegrityError
|
|
||||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||||
|
from django.db import IntegrityError
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework.permissions import IsAuthenticated
|
|
||||||
from rest_framework import status
|
|
||||||
from sentry_sdk import capture_exception
|
from sentry_sdk import capture_exception
|
||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from plane.api.middleware.api_authentication import APIKeyAuthentication
|
from plane.api.middleware.api_authentication import APIKeyAuthentication
|
||||||
from plane.api.rate_limit import ApiKeyRateThrottle
|
from plane.api.rate_limit import ApiKeyRateThrottle
|
||||||
from plane.utils.paginator import BasePaginator
|
|
||||||
from plane.bgtasks.webhook_task import send_webhook
|
from plane.bgtasks.webhook_task import send_webhook
|
||||||
|
from plane.utils.paginator import BasePaginator
|
||||||
|
|
||||||
|
|
||||||
class TimezoneMixin:
|
class TimezoneMixin:
|
||||||
@ -104,6 +105,35 @@ class BaseAPIView(TimezoneMixin, APIView, BasePaginator):
|
|||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if isinstance(e, ValidationError):
|
||||||
|
return Response(
|
||||||
|
{"error": "Please provide valid detail"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(e, ObjectDoesNotExist):
|
||||||
|
model_name = str(exc).split(" matching query does not exist.")[
|
||||||
|
0
|
||||||
|
]
|
||||||
|
return Response(
|
||||||
|
{"error": f"{model_name} does not exist."},
|
||||||
|
status=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(e, KeyError):
|
||||||
|
return Response(
|
||||||
|
{"error": f"key {e} does not exist"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger("plane")
|
||||||
|
logger.error(e)
|
||||||
|
capture_exception(e)
|
||||||
|
return Response(
|
||||||
|
{"error": "Something went wrong please try again later"},
|
||||||
|
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
)
|
||||||
|
|
||||||
if isinstance(e, ValidationError):
|
if isinstance(e, ValidationError):
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
import csv
|
import csv
|
||||||
import io
|
import io
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Third party imports
|
||||||
|
from celery import shared_task
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.core.mail import EmailMultiAlternatives, get_connection
|
from django.core.mail import EmailMultiAlternatives, get_connection
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.html import strip_tags
|
from django.utils.html import strip_tags
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
# Third party imports
|
|
||||||
from celery import shared_task
|
|
||||||
from sentry_sdk import capture_exception
|
from sentry_sdk import capture_exception
|
||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from plane.db.models import Issue
|
from plane.db.models import Issue
|
||||||
|
from plane.license.utils.instance_value import get_email_configuration
|
||||||
from plane.utils.analytics_plot import build_graph_plot
|
from plane.utils.analytics_plot import build_graph_plot
|
||||||
from plane.utils.issue_filters import issue_filters
|
from plane.utils.issue_filters import issue_filters
|
||||||
from plane.license.utils.instance_value import get_email_configuration
|
|
||||||
|
|
||||||
row_mapping = {
|
row_mapping = {
|
||||||
"state__name": "State",
|
"state__name": "State",
|
||||||
@ -210,9 +211,9 @@ def generate_segmented_rows(
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
if assignee:
|
if assignee:
|
||||||
generated_row[
|
generated_row[0] = (
|
||||||
0
|
f"{assignee['assignees__first_name']} {assignee['assignees__last_name']}"
|
||||||
] = f"{assignee['assignees__first_name']} {assignee['assignees__last_name']}"
|
)
|
||||||
|
|
||||||
if x_axis == LABEL_ID:
|
if x_axis == LABEL_ID:
|
||||||
label = next(
|
label = next(
|
||||||
@ -279,9 +280,9 @@ def generate_segmented_rows(
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
if assignee:
|
if assignee:
|
||||||
row_zero[
|
row_zero[index + 2] = (
|
||||||
index + 2
|
f"{assignee['assignees__first_name']} {assignee['assignees__last_name']}"
|
||||||
] = f"{assignee['assignees__first_name']} {assignee['assignees__last_name']}"
|
)
|
||||||
|
|
||||||
if segmented == LABEL_ID:
|
if segmented == LABEL_ID:
|
||||||
for index, segm in enumerate(row_zero[2:]):
|
for index, segm in enumerate(row_zero[2:]):
|
||||||
@ -366,9 +367,9 @@ def generate_non_segmented_rows(
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
if assignee:
|
if assignee:
|
||||||
row[
|
row[0] = (
|
||||||
0
|
f"{assignee['assignees__first_name']} {assignee['assignees__last_name']}"
|
||||||
] = f"{assignee['assignees__first_name']} {assignee['assignees__last_name']}"
|
)
|
||||||
|
|
||||||
if x_axis == LABEL_ID:
|
if x_axis == LABEL_ID:
|
||||||
label = next(
|
label = next(
|
||||||
@ -506,8 +507,7 @@ def analytic_export_task(email, data, slug):
|
|||||||
send_export_email(email, slug, csv_buffer, rows)
|
send_export_email(email, slug, csv_buffer, rows)
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
logger = logging.getLogger("plane")
|
||||||
if settings.DEBUG:
|
logger.error(e)
|
||||||
print(e)
|
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return
|
return
|
||||||
|
@ -4,6 +4,8 @@ import io
|
|||||||
import json
|
import json
|
||||||
import boto3
|
import boto3
|
||||||
import zipfile
|
import zipfile
|
||||||
|
import logging
|
||||||
|
from urllib.parse import urlparse, urlunparse
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -403,8 +405,7 @@ def issue_export_task(
|
|||||||
exporter_instance.status = "failed"
|
exporter_instance.status = "failed"
|
||||||
exporter_instance.reason = str(e)
|
exporter_instance.reason = str(e)
|
||||||
exporter_instance.save(update_fields=["status", "reason"])
|
exporter_instance.save(update_fields=["status", "reason"])
|
||||||
# Print logs if in DEBUG mode
|
logger = logging.getLogger("plane")
|
||||||
if settings.DEBUG:
|
logger.error(e)
|
||||||
print(e)
|
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return
|
return
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
# Python import
|
# Python imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Third party imports
|
||||||
|
from celery import shared_task
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.core.mail import EmailMultiAlternatives, get_connection
|
from django.core.mail import EmailMultiAlternatives, get_connection
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.html import strip_tags
|
from django.utils.html import strip_tags
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
# Third party imports
|
|
||||||
from celery import shared_task
|
|
||||||
from sentry_sdk import capture_exception
|
from sentry_sdk import capture_exception
|
||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
@ -62,8 +62,7 @@ def forgot_password(first_name, email, uidb64, token, current_site):
|
|||||||
msg.send()
|
msg.send()
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Print logs if in DEBUG mode
|
logger = logging.getLogger("plane")
|
||||||
if settings.DEBUG:
|
logger.error(e)
|
||||||
print(e)
|
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return
|
return
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
import logging
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -1668,8 +1669,7 @@ def issue_activity(
|
|||||||
|
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Print logs if in DEBUG mode
|
logger = logging.getLogger("plane")
|
||||||
if settings.DEBUG:
|
logger.error(e)
|
||||||
print(e)
|
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return
|
return
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
import json
|
import json
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
@ -96,8 +97,8 @@ def archive_old_issues():
|
|||||||
]
|
]
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if settings.DEBUG:
|
logger = logging.getLogger("plane")
|
||||||
print(e)
|
logger.error(e)
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -179,7 +180,7 @@ def close_old_issues():
|
|||||||
]
|
]
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if settings.DEBUG:
|
logger = logging.getLogger("plane")
|
||||||
print(e)
|
logger.error(e)
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return
|
return
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Third party imports
|
||||||
|
from celery import shared_task
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.core.mail import EmailMultiAlternatives, get_connection
|
from django.core.mail import EmailMultiAlternatives, get_connection
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.html import strip_tags
|
from django.utils.html import strip_tags
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
# Third party imports
|
|
||||||
from celery import shared_task
|
|
||||||
from sentry_sdk import capture_exception
|
from sentry_sdk import capture_exception
|
||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
@ -54,9 +55,7 @@ def magic_link(email, key, token, current_site):
|
|||||||
msg.send()
|
msg.send()
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
logger = logging.getLogger("plane")
|
||||||
|
logger.error(e)
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
# Print logs if in DEBUG mode
|
|
||||||
if settings.DEBUG:
|
|
||||||
print(e)
|
|
||||||
return
|
return
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
# Python import
|
# Python imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Third party imports
|
||||||
|
from celery import shared_task
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.core.mail import EmailMultiAlternatives, get_connection
|
from django.core.mail import EmailMultiAlternatives, get_connection
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.html import strip_tags
|
from django.utils.html import strip_tags
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
# Third party imports
|
|
||||||
from celery import shared_task
|
|
||||||
from sentry_sdk import capture_exception
|
from sentry_sdk import capture_exception
|
||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from plane.db.models import Project, User, ProjectMemberInvite
|
from plane.db.models import Project, ProjectMemberInvite, User
|
||||||
from plane.license.utils.instance_value import get_email_configuration
|
from plane.license.utils.instance_value import get_email_configuration
|
||||||
|
|
||||||
|
|
||||||
@ -77,8 +77,7 @@ def project_invitation(email, project_id, token, current_site, invitor):
|
|||||||
except (Project.DoesNotExist, ProjectMemberInvite.DoesNotExist):
|
except (Project.DoesNotExist, ProjectMemberInvite.DoesNotExist):
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Print logs if in DEBUG mode
|
logger = logging.getLogger("plane")
|
||||||
if settings.DEBUG:
|
logger.error(e)
|
||||||
print(e)
|
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return
|
return
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Third party imports
|
||||||
|
from celery import shared_task
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.core.mail import EmailMultiAlternatives, get_connection
|
from django.core.mail import EmailMultiAlternatives, get_connection
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.html import strip_tags
|
from django.utils.html import strip_tags
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
# Third party imports
|
|
||||||
from celery import shared_task
|
|
||||||
from sentry_sdk import capture_exception
|
from sentry_sdk import capture_exception
|
||||||
|
|
||||||
# Module imports
|
# Module imports
|
||||||
from plane.db.models import Workspace, WorkspaceMemberInvite, User
|
from plane.db.models import User, Workspace, WorkspaceMemberInvite
|
||||||
from plane.license.utils.instance_value import get_email_configuration
|
from plane.license.utils.instance_value import get_email_configuration
|
||||||
|
|
||||||
|
|
||||||
@ -82,8 +82,7 @@ def workspace_invitation(email, workspace_id, token, current_site, invitor):
|
|||||||
print("Workspace or WorkspaceMember Invite Does not exists")
|
print("Workspace or WorkspaceMember Invite Does not exists")
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Print logs if in DEBUG mode
|
logger = logging.getLogger("plane")
|
||||||
if settings.DEBUG:
|
logger.error(e)
|
||||||
print(e)
|
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
return
|
return
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
import uuid
|
|
||||||
import string
|
|
||||||
import random
|
import random
|
||||||
|
import string
|
||||||
|
import uuid
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
|
from django.contrib.auth.models import (
|
||||||
|
AbstractBaseUser,
|
||||||
|
PermissionsMixin,
|
||||||
|
UserManager,
|
||||||
|
)
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import (
|
|
||||||
AbstractBaseUser,
|
|
||||||
UserManager,
|
|
||||||
PermissionsMixin,
|
|
||||||
)
|
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
@ -3,19 +3,20 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
import os
|
import os
|
||||||
import ssl
|
import ssl
|
||||||
import certifi
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
# Django imports
|
import certifi
|
||||||
from django.core.management.utils import get_random_secret_key
|
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
import dj_database_url
|
import dj_database_url
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
|
|
||||||
|
# Django imports
|
||||||
|
from django.core.management.utils import get_random_secret_key
|
||||||
|
from sentry_sdk.integrations.celery import CeleryIntegration
|
||||||
from sentry_sdk.integrations.django import DjangoIntegration
|
from sentry_sdk.integrations.django import DjangoIntegration
|
||||||
from sentry_sdk.integrations.redis import RedisIntegration
|
from sentry_sdk.integrations.redis import RedisIntegration
|
||||||
from sentry_sdk.integrations.celery import CeleryIntegration
|
|
||||||
|
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
@ -345,3 +346,49 @@ INSTANCE_KEY = os.environ.get(
|
|||||||
SKIP_ENV_VAR = os.environ.get("SKIP_ENV_VAR", "1") == "1"
|
SKIP_ENV_VAR = os.environ.get("SKIP_ENV_VAR", "1") == "1"
|
||||||
|
|
||||||
DATA_UPLOAD_MAX_MEMORY_SIZE = int(os.environ.get("FILE_SIZE_LIMIT", 5242880))
|
DATA_UPLOAD_MAX_MEMORY_SIZE = int(os.environ.get("FILE_SIZE_LIMIT", 5242880))
|
||||||
|
|
||||||
|
LOG_DIR = os.path.join(BASE_DIR, "logs")
|
||||||
|
|
||||||
|
if not os.path.exists(LOG_DIR):
|
||||||
|
os.makedirs(LOG_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
LOGGING = {
|
||||||
|
"version": 1,
|
||||||
|
"disable_existing_loggers": False,
|
||||||
|
"formatters": {
|
||||||
|
"verbose": {
|
||||||
|
"format": "{levelname} {asctime} {module} {process:d} {thread:d} {message}",
|
||||||
|
"style": "{",
|
||||||
|
},
|
||||||
|
"json": {
|
||||||
|
"()": "pythonjsonlogger.jsonlogger.JsonFormatter",
|
||||||
|
"fmt": "%(levelname)s %(asctime)s %(module)s %(name)s %(message)s",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"handlers": {
|
||||||
|
"console": {
|
||||||
|
"class": "logging.StreamHandler",
|
||||||
|
"formatter": "verbose",
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"class": "logging.handlers.TimedRotatingFileHandler",
|
||||||
|
"filename": (
|
||||||
|
os.path.join(BASE_DIR, "logs", "debug.log")
|
||||||
|
if DEBUG
|
||||||
|
else os.path.join(BASE_DIR, "logs", "error.log")
|
||||||
|
),
|
||||||
|
"when": "midnight",
|
||||||
|
"interval": 1, # One day
|
||||||
|
"backupCount": 5, # Keep last 5 days of logs,
|
||||||
|
"formatter": "json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"loggers": {
|
||||||
|
"plane": {
|
||||||
|
"level": "DEBUG" if DEBUG else "ERROR",
|
||||||
|
"handlers": ["console", "file"],
|
||||||
|
"propagate": False,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -90,6 +90,8 @@ services:
|
|||||||
command: ./bin/takeoff
|
command: ./bin/takeoff
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${API_REPLICAS:-1}
|
replicas: ${API_REPLICAS:-1}
|
||||||
|
volumes:
|
||||||
|
- logs/api:/code/plane/logs
|
||||||
depends_on:
|
depends_on:
|
||||||
- plane-db
|
- plane-db
|
||||||
- plane-redis
|
- plane-redis
|
||||||
@ -100,6 +102,8 @@ services:
|
|||||||
pull_policy: ${PULL_POLICY:-always}
|
pull_policy: ${PULL_POLICY:-always}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: ./bin/worker
|
command: ./bin/worker
|
||||||
|
volumes:
|
||||||
|
- logs/worker:/code/plane/logs
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
- plane-db
|
- plane-db
|
||||||
@ -111,6 +115,8 @@ services:
|
|||||||
pull_policy: ${PULL_POLICY:-always}
|
pull_policy: ${PULL_POLICY:-always}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: ./bin/beat
|
command: ./bin/beat
|
||||||
|
volumes:
|
||||||
|
- logs/beat-worker:/code/plane/logs
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
- plane-db
|
- plane-db
|
||||||
@ -169,3 +175,4 @@ volumes:
|
|||||||
pgdata:
|
pgdata:
|
||||||
redisdata:
|
redisdata:
|
||||||
uploads:
|
uploads:
|
||||||
|
logs:
|
||||||
|
Loading…
Reference in New Issue
Block a user