2 ๋ถ„ ์†Œ์š”

๋กœ๊ทธ๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค๋Š” ๋ง์ด ๋ญ˜๊นŒ?

์ „๋ฌธ์ ์œผ๋กœ ์กด์žฌํ•˜๋Š” ๋‹จ์–ด๋Š” ์•„๋‹ˆ๊ณ , ๊ทธ๋ƒฅ ์Šค์Šค๋กœ ์ง€์€ ๋ง์ด๊ธด ํ•จ..!

๋‚ด๊ฐ€ ์ƒ๊ฐํ•œ ๋กœ๊ทธ์˜ ๋ถ„๋ฆฌ๋ž€, API ๋ณ„๋กœ ๋กœ๊ทธ ํŒŒ์ผ์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์‹ถ๋‹ค๋Š” ๋ง์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค๋ฉด ํ•˜๋‚˜์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ, ๋‘ ๊ฐ€์ง€์˜ ์„œ๋น„์Šค๊ฐ€ ๊ฒฐํ•ฉ๋œ ํ˜•ํƒœ์ผ ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ์—”๋“œํฌ์ธํŠธ๊ฐ€ ๋‘๊ฐ€์ง€ ๊ฐˆ๋ž˜๊ธธ๋กœ ๋‚˜๋ˆ ์ง€๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•˜๊ณ , /api/endpoint-1, /api/endpoint-2 ๋ฅผ ๊ธฐ์ ์œผ๋กœ ๋‘ ๊ฐ€์ง€์˜ ์„œ๋น„์Šค๋ฅผ ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์˜๋ฏธํ•œ๋‹ค!

์™œ ์ด๋ ‡๊ฒŒ ํ•˜๋Š”๊ฐ€? ๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ๊ฐ€ ์• ์ดˆ์— ์ด๋ ‡๊ฒŒ ๋˜์–ด์žˆ์—ˆ๊ณ , ์ด๊ฒŒ ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉํ–ฅ์ธ์ง€ ์•„๋‹Œ์ง€๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ๊ธฐ๋„ ํ•˜๊ณ , ๋ฆฌํŒฉํ† ๋ง ํ•˜๊ธฐ์—๋„ ์‹œ๊ฐ„์ด ๋„ˆ๋ฌด ๋งŽ์ด ์†Œ์š”๋  ๊ฒƒ ๊ฐ™์•„์„œ ์ผ๋‹จ ๊ทธ๋Œ€๋กœ..

๊ทธ๋ž˜์„œ ์–ด๋–ป๊ฒŒ ํ•˜๋Š”๋ฐ?

์šฐ์„  ์ง€๊ธˆ ์ง„ํ–‰ ์ค‘์ธ ํ”„๋กœ์ ํŠธ๋Š” aptifit ์ด๋ผ๋Š” ํ”„๋กœ์ ํŠธ์™€ dashboard ํ”„๋กœ์ ํŠธ ๋‘ ๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค.

์ด ๋‘ ํ”„๋กœ์ ํŠธ๊ฐ€ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋‚ด์šฉ์ฒ˜๋Ÿผ ํ•˜๋‚˜์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์—์„œ ์ž‘์„ฑ๋˜์—ˆ๋‹ค.

์ฆ‰ django ํ”„๋กœ์ ํŠธ์—์„œ ๋‘ ๊ฐ€์ง€์˜ app์ด ์žˆ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋ผ๊ณ  ๋ณด๋ฉด ๋  ๋“ฏ ํ•˜๋‹ค. (์‹ค์ œ๋กœ๋Š” ํ•˜๋‚˜์˜ app์— ์กด์žฌํ•˜๊ธด ํ•˜์ง€๋งŒ..!)

์ด ๋•Œ ํ•˜๋‚˜์˜ ๋กœ๊ทธ ํŒŒ์ผ์—์„œ ๋‘ ์•ฑ์— ๋Œ€ํ•œ ๋กœ๊ทธ๋“ค์„ ๋ชจ๋‘ ๊ด€๋ฆฌํ•˜๋ฉด( DEBUG, INFO, WARNING, ERROR, CRITICAL ๋ ˆ๋ฒจ์˜ ๋กœ๊ทธ) ์–ด๋–ค ์•ฑ์—์„œ ์ฐํžŒ ๋กœ๊ทธ์ธ์ง€ ํ•œ ๋ˆˆ์— ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šธ ๊ฒƒ ๊ฐ™์•„์„œ ๋กœ๊ทธ ํŒŒ์ผ์„ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•ด๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค.

์šฐ์„  ๊ฐ€์žฅ ๋จผ์ € ChatGPT์—๊ฒŒ ๋ฌผ์–ด๋ดค๋‹ค.

๐Ÿ—ฃ๏ธย ย ์–ด๋–ค api์—์„œ๋Š” a.log ํŒŒ์ผ์— ๋กœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , ๋˜ ๋‹ค๋ฅธ api์—์„œ๋Š” b.log ํŒŒ์ผ์— ๋กœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์–ด.

์˜ˆ๋ฅผ ๋“ค๋ฉด views_.py ํŒŒ์ผ๋“ค์€ aptifit.log, dashboard_.py์—๋Š” dashboard.log ํŒŒ์ผ์—

1. ๋ณ„๋„ Logger ์ด๋ฆ„์„ ์ง์ ‘ ์„ค์ •ํ•˜๊ธฐ

๊ฐ ํŒŒ์ผ์—์„œ logger = logging.getLogger(<๊ทธ๋ฃน๋ช…>) ์„ ์“ฐ๊ณ , settings.py์˜ LOGGING์— ํ•ด๋‹น ๊ทธ๋ฃน์šฉ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ถ„๋ฆฌํ•ด ์ฃผ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

# views_orders.py
import logging
logger = logging.getLogger('aptifit')   # โ†’ aptifit.log ๋กœ ๊ฐ„๋‹ค

def order_view(...):
    logger.info("Order view called")
    ...

# dashboard_students.py
import logging
logger = logging.getLogger('dashboard')  # โ†’ dashboard.log ๋กœ ๊ฐ„๋‹ค

def students(...):
    logger.error("Student lookup error", exc_info=True)
    ...

# settings.py

import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(asctime)s %(levelname)-8s %(name)s %(message)s'
        },
    },
    'handlers': {
        'aptifit_file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'logs/aptifit.log'),
            'formatter': 'verbose',
        },
        'dashboard_file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'logs/dashboard.log'),
            'formatter': 'verbose',
        },
    },
    'loggers': {
        # getLogger('aptifit') โ†’ aptifit_file
        'aptifit': {
            'handlers': ['aptifit_file'],
            'level': 'DEBUG',
            'propagate': False,
        },
        # getLogger('dashboard') โ†’ dashboard_file
        'dashboard': {
            'handlers': ['dashboard_file'],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

์ ์šฉํ•ด๋ณด์ž!

settings.py


LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,   # Django ๊ธฐ๋ณธ ๋กœ๊ฑฐ ์œ ์ง€
    "formatters": {
        "custom": {
            "format": "[{asctime}] [{filename}:{lineno}] [{levelname}] {message}",
            "style": "{",
            "datefmt": "%Y-%m-%d %H:%M:%S",
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "custom",
            "level": "WARNING",
        },
        "aptifit_file": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "formatter": "custom",
            "filename": os.path.join(LOG_DIR, "aptifit.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 7,
            "encoding": "utf-8",
            "level": "DEBUG",
        },
        "dashboard_file": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "formatter": "custom",
            "filename": os.path.join(LOG_DIR, "dashboard.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 7,
            "encoding": "utf-8",
            "level": "DEBUG",
        },
    },
    "loggers": {
        # root: WARNING ์ด์ƒ๋งŒ ์ฝ˜์†”๋กœ
        "": {
            "handlers": ["console"],
            "level": "INFO",
            "propagate": False,
        },
        # Django ์ž์ฒด ๋กœ๊ทธ๋„ WARNING ์ด์ƒ๋งŒ ์ฝ˜์†”
        "django": {
            "handlers": ["console"],
            "level": "INFO",
            "propagate": False,
        },
        # views_*.py ์—์„œ getLogger('aptifit') ํ˜ธ์ถœ ์‹œ
        "aptifit": {
            "handlers": ["console", "aptifit_file"],
            "level": "DEBUG",
            "propagate": False,
        },
        # dashboard_*.py ์—์„œ getLogger('dashboard') ํ˜ธ์ถœ ์‹œ
        "dashboard": {
            "handlers": ["console", "dashboard_file"],
            "level": "DEBUG",
            "propagate": False,
        },
    },
}

views.py

import logging

logger = logging.getLogger("aptifit")

...

import logging

logger = logging.getLogger("dashboard")

...

๋ถ„๋ฆฌํ•˜๊ณ ์ž ํ•˜๋Š” views๋ฅผ ๊ฐ๊ฐ ์œ„์ฒ˜๋Ÿผ getLogger({log_file_name}) ์ฒ˜๋Ÿผ ์ž‘์„ฑํ•˜๊ณ , ํ•„์š”ํ•œ ๊ณณ์— ๋กœ๊ทธ๋ฅผ ์ฐ์œผ๋ฉด?

Image

์ด๋ ‡๊ฒŒ ๋กœ๊ทธ ํŒŒ์ผ์ด ๋ถ„๋ฆฌ๋˜์–ด ์ž‘์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค!!

ํƒœ๊ทธ: ,

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ