Skip to content

Commit 182b647

Browse files
Fix issue #374
Signed-off-by: Deepanshu Tiwari <tiwarideepanshu235@gmail.com>
1 parent d289de1 commit 182b647

5 files changed

Lines changed: 99 additions & 9 deletions

File tree

collectoss/api/gunicorn_conf.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@
4242
logs_directory = get_value('Logging', 'logs_directory')
4343

4444
# this syntax satisfies the type checker
45-
is_docker = SystemEnv.get_bool("AUGUR_DOCKER_DEPLOY", False)
45+
is_docker = SystemEnv.get_bool("COLLECTOSS_DOCKER_DEPLOY", False)
4646
accesslog = f"{logs_directory}/gunicorn.log"
4747
errorlog = f"{logs_directory}/gunicorn.log"
4848

49-
# If deploying via docker, include gunicorn error logs in the docker log stream by sending it to stdout
49+
# If deploying via Docker, include Gunicorn error logs in the Docker log stream.
5050
if is_docker:
5151
errorlog = '-'
5252

@@ -69,4 +69,3 @@
6969
def worker_exit(server, worker):
7070
print("Stopping gunicorn worker process")
7171
dispose_database_engine()
72-
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# SPDX-License-Identifier: MIT
2+
"""
3+
Helpers for starting Gunicorn from CollectOSS CLI commands.
4+
"""
5+
from __future__ import annotations
6+
7+
import os
8+
from typing import Optional
9+
10+
from collectoss.application.environment import SystemEnv
11+
12+
13+
def is_docker_deploy() -> bool:
14+
return SystemEnv.get_bool("COLLECTOSS_DOCKER_DEPLOY", False)
15+
16+
17+
def build_gunicorn_command(
18+
gunicorn_config: str,
19+
host: str,
20+
port: str,
21+
app: str = "collectoss.api.server:app",
22+
log_file: Optional[str] = None,
23+
docker_deploy: Optional[bool] = None,
24+
) -> list[str]:
25+
"""
26+
Build a Gunicorn command while preserving Docker stderr logging.
27+
28+
In Docker, Gunicorn's config sends error logs to "-" so failures are visible
29+
through container logs. Passing --log-file would override that setting.
30+
"""
31+
command = [
32+
"gunicorn",
33+
"-c",
34+
gunicorn_config,
35+
"-b",
36+
f"{host}:{port}",
37+
app,
38+
]
39+
40+
if docker_deploy is None:
41+
docker_deploy = is_docker_deploy()
42+
43+
if log_file and not docker_deploy:
44+
command.extend(["--log-file", os.fspath(log_file)])
45+
46+
return command

collectoss/application/cli/api.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from collectoss.application.logs import SystemLogger
1717
from collectoss.application.cli import test_connection, test_db_connection, with_database, DatabaseContext
1818
from collectoss.application.cli._cli_util import _broadcast_signal_to_processes, raise_open_file_limit, clear_redis_caches, clear_rabbitmq_messages
19+
from collectoss.application.cli._gunicorn import build_gunicorn_command
1920
from collectoss.application.db.lib import get_value
2021
from collectoss.application.environment import SystemEnv
2122

@@ -61,8 +62,8 @@ def start(ctx, development, port):
6162
if not port:
6263
port = get_value("Server", "port")
6364

64-
gunicorn_command = f"gunicorn -c {gunicorn_location} -b {host}:{port} collectoss.api.server:app --log-file gunicorn.log"
65-
server = subprocess.Popen(gunicorn_command.split(" "))
65+
gunicorn_command = build_gunicorn_command(gunicorn_location, host, str(port), log_file="gunicorn.log")
66+
server = subprocess.Popen(gunicorn_command)
6667

6768
time.sleep(3)
6869
logger.info('Gunicorn webserver started...')
@@ -154,5 +155,3 @@ def is_api_process(process):
154155
return True
155156

156157
return False
157-
158-

collectoss/application/cli/backend.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from collectoss.application.service_manager import SystemServiceManager, cleanup_collection_status_and_rabbit, clean_collection_status
2929
from collectoss.application.db.lib import get_value
3030
from collectoss.application.cli import test_connection, test_db_connection, with_database, DatabaseContext
31+
from collectoss.application.cli._gunicorn import build_gunicorn_command
3132
import sqlalchemy as s
3233

3334
from keyman.KeyClient import KeyClient, KeyPublisher
@@ -104,8 +105,8 @@ def start(ctx, disable_collection, development, pidfile, port):
104105
log_dir = get_value("Logging", "logs_directory") or "."
105106
gunicorn_log_file = os.path.join(log_dir, "gunicorn.log")
106107

107-
gunicorn_command = f"gunicorn -c {gunicorn_location} -b {host}:{port} collectoss.api.server:app --log-file {gunicorn_log_file}"
108-
server = subprocess.Popen(gunicorn_command.split(" "))
108+
gunicorn_command = build_gunicorn_command(gunicorn_location, host, str(port), log_file=gunicorn_log_file)
109+
server = subprocess.Popen(gunicorn_command)
109110
manager.server = server
110111

111112
logger.info("awaiting Gunicorn start")
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# SPDX-License-Identifier: MIT
2+
"""Tests for Gunicorn CLI command construction."""
3+
4+
from collectoss.application.cli._gunicorn import build_gunicorn_command
5+
6+
7+
def test_gunicorn_command_uses_log_file_outside_docker():
8+
command = build_gunicorn_command(
9+
"/collectoss/collectoss/api/gunicorn_conf.py",
10+
"0.0.0.0",
11+
"5000",
12+
log_file="/collectoss/logs/gunicorn.log",
13+
docker_deploy=False,
14+
)
15+
16+
assert command == [
17+
"gunicorn",
18+
"-c",
19+
"/collectoss/collectoss/api/gunicorn_conf.py",
20+
"-b",
21+
"0.0.0.0:5000",
22+
"collectoss.api.server:app",
23+
"--log-file",
24+
"/collectoss/logs/gunicorn.log",
25+
]
26+
27+
28+
def test_gunicorn_command_does_not_override_docker_errorlog():
29+
command = build_gunicorn_command(
30+
"/collectoss/collectoss/api/gunicorn_conf.py",
31+
"0.0.0.0",
32+
"5000",
33+
log_file="/collectoss/logs/gunicorn.log",
34+
docker_deploy=True,
35+
)
36+
37+
assert "--log-file" not in command
38+
assert command == [
39+
"gunicorn",
40+
"-c",
41+
"/collectoss/collectoss/api/gunicorn_conf.py",
42+
"-b",
43+
"0.0.0.0:5000",
44+
"collectoss.api.server:app",
45+
]

0 commit comments

Comments
 (0)