Skip to content

Commit 067613f

Browse files
committed
Use common logging configuration for all services
1 parent 6b410e9 commit 067613f

10 files changed

Lines changed: 74 additions & 64 deletions

src/modality_emulator.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import datetime
2-
import logging
32
import os
43
import time
54

@@ -18,15 +17,11 @@
1817
from services.dicom import PENDING, PENDING_WARNING, SUCCESS
1918
from services.mwl import MWLStatus
2019
from services.storage import MWLStorage
20+
from telemetry import configure_logging
2121

2222
load_dotenv()
2323

24-
logging.basicConfig(
25-
level=os.getenv("LOG_LEVEL", "INFO").upper(),
26-
format=os.getenv("LOG_FORMAT", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"),
27-
)
28-
29-
logger = logging.getLogger(__name__)
24+
logger = configure_logging("Gateway-Emulator")
3025

3126

3227
DICOM_LATERALITIES = ["L", "R"]

src/mwl_main.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
"""Entry point for MWL server."""
22

3-
import logging
43
import os
54

65
from dotenv import load_dotenv
76

87
from server import MWLServer
9-
from telemetry import configure_telemetry
8+
from telemetry import configure_logging, configure_telemetry
109

1110
load_dotenv()
1211

12+
logger = configure_logging("Gateway-MWL")
13+
1314

1415
def main():
1516
"""
@@ -20,23 +21,24 @@ def main():
2021
MWL_PORT: Port to listen on (default: 4243)
2122
MWL_DB_PATH: Path to the SQLite database file (default: /var/lib/pacs/worklist.db)
2223
"""
23-
logging.basicConfig(
24-
level=os.getenv("LOG_LEVEL", "INFO").upper(),
25-
format=os.getenv("LOG_FORMAT", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"),
26-
)
27-
2824
mwl_aet = os.getenv("MWL_AET", "MWL_SCP")
2925
mwl_port = int(os.getenv("MWL_PORT", "4243"))
3026
mwl_db_path = os.getenv("MWL_DB_PATH", "/var/lib/pacs/worklist.db")
3127

32-
mwl_server = MWLServer(mwl_aet, mwl_port, mwl_db_path, block=True)
28+
mwl_server = MWLServer(
29+
ae_title=mwl_aet,
30+
port=mwl_port,
31+
db_path=mwl_db_path,
32+
logger=logger,
33+
block=True,
34+
)
3335

3436
configure_telemetry(service_name="mwl-server")
3537

3638
try:
3739
mwl_server.start()
3840
except KeyboardInterrupt:
39-
logging.info("Received shutdown signal")
41+
logger.info("Received shutdown signal")
4042
mwl_server.stop()
4143

4244

src/pacs_main.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
"""Entry point for PACS server."""
22

3-
import logging
43
import os
54

65
from dotenv import load_dotenv
76

87
from server import PACSServer
9-
from telemetry import configure_telemetry
8+
from telemetry import configure_logging, configure_telemetry
109

1110
load_dotenv()
1211

12+
logger = configure_logging("Gateway-PACS")
13+
1314

1415
def main():
1516
"""
@@ -21,25 +22,28 @@ def main():
2122
PACS_STORAGE_PATH: Path to store incoming DICOM files (default: /var/lib/pacs/storage)
2223
PACS_DB_PATH: Path to the SQLite database file (default: /var/lib/pacs/pacs.db)
2324
"""
24-
logging.basicConfig(
25-
level=os.getenv("LOG_LEVEL", "INFO").upper(),
26-
format=os.getenv("LOG_FORMAT", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"),
27-
)
28-
2925
pacs_aet = os.getenv("PACS_AET", "SCREENING_PACS")
3026
pacs_port = int(os.getenv("PACS_PORT", "4244"))
3127
pacs_storage_path = os.getenv("PACS_STORAGE_PATH", "/var/lib/pacs/storage")
3228
pacs_db_path = os.getenv("PACS_DB_PATH", "/var/lib/pacs/pacs.db")
3329
mwl_db_path = os.getenv("MWL_DB_PATH", "/var/lib/pacs/worklist.db")
3430

35-
pacs_server = PACSServer(pacs_aet, pacs_port, pacs_storage_path, pacs_db_path, block=True, mwl_db_path=mwl_db_path)
31+
pacs_server = PACSServer(
32+
ae_title=pacs_aet,
33+
port=pacs_port,
34+
storage_path=pacs_storage_path,
35+
db_path=pacs_db_path,
36+
logger=logger,
37+
block=True,
38+
mwl_db_path=mwl_db_path,
39+
)
3640

3741
configure_telemetry(service_name="pacs-server")
3842

3943
try:
4044
pacs_server.start()
4145
except KeyboardInterrupt:
42-
logging.info("Received shutdown signal")
46+
logger.info("Received shutdown signal")
4347
pacs_server.stop()
4448

4549

src/relay_listener.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import hashlib
1010
import hmac
1111
import json
12-
import logging
1312
import os
1413
import time
1514
import urllib.parse
@@ -23,11 +22,11 @@
2322
from services.mwl.create_worklist_item import CreateWorklistItem
2423
from services.mwl.update_worklist_item_status import UpdateWorklistItemStatus
2524
from services.storage import MWLStorage
26-
from telemetry import configure_telemetry
25+
from telemetry import configure_logging, configure_telemetry
2726

2827
load_dotenv()
2928

30-
logger = logging.getLogger(__name__)
29+
logger = configure_logging("Gateway-Relay")
3130

3231
DB_PATH = os.getenv("MWL_DB_PATH", "/var/lib/pacs/worklist.db")
3332
AZURE_RELAY_SCOPE = "https://relay.azure.net/.default"
@@ -174,13 +173,9 @@ def verify_credentials():
174173

175174

176175
async def main():
177-
logging.basicConfig(
178-
level=os.getenv("LOG_LEVEL", "INFO").upper(),
179-
format=os.getenv("LOG_FORMAT", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"),
180-
)
181176
configure_telemetry(service_name="relay-listener")
182177

183-
logger.info("Socket Listener Starting...")
178+
logger.info("Gateway Relay Listener Starting...")
184179
verify_credentials()
185180
storage = MWLStorage(db_path=DB_PATH)
186181

src/server.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(
3636
port: int = 4244,
3737
storage_path: str = "/var/lib/pacs/storage",
3838
db_path: str = "/var/lib/pacs/pacs.db",
39+
logger: logging.Logger = logger,
3940
block: bool = True,
4041
mwl_db_path: str = "/var/lib/pacs/worklist.db",
4142
):
@@ -54,11 +55,12 @@ def __init__(
5455
self.storage = PACSStorage(db_path, storage_path)
5556
self.mwl_storage = MWLStorage(mwl_db_path)
5657
self.ae = None
58+
self.logger = logger
5759
self.block = block
5860

5961
def start(self):
6062
"""Start the PACS server and listen for incoming connections."""
61-
logger.info(f"Starting PACS server: {self.ae_title} on port {self.port}")
63+
self.logger.info(f"Starting PACS server: {self.ae_title} on port {self.port}")
6264

6365
transfer_syntaxes = [
6466
dicom_uid.JPEGLosslessSV1, # Hologic preferred
@@ -78,16 +80,16 @@ def start(self):
7880
(evt.EVT_C_STORE, CStore(self.storage, mwl_storage=self.mwl_storage).call),
7981
]
8082

81-
logger.info(f"PACS server listening on 0.0.0.0:{self.port}")
82-
logger.info(f"Storage: {self.storage.storage_root}")
83-
logger.info(f"Database: {self.storage.db_path}")
83+
self.logger.info(f"PACS server listening on 0.0.0.0:{self.port}")
84+
self.logger.info(f"Storage: {self.storage.storage_root}")
85+
self.logger.info(f"Database: {self.storage.db_path}")
8486

8587
self.ae.start_server(("0.0.0.0", self.port), block=self.block, evt_handlers=handlers) # type: ignore
8688

8789
def stop(self):
8890
"""Stop the PACS server."""
8991
if self.ae:
90-
logger.info("Stopping PACS server")
92+
self.logger.info("Stopping PACS server")
9193
self.ae.shutdown()
9294
self.storage.close()
9395

@@ -100,6 +102,7 @@ def __init__(
100102
ae_title: str = "MWL_SCP",
101103
port: int = 4243,
102104
db_path: str = "/var/lib/pacs/worklist.db",
105+
logger: logging.Logger = logger,
103106
block: bool = True,
104107
):
105108
"""
@@ -115,11 +118,12 @@ def __init__(
115118
self.port = port
116119
self.storage = MWLStorage(db_path)
117120
self.ae = None
121+
self.logger = logger
118122
self.block = block
119123

120124
def start(self):
121125
"""Start the MWL server."""
122-
logger.info(f"Starting MWL server: {self.ae_title} on port {self.port}")
126+
self.logger.info(f"Starting MWL server: {self.ae_title} on port {self.port}")
123127

124128
self.ae = AE(ae_title=self.ae_title)
125129
self.ae.add_supported_context(Verification)
@@ -133,13 +137,13 @@ def start(self):
133137
(evt.EVT_N_SET, NSet(self.storage).call),
134138
]
135139

136-
logger.info(f"MWL server listening on 0.0.0.0:{self.port}")
137-
logger.info(f"Database: {self.storage.db_path}")
140+
self.logger.info(f"MWL server listening on 0.0.0.0:{self.port}")
141+
self.logger.info(f"Database: {self.storage.db_path}")
138142

139143
self.ae.start_server(("0.0.0.0", self.port), block=self.block, evt_handlers=handlers) # type: ignore
140144

141145
def stop(self):
142146
"""Stop the MWL server."""
143147
if self.ae:
144-
logger.info("Stopping MWL server")
148+
self.logger.info("Stopping MWL server")
145149
self.ae.shutdown()

src/upload_main.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Entry point for DICOM upload listener service."""
22

3-
import logging
43
import os
54

65
from dotenv import load_dotenv
@@ -9,7 +8,7 @@
98
from services.dicom.upload_listener import UploadListener
109
from services.dicom.upload_processor import UploadProcessor
1110
from services.storage import MWLStorage, PACSStorage
12-
from telemetry import configure_telemetry
11+
from telemetry import configure_logging, configure_telemetry
1312

1413
load_dotenv()
1514

@@ -28,10 +27,7 @@ def main():
2827
UPLOAD_POLL_INTERVAL: Time in seconds between polling for new uploads (default: 2)
2928
UPLOAD_BATCH_SIZE: Number of pending uploads to process in each batch (default: 10)
3029
"""
31-
logging.basicConfig(
32-
level=os.getenv("LOG_LEVEL", "INFO").upper(),
33-
format=os.getenv("LOG_FORMAT", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"),
34-
)
30+
logger = configure_logging("Gateway-Upload")
3531

3632
poll_interval = float(os.getenv("UPLOAD_POLL_INTERVAL", "2"))
3733
batch_size = int(os.getenv("UPLOAD_BATCH_SIZE", "10"))
@@ -56,24 +52,24 @@ def main():
5652
batch_size=batch_size,
5753
)
5854

59-
logging.info("=" * 60)
60-
logging.info("Starting DICOM upload listener service")
61-
logging.info("=" * 60)
62-
logging.info(f"PACS DB: {pacs_storage.db_path}")
63-
logging.info(f"Worklist DB: {mwl_storage.db_path}")
64-
logging.info(f"Storage: {pacs_storage.storage_root}")
65-
logging.info(f"Poll interval: {poll_interval}s")
66-
logging.info(f"Batch size: {batch_size}")
67-
logging.info(f"Max retries: {max_retries}")
68-
logging.info(f"API endpoint: {uploader.api_endpoint}")
69-
logging.info("=" * 60)
55+
logger.info("=" * 60)
56+
logger.info("Starting DICOM upload listener service")
57+
logger.info("=" * 60)
58+
logger.info(f"PACS DB: {pacs_storage.db_path}")
59+
logger.info(f"Worklist DB: {mwl_storage.db_path}")
60+
logger.info(f"Storage: {pacs_storage.storage_root}")
61+
logger.info(f"Poll interval: {poll_interval}s")
62+
logger.info(f"Batch size: {batch_size}")
63+
logger.info(f"Max retries: {max_retries}")
64+
logger.info(f"API endpoint: {uploader.api_endpoint}")
65+
logger.info("=" * 60)
7066

7167
configure_telemetry(service_name="upload-listener")
7268

7369
try:
7470
listener.start()
7571
except KeyboardInterrupt:
76-
logging.info("Received shutdown signal")
72+
logger.info("Received shutdown signal")
7773
listener.stop()
7874

7975

tests/integration/test_end_to_end_relay_to_upload.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77

88
import json
9+
import logging
910
from unittest.mock import Mock, patch
1011

1112
import pytest
@@ -81,6 +82,7 @@ def mwl_server(self, mwl_storage):
8182
server.port = 4243
8283
server.storage = mwl_storage
8384
server.ae = None
85+
server.logger = logging.getLogger("MWLServer")
8486
server.block = False
8587
return server
8688

@@ -93,6 +95,7 @@ def pacs_server(self, pacs_storage, mwl_storage):
9395
server.storage = pacs_storage
9496
server.mwl_storage = mwl_storage
9597
server.ae = None
98+
server.logger = logging.getLogger("PACSServer")
9699
server.block = False
97100
return server
98101

tests/scripts/test_database.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import pytest
21
import sqlite3
32
import sys
43
from pathlib import Path
54

5+
import pytest
6+
67
sys.path.append(f"{Path(__file__).parent.parent.parent}/scripts/python")
78

89
from database import backup_database, reset_worklist_database

tests/test_relay_listener.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ async def test_main_handles_connection_closed_and_keyboard_interrupt(
252252
await main()
253253

254254
assert relay_listener_instance.listen.call_count == 3
255-
mock_logger.info.assert_any_call("Socket Listener Starting...")
255+
mock_logger.info.assert_any_call("Gateway Relay Listener Starting...")
256256
mock_logger.warning.assert_any_call("Connection closed with code 1011: Something went wrong")
257257
mock_logger.warning.assert_any_call("Retrying in 5 seconds...")
258258
mock_logger.warning.assert_any_call("Connection closed with code 1014: Bad gateway")

tests/test_server.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,23 @@
1717
@patch(f"{PACSServer.__module__}.PACSStorage")
1818
class TestPACSServer:
1919
def test_init(self, mock_pacs_storage, mock_mwl_storage, tmp_dir):
20+
mock_logger = MagicMock()
2021
subject = PACSServer(
21-
"Custom AE Title", 2222, tmp_dir, f"{tmp_dir}/test.db", False, mwl_db_path=f"{tmp_dir}/worklist.db"
22+
"Custom AE Title",
23+
2222,
24+
tmp_dir,
25+
f"{tmp_dir}/test.db",
26+
logger=mock_logger,
27+
block=False,
28+
mwl_db_path=f"{tmp_dir}/worklist.db",
2229
)
2330

2431
assert subject.ae_title == "Custom AE Title"
2532
assert subject.port == 2222
2633
assert subject.storage == mock_pacs_storage.return_value
2734
assert subject.mwl_storage == mock_mwl_storage.return_value
2835
assert subject.ae is None
36+
assert subject.logger == mock_logger
2937
assert subject.block is False
3038

3139
mock_pacs_storage.assert_called_once_with(f"{tmp_dir}/test.db", tmp_dir)
@@ -80,12 +88,14 @@ def test_stop(self, *_):
8088
@patch(f"{MWLServer.__module__}.MWLStorage")
8189
class TestMWLServer:
8290
def test_init(self, mock_storage):
83-
subject = MWLServer("CUSTOM_MWL", 11112, "/custom/path/worklist.db", False)
91+
mock_logger = MagicMock()
92+
subject = MWLServer("CUSTOM_MWL", 11112, "/custom/path/worklist.db", logger=mock_logger, block=False)
8493

8594
assert subject.ae_title == "CUSTOM_MWL"
8695
assert subject.port == 11112
8796
assert subject.storage == mock_storage.return_value
8897
assert subject.ae is None
98+
assert subject.logger == mock_logger
8999
assert subject.block is False
90100

91101
mock_storage.assert_called_once_with("/custom/path/worklist.db")

0 commit comments

Comments
 (0)