SlimG commited on
Commit
3dea1ba
·
1 Parent(s): ff2d34e

improve logging

Browse files
src/entity/api/fraud_prediction_api.py CHANGED
@@ -1,9 +1,4 @@
1
  from pydantic import BaseModel
2
- import logging
3
-
4
- # Set up logging
5
- logging.basicConfig(level=logging.INFO)
6
- logger = logging.getLogger(__name__)
7
 
8
  class FraudPredictionInput(BaseModel):
9
  """
 
1
  from pydantic import BaseModel
 
 
 
 
 
2
 
3
  class FraudPredictionInput(BaseModel):
4
  """
src/entity/api/transaction_api.py CHANGED
@@ -5,7 +5,6 @@ from src.entity.transaction import Transaction
5
  import logging
6
 
7
  # Set up logging
8
- logging.basicConfig(level=logging.INFO)
9
  logger = logging.getLogger(__name__)
10
 
11
  class TransactionApi(BaseModel):
 
5
  import logging
6
 
7
  # Set up logging
 
8
  logger = logging.getLogger(__name__)
9
 
10
  class TransactionApi(BaseModel):
src/main.py CHANGED
@@ -28,19 +28,24 @@ from sqlalchemy.orm import Session
28
 
29
  from src.entity.api.transaction_api import TransactionApi
30
  from src.service.fraud_service import check_for_fraud_api
 
31
  from src.service.notification_service import send_notification
32
  from src.repository.common import get_session
33
  from src.repository.fraud_details_repo import insert_fraud
34
  from src.repository.transaction_repo import insert_transaction
35
 
36
  # ------------------------------------------------------------------------------
 
 
 
37
 
 
38
  def provide_connection() -> Generator[Session, None, None]:
39
  with get_session() as conn:
40
  yield conn
41
 
42
  # ------------------------------------------------------------------------------
43
-
44
  load_dotenv()
45
  FASTAPI_API_KEY = os.getenv("FASTAPI_API_KEY")
46
  FRAUD_ML_API_KEY = os.getenv("FRAUD_ML_API_KEY")
@@ -123,19 +128,19 @@ async def process_transaction(
123
  # Insert every single transaction into the database
124
  transaction = insert_transaction(db, transaction)
125
  except UniqueViolation as e:
126
- logging.error(e)
127
  raise HTTPException(
128
  status_code=HTTP_422_UNPROCESSABLE_ENTITY,
129
  detail=f"Transaction {transaction.transaction_number} already exists"
130
  )
131
  except IntegrityError as e:
132
- logging.error(e)
133
  raise HTTPException(
134
  status_code=HTTP_422_UNPROCESSABLE_ENTITY,
135
  detail=f"Transaction {transaction.transaction_number} is not valid. Check input values."
136
  )
137
  except Exception as e:
138
- logging.error(e)
139
  raise HTTPException(
140
  status_code=HTTP_500_INTERNAL_SERVER_ERROR,
141
  detail="An error occurred while processing the transaction. See logs for details."
@@ -176,7 +181,7 @@ async def check_health(session: Annotated[Session, Depends(provide_connection)])
176
  try:
177
  session.execute(text("SELECT 1"))
178
  except Exception as e:
179
- logging.error(f"DB check failed: {e}")
180
  return JSONResponse(content={"status": "unhealthy"}, status_code=HTTP_503_SERVICE_UNAVAILABLE)
181
 
182
  # Check if the fraud detection API is alive
@@ -187,7 +192,7 @@ async def check_health(session: Annotated[Session, Depends(provide_connection)])
187
  })
188
 
189
  if response.status_code != HTTP_200_OK:
190
- logging.error(f"Fraud detection API check failed: {response.status_code} - {response.text}")
191
  return JSONResponse(content={"status": "unhealthy"}, status_code=HTTP_503_SERVICE_UNAVAILABLE)
192
 
193
  return JSONResponse(content={"status": "healthy"}, status_code=HTTP_200_OK)
 
28
 
29
  from src.entity.api.transaction_api import TransactionApi
30
  from src.service.fraud_service import check_for_fraud_api
31
+ from src.service.logging_service import setup_logging
32
  from src.service.notification_service import send_notification
33
  from src.repository.common import get_session
34
  from src.repository.fraud_details_repo import insert_fraud
35
  from src.repository.transaction_repo import insert_transaction
36
 
37
  # ------------------------------------------------------------------------------
38
+ # Configure logging
39
+ setup_logging()
40
+ logger = logging.getLogger(__name__)
41
 
42
+ # ------------------------------------------------------------------------------
43
  def provide_connection() -> Generator[Session, None, None]:
44
  with get_session() as conn:
45
  yield conn
46
 
47
  # ------------------------------------------------------------------------------
48
+ # Load environment variables
49
  load_dotenv()
50
  FASTAPI_API_KEY = os.getenv("FASTAPI_API_KEY")
51
  FRAUD_ML_API_KEY = os.getenv("FRAUD_ML_API_KEY")
 
128
  # Insert every single transaction into the database
129
  transaction = insert_transaction(db, transaction)
130
  except UniqueViolation as e:
131
+ logger.error(e)
132
  raise HTTPException(
133
  status_code=HTTP_422_UNPROCESSABLE_ENTITY,
134
  detail=f"Transaction {transaction.transaction_number} already exists"
135
  )
136
  except IntegrityError as e:
137
+ logger.error(e)
138
  raise HTTPException(
139
  status_code=HTTP_422_UNPROCESSABLE_ENTITY,
140
  detail=f"Transaction {transaction.transaction_number} is not valid. Check input values."
141
  )
142
  except Exception as e:
143
+ logger.error(e)
144
  raise HTTPException(
145
  status_code=HTTP_500_INTERNAL_SERVER_ERROR,
146
  detail="An error occurred while processing the transaction. See logs for details."
 
181
  try:
182
  session.execute(text("SELECT 1"))
183
  except Exception as e:
184
+ logger.error(f"DB check failed: {e}")
185
  return JSONResponse(content={"status": "unhealthy"}, status_code=HTTP_503_SERVICE_UNAVAILABLE)
186
 
187
  # Check if the fraud detection API is alive
 
192
  })
193
 
194
  if response.status_code != HTTP_200_OK:
195
+ logger.error(f"Fraud detection API check failed: {response.status_code} - {response.text}")
196
  return JSONResponse(content={"status": "unhealthy"}, status_code=HTTP_503_SERVICE_UNAVAILABLE)
197
 
198
  return JSONResponse(content={"status": "healthy"}, status_code=HTTP_200_OK)
src/repository/transaction_repo.py CHANGED
@@ -5,6 +5,7 @@ from sqlalchemy.orm import joinedload
5
  from typing import Optional
6
  from src.entity.transaction import Transaction
7
 
 
8
 
9
  def fetch_transaction(db: Connection, transaction_id: int) -> Optional[Transaction]:
10
  """
@@ -17,7 +18,7 @@ def fetch_transaction(db: Connection, transaction_id: int) -> Optional[Transacti
17
  if transaction is None:
18
  raise ValueError(f"Transaction {transaction_id} not found")
19
  else:
20
- logging.info(f"Transaction {transaction_id} found")
21
 
22
  return transaction
23
 
 
5
  from typing import Optional
6
  from src.entity.transaction import Transaction
7
 
8
+ logger = logging.getLogger(__name__)
9
 
10
  def fetch_transaction(db: Connection, transaction_id: int) -> Optional[Transaction]:
11
  """
 
18
  if transaction is None:
19
  raise ValueError(f"Transaction {transaction_id} not found")
20
  else:
21
+ logger.info(f"Transaction {transaction_id} found")
22
 
23
  return transaction
24
 
src/service/fraud_service.py CHANGED
@@ -14,7 +14,6 @@ FRAUD_ML_API_KEY = os.getenv("FRAUD_ML_API_KEY")
14
  FRAUD_ML_PREDICTION_ENDPOINT = os.getenv("FRAUD_ML_PREDICTION_ENDPOINT")
15
 
16
  # Configure logging
17
- logging.basicConfig(level=logging.DEBUG)
18
  logger = logging.getLogger(__name__)
19
 
20
  def check_for_fraud_api(transaction: Transaction) -> Optional[FraudPredictionOutput]:
 
14
  FRAUD_ML_PREDICTION_ENDPOINT = os.getenv("FRAUD_ML_PREDICTION_ENDPOINT")
15
 
16
  # Configure logging
 
17
  logger = logging.getLogger(__name__)
18
 
19
  def check_for_fraud_api(transaction: Transaction) -> Optional[FraudPredictionOutput]:
src/service/logging_service.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import logging.config
3
+
4
+ LOGGING_CONFIG = {
5
+ 'version': 1,
6
+ 'disable_existing_loggers': False,
7
+ 'formatters': {
8
+ 'default': {
9
+ 'format': '[%(asctime)s] %(levelname)s in %(name)s: %(message)s',
10
+ },
11
+ 'verbose': {
12
+ 'format': '[%(asctime)s] %(levelname)s [%(name)s:%(lineno)d] %(message)s',
13
+ },
14
+ },
15
+ 'handlers': {
16
+ 'console': {
17
+ 'class': 'logging.StreamHandler',
18
+ 'formatter': 'default',
19
+ },
20
+ # Exemple fichier
21
+ 'file': {
22
+ 'class': 'logging.FileHandler',
23
+ 'filename': 'app.log',
24
+ 'formatter': 'verbose',
25
+ },
26
+ },
27
+ 'root': {
28
+ 'handlers': ['console', 'file'],
29
+ 'level': 'INFO',
30
+ },
31
+ 'loggers': {
32
+ 'myapp': {
33
+ 'handlers': ['console'],
34
+ 'level': 'DEBUG',
35
+ 'propagate': False,
36
+ },
37
+ }
38
+ }
39
+
40
+ def setup_logging():
41
+ logging.config.dictConfig(LOGGING_CONFIG)
src/service/notification_service.py CHANGED
@@ -10,7 +10,6 @@ from src.repository.transaction_repo import fetch_transaction
10
  from dotenv import load_dotenv
11
 
12
  # Configure logging
13
- logging.basicConfig(level=logging.DEBUG)
14
  logger = logging.getLogger(__name__)
15
 
16
  # Load environment variables
@@ -57,7 +56,7 @@ def send_notification(transaction_id: int):
57
  model_version=transaction.fraud_details.model_version,
58
  )
59
 
60
- logging.info("Email sent!")
61
 
62
  # Update the transaction details in the database
63
  transaction.fraud_details.notification_sent = True
@@ -105,7 +104,7 @@ def _send_with_smtp_server(transaction_number: str,
105
  msg.set_content(email_body)
106
 
107
  # Send the email
108
- logging.debug(f"Connecting to SMTP server {SMTP_SERVER} using port {SMTP_PORT}...")
109
  with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
110
  server.starttls() # Secure the connection
111
  server.login(SENDER_EMAIL, SENDER_PASSWORD)
 
10
  from dotenv import load_dotenv
11
 
12
  # Configure logging
 
13
  logger = logging.getLogger(__name__)
14
 
15
  # Load environment variables
 
56
  model_version=transaction.fraud_details.model_version,
57
  )
58
 
59
+ logger.info("Email sent!")
60
 
61
  # Update the transaction details in the database
62
  transaction.fraud_details.notification_sent = True
 
104
  msg.set_content(email_body)
105
 
106
  # Send the email
107
+ logger.debug(f"Connecting to SMTP server {SMTP_SERVER} using port {SMTP_PORT}...")
108
  with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
109
  server.starttls() # Secure the connection
110
  server.login(SENDER_EMAIL, SENDER_PASSWORD)