Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2023973

Browse files
Add ddog logger.
1 parent e50e95b commit 2023973

File tree

6 files changed

+1358
-157
lines changed

6 files changed

+1358
-157
lines changed

‎config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Config:
1313

1414
# General Config
1515
ENVIRONMENT = environ.get("ENVIRONMENT")
16+
APP_NAME = "flask_sqlalchemy_tutorial"
1617

1718
# Flask Config
1819
FLASK_APP = "wsgi.py"
@@ -23,3 +24,6 @@ class Config:
2324
SQLALCHEMY_DATABASE_URI = environ.get("SQLALCHEMY_DATABASE_URI")
2425
SQLALCHEMY_ECHO = False
2526
SQLALCHEMY_TRACK_MODIFICATIONS = False
27+
28+
29+
settings = Config

‎gunicorn.conf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
bind = ["127.0.0.1:8000"]
2525
elif ENVIRONMENT == "production":
2626
daemon = True
27-
accesslog = "/var/log/flasksession/access.log"
28-
errorlog = "/var/log/flasksession/error.log"
27+
accesslog = "/var/log/flasksqlalchemy/access.log"
28+
errorlog = "/var/log/flasksqlalchemy/error.log"
2929
loglevel = "trace"
30-
dogstatsd_tags = "env:prod,service:flasksession,language:python"
30+
dogstatsd_tags = "env:prod,service:flasksqlalchemy,language:python"
3131
else:
3232
raise ValueError(f"Unknown environment provided: `{ENVIRONMENT}`. Must be `development` or `production`.")

‎logger.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
"""Custom logger."""
2+
3+
import json
4+
from os import path
5+
from sys import stdout
6+
7+
from loguru import logger
8+
9+
from config import settings
10+
11+
12+
def json_formatter(record: dict) -> str:
13+
"""
14+
Pass raw log to be serialized.
15+
16+
:param dict record: Dictionary containing logged message with metadata.
17+
18+
:returns: str
19+
"""
20+
21+
def serialize(log: dict) -> str:
22+
"""
23+
Parse log message into Datadog JSON format.
24+
25+
:param dict log: Dictionary containing logged message with metadata.
26+
27+
:returns: str
28+
"""
29+
subset = {
30+
"time": log["time"].strftime("%m/%d/%Y, %H:%M:%S"),
31+
"message": log["message"],
32+
"level": log["level"].name,
33+
"function": log.get("function"),
34+
"module": log.get("name"),
35+
}
36+
if log.get("exception", None):
37+
subset.update({"exception": log["exception"]})
38+
return json.dumps(subset)
39+
40+
record["extra"]["serialized"] = serialize(record)
41+
return "{extra[serialized]},\n"
42+
43+
44+
def log_formatter(record: dict) -> str:
45+
"""
46+
Formatter for .log records
47+
48+
:param dict record: Key/value object containing log message & metadata.
49+
50+
:returns: str
51+
"""
52+
if record["level"].name == "TRACE":
53+
return "<fg #5278a3>{time:MM-DD-YYYY HH:mm:ss}</fg #5278a3> | <fg #d2eaff>{level}</fg #d2eaff>: <light-white>{message}</light-white>\n"
54+
if record["level"].name == "INFO":
55+
return "<fg #5278a3>{time:MM-DD-YYYY HH:mm:ss}</fg #5278a3> | <fg #98bedf>{level}</fg #98bedf>: <light-white>{message}</light-white>\n"
56+
if record["level"].name == "WARNING":
57+
return "<fg #5278a3>{time:MM-DD-YYYY HH:mm:ss}</fg #5278a3> | <fg #b09057>{level}</fg #b09057>: <light-white>{message}</light-white>\n"
58+
if record["level"].name == "SUCCESS":
59+
return "<fg #5278a3>{time:MM-DD-YYYY HH:mm:ss}</fg #5278a3> | <fg #6dac77>{level}</fg #6dac77>: <light-white>{message}</light-white>\n"
60+
if record["level"].name == "ERROR":
61+
return "<fg #5278a3>{time:MM-DD-YYYY HH:mm:ss}</fg #5278a3> | <fg #a35252>{level}</fg #a35252>: <light-white>{message}</light-white>\n"
62+
if record["level"].name == "CRITICAL":
63+
return "<fg #5278a3>{time:MM-DD-YYYY HH:mm:ss}</fg #5278a3> | <fg #521010>{level}</fg #521010>: <light-white>{message}</light-white>\n"
64+
return "<fg #5278a3>{time:MM-DD-YYYY HH:mm:ss}</fg #5278a3> | <fg #98bedf>{level}</fg #98bedf>: <light-white>{message}</light-white>\n"
65+
66+
67+
def create_logger() -> logger:
68+
"""
69+
Configure custom logger.
70+
71+
:returns: logger
72+
"""
73+
logger.remove()
74+
logger.add(
75+
stdout,
76+
colorize=True,
77+
catch=True,
78+
level="TRACE",
79+
format=log_formatter,
80+
)
81+
if settings.ENVIRONMENT == "production" and path.isdir(f"/var/log/{settings.APP_NAME}"):
82+
# Datadog JSON logs
83+
logger.add(
84+
f"/var/log/{settings.APP_NAME}/info.json",
85+
format=json_formatter,
86+
rotation="200 MB",
87+
level="TRACE",
88+
compression="zip",
89+
)
90+
# Readable logs
91+
logger.add(
92+
f"/var/log/{settings.APP_NAME}/info.log",
93+
colorize=True,
94+
catch=True,
95+
level="TRACE",
96+
format=log_formatter,
97+
rotation="200 MB",
98+
compression="zip",
99+
)
100+
else:
101+
logger.add(
102+
"./logs/error.log",
103+
colorize=True,
104+
catch=True,
105+
format=log_formatter,
106+
rotation="200 MB",
107+
compression="zip",
108+
level="ERROR",
109+
)
110+
return logger
111+
112+
113+
# Custom logger
114+
LOGGER = create_logger()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /