Pythonã®ãã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã培åºè§£èª¬ããã³ãã©èšå®ãã«ã¹ã¿ã ãã©ãŒããã¿ãå®è·µäŸããã¹ããã©ã¯ãã£ã¹ãæ¢æ±ããå ç¢ã§å¹ççãªã¢ããªã±ãŒã·ã§ã³ãã®ã³ã°ãå®çŸããŸãã
Pythonãã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ïŒãã³ãã©èšå® vs ã«ã¹ã¿ã ãã©ãŒããã¿
Pythonã®ãã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ã®æ¯ãèãã管çã»ç£èŠããããã®åŒ·åãªããŒã«ã§ãã广çãªãã®ã³ã°ã¯ããããã°ããã©ãã«ã·ã¥ãŒãã£ã³ã°ããããŠãœãããŠã§ã¢ã®ããã©ãŒãã³ã¹ã«é¢ããæŽå¯ãåŸãããã«äžå¯æ¬ ã§ãããã®å æ¬çãªã¬ã€ãã§ã¯ãPythonãã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã®2ã€ã®éèŠãªåŽé¢ããã³ãã©èšå®ãšã«ã¹ã¿ã ãã©ãŒããã¿ã«ã€ããŠæ·±ãæãäžããŸããäžçäžã®ã©ãã«ããŠããPythonãããžã§ã¯ãã§å ç¢ãã€å¹ççãªãã®ã³ã°ãå®è£ ã§ããããããã®æ©èœããã¹ããã©ã¯ãã£ã¹ãå®è·µçãªäŸãæ¢æ±ããŸãã
Pythonãã®ã³ã°ã®åºç€ãçè§£ãã
ãã³ãã©ãšãã©ãŒããã¿ã«é£ã³èŸŒãåã«ãPythonãã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã®ã³ã¢ã³ã³ããŒãã³ãã«ã€ããŠãã£ãããšçè§£ãæ·±ããŸãããã
- ãã¬ãŒ(Loggers): ãã¬ãŒã¯ãã¢ããªã±ãŒã·ã§ã³ããã°ã¡ãã»ãŒãžãæžã蟌ãããã®äž»èŠãªã€ã³ã¿ãŒãã§ãŒã¹ã§ãããã¬ãŒã¯éå±€çã§ãããåãã¬ãŒãæã€ããšãã§ãã芪ããèšå®ãç¶æ¿ããŸãããã°ã¡ãã»ãŒãžã®ã²ãŒãããŒããŒã®ãããªãã®ã ãšèããŠãã ããã
- ãã°ã¬ãã«(Log Levels): ãã°ã¬ãã«ïŒDEBUG, INFO, WARNING, ERROR, CRITICALïŒã¯ããã°ã¡ãã»ãŒãžã®éèŠåºŠãåé¡ããŸãããããã®ã¬ãã«ã䜿çšããŠãã©ã®ã¡ãã»ãŒãžãåŠçãããããã£ã«ã¿ãªã³ã°ããŸããäŸãã°ãæ¬çªç°å¢ã§ã¯ãåé·æ§ãæžããããã«WARNINGãERRORãCRITICALã¡ãã»ãŒãžã®ã¿ããã°ã«èšé²ããããšããããŸãã
- ãã³ãã©(Handlers): ãã³ãã©ã¯ããã°ã¡ãã»ãŒãžã®éä¿¡å ãæ±ºå®ããŸããéä¿¡å ã¯ãã³ã³ãœãŒã«ïŒstdoutïŒããã¡ã€ã«ããããã¯ãŒã¯ãœã±ããããããã¯ããŒã¿ããŒã¹ãªã©ã§ãããã³ãã©ã¯ããã°ã¬ãã«ã«ãããã£ã«ã¿ãªã³ã°ããã©ãŒããã¿ã®é©çšãèšå®ã§ããŸãã
- ãã©ãŒããã¿(Formatters): ãã©ãŒããã¿ã¯ããã°ã¡ãã»ãŒãžã®æ§é ãšå 容ãå®çŸ©ããŸããã¿ã€ã ã¹ã¿ã³ãããã¬ãŒåããã°ã¬ãã«ãã¡ãã»ãŒãžå 容ãªã©ãã©ã®æ å ±ãå«ããã©ã®ããã«è¡šç€ºããããå¶åŸ¡ããŸãããã©ãŒããã¿ã¯ããã°ã¡ãã»ãŒãžãæžã蟌ãŸããåã«ãã³ãã©ã«ãã£ãŠé©çšãããŸãã
ãããã®ã³ã³ããŒãã³ãã¯é£æºããŠãæè»ã§èšå®å¯èœãªãã®ã³ã°ã·ã¹ãã ãæäŸããŸãããã°ã¡ãã»ãŒãžã¯ãã¬ãŒã§çºçãããã³ãã©ãééãããã©ãŒããã¿ã§æŽåœ¢ãããåŸãå®å ã«éä¿¡ãããŸãããã®æ§é ã«ããããã°ã®çæãåŠçãä¿åæ¹æ³ã现ããå¶åŸ¡ã§ããŸãã
ãã³ãã©èšå®ïŒãã°ã广çã«ã«ãŒãã£ã³ã°ãã
ãã³ãã©ã¯ãã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã®äž»åã§ããããã°ã¡ãã»ãŒãžãæçµçãªå®å ã«éã圹å²ãæ ããŸãã广çãªãã®ã³ã°ã«ã¯ãé©åãªãã³ãã©èšå®ãäžå¯æ¬ ã§ãã以äžã«äž»èŠãªèæ ®äºé ããŸãšããŸãã
äžè¬çãªãã³ãã©ã®çš®é¡ïŒ
- StreamHandler: ãã°ã¡ãã»ãŒãžãã¹ããªãŒã ïŒéåžžã¯stdoutãŸãã¯stderrïŒã«éä¿¡ããŸããéçºäžã®ã³ã³ãœãŒã«ãã®ã³ã°ã«æé©ã§ãã
- FileHandler: ãã°ã¡ãã»ãŒãžããã¡ã€ã«ã«æžã蟌ã¿ãŸããç¹ã«æ¬çªç°å¢ã§ã®ã¢ããªã±ãŒã·ã§ã³ã€ãã³ãã®æ°žç¶çãªãã®ã³ã°ã«äžå¯æ¬ ã§ããããã¯ããããã€åŸã«çºçããåé¡ã®ãããã°ã«éèŠã§ãã
- RotatingFileHandler: FileHandlerã®ãµãã¯ã©ã¹ã§ããã°ãã¡ã€ã«ãç¹å®ã®ãµã€ãºã«éããããç¹å®ã®æéééã§èªåçã«ããŒããŒã·ã§ã³ããŸããåäžã®ãã°ãã¡ã€ã«ãç¡éã«å€§ãããªãã®ãé²ããããã©ãŒãã³ã¹ãšç®¡çæ§ãåäžãããŸãã
- TimedRotatingFileHandler: RotatingFileHandlerã«äŒŒãŠããŸãããæéïŒæ¥æ¬¡ã鱿¬¡ãªã©ïŒã«åºã¥ããŠããŒããŒã·ã§ã³ããŸãããã°ãæ¥ä»å¥ã«æŽçããã®ã«åœ¹ç«ã¡ãŸãã
- SocketHandler: ãããã¯ãŒã¯ãœã±ããçµç±ã§ãã°ã¡ãã»ãŒãžãéä¿¡ããŸãããªã¢ãŒããã®ã³ã°ãå¯èœã«ããè€æ°ã®ã¢ããªã±ãŒã·ã§ã³ããã®ãã°ãäžå 管çã§ããŸãã
- SMTPHandler: é»åã¡ãŒã«çµç±ã§ãã°ã¡ãã»ãŒãžãéä¿¡ããŸããã¯ãªãã£ã«ã«ãªãšã©ãŒãèŠåãéç¥ããã®ã«åœ¹ç«ã¡ãŸãã
Pythonã§ã®ãã³ãã©ã®èšå®ïŒ
ãã³ãã©ãèšå®ããã«ã¯ãäž»ã«2ã€ã®æ¹æ³ããããŸãã
- ããã°ã©ã ã«ããèšå®: Pythonã³ãŒãå ã§çŽæ¥ãã³ãã©ã€ã³ã¹ã¿ã³ã¹ãäœæãããããããã¬ãŒã«ã¢ã¿ããããŸãããã®ã¢ãããŒãã¯æãæè»æ§ãšå¶åŸ¡æ§ãæäŸããã¢ããªã±ãŒã·ã§ã³ã®ããŒãºã«å¿ããŠãã®ã³ã°ã®æ¯ãèããåçã«èª¿æŽã§ããŸãã
- èšå®ãã¡ã€ã«ïŒäŸïŒYAMLãJSONãINIïŒ: èšå®ãã¡ã€ã«ã䜿çšãããšããã®ã³ã°èšå®ãã¢ããªã±ãŒã·ã§ã³ã³ãŒãããåé¢ã§ããã³ãŒãã倿Žããããšãªããã®ã³ã°èšå®ã®ç®¡çã倿Žã容æã«ãªããŸããããã¯ç¹ã«ãããã€ç°å¢ã§åœ¹ç«ã¡ãŸãã
ããã°ã©ã ã«ãããã³ãã©èšå®ã®äŸïŒ
ã³ã³ãœãŒã«ãšãã¡ã€ã«ã«æžã蟌ãç°¡åãªäŸã§ãããã°ã©ã ã«ããèšå®ã説æããŸãããã®äŸã¯åºæ¬çãªæ§é ã瀺ããŠããŸãããããžã§ã¯ãã®å¿ èŠã«å¿ããŠããã¡ã€ã«ãã¹ããã°ã¬ãã«ã調æŽããŠãã ããã
import logging
# Create a logger
logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG) # Set the root logger level
# Create a handler to print to the console (stdout)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO) # Set level for this handler
# Create a handler to write to a file
file_handler = logging.FileHandler('my_app.log')
file_handler.setLevel(logging.DEBUG) # Log everything to the file
# Create formatters (explained later)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# Add the handlers to the logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# Example log messages
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')
ãã®äŸã®ãã€ã³ãïŒ
logging.getLogger()ã䜿çšããŠãã¬ãŒã€ã³ã¹ã¿ã³ã¹ãäœæããŸããåŒæ°ã¯éåžžãã¢ãžã¥ãŒã«åãŸãã¯ã¢ããªã±ãŒã·ã§ã³åºæã®ååã§ãã- ã«ãŒããã¬ãŒïŒãã®å Žå㯠'my_app'ïŒã®ãã°ã¬ãã«ãèšå®ããŸããããã«ããããã¬ãŒã«ãã£ãŠåŠçãããã¡ãã»ãŒãžã®*æå°*ã®éèŠåºŠã¬ãã«ã決å®ãããŸãã
- 2ã€ã®ãã³ãã©ãäœæããŸãïŒ1ã€ã¯ã³ã³ãœãŒã«çšïŒStreamHandlerïŒããã1ã€ã¯ãã¡ã€ã«çšïŒFileHandlerïŒã§ãã
- *å*ãã³ãã©ã«ã¬ãã«ãèšå®ããŸããããã«ãããã£ã«ã¿ãªã³ã°ãå¯èœã«ãªããŸããäŸãã°ãã³ã³ãœãŒã«ãã³ãã©ã¯INFO以äžã®ã¡ãã»ãŒãžã®ã¿ã衚瀺ãããã¡ã€ã«ãã³ãã©ã¯ãã¹ãŠã®ã¡ãã»ãŒãžïŒDEBUG以äžïŒãèšé²ããŸãã
- åãã³ãã©ã«ãã©ãŒããã¿ãã¢ã¿ããããŸãïŒè©³çްã¯åŸè¿°ïŒã
logger.addHandler()ã䜿çšããŠãã¬ãŒã«ãã³ãã©ã远å ããŸãã- ãã¬ãŒã䜿çšããŠãããŸããŸãªã¬ãã«ã®ãã°ã¡ãã»ãŒãžãçæããŸãã
èšå®ãã¡ã€ã«ïŒYAMLïŒã®äŸïŒ
èšå®ãã¡ã€ã«ïŒäŸïŒYAMLïŒã䜿çšãããšããã®ã³ã°èšå®ãå€éšã§å®çŸ©ã§ãããããã³ãŒãã倿Žããããšãªããã®ã³ã°ã®æ¯ãèããç°¡åã«å€æŽã§ããŸãã以äžã¯ logging.config.dictConfig() 颿°ã䜿çšããäŸã§ãã
import logging
import logging.config
import yaml
# Load the configuration from a YAML file
with open('logging_config.yaml', 'r') as f:
config = yaml.safe_load(f)
# Configure logging
logging.config.dictConfig(config)
# Get a logger (the name should match the one defined in the config file)
logger = logging.getLogger('my_app')
# Example log messages
logger.debug('This is a debug message from the config')
logger.info('This is an info message from the config')
ãããŠãããããµã³ãã« logging_config.yaml ãã¡ã€ã«ã§ãã
version: 1
formatters:
simple:
format: '%(levelname)s - %(message)s'
detailed:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: simple
stream: ext://sys.stdout
file:
class: logging.FileHandler
level: DEBUG
formatter: detailed
filename: my_app_config.log
loggers:
my_app:
level: DEBUG
handlers: [console, file]
propagate: no
root:
level: WARNING # Defaults, if not set in logger.
YAMLèšå®ã®èª¬æïŒ
version: 1: èšå®ãã¡ã€ã«ã®ããŒãžã§ã³ãæå®ããŸããformatters: å©çšå¯èœãªãã©ãŒããã¿ãå®çŸ©ããŸããhandlers: ãã³ãã©ãå®çŸ©ããŸããåãã³ãã©ã¯ããã®ã¯ã©ã¹ãã¬ãã«ããã©ãŒããã¿ãããã³å®å ïŒäŸïŒã³ã³ãœãŒã«ããã¡ã€ã«ïŒãæå®ããŸããloggers: ãã¬ãŒãå®çŸ©ããŸããããã§ã¯ã'my_app' ãã¬ãŒã 'console' ãš 'file' ã®äž¡æ¹ã®ãã³ãã©ã䜿çšããããã«èšå®ããŸãããŸãããã®ãã°ã¬ãã«ãèšå®ããŸããroot: ãã¬ãŒã§èšå®ãããŠããªãå Žåã®ããã©ã«ãèšå®ã§ãã
èšå®ãã¡ã€ã«ã®äž»ãªå©ç¹ïŒ
- é¢å¿ã®åé¢: ãã®ã³ã°èšå®ãã³ã¢ã¢ããªã±ãŒã·ã§ã³ããžãã¯ããåé¢ããŸãã
- 容æãªå€æŽ: ãã®ã³ã°ã®æ¯ãèãïŒäŸïŒãã°ã¬ãã«ãåºåå ïŒã®å€æŽã¯ãã³ãŒãã§ã¯ãªãèšå®ãã¡ã€ã«ã®å€æŽã®ã¿ã§æžã¿ãŸãã
- ãããã€ã®æè»æ§: ç°ãªãç°å¢ïŒéçºããã¹ããæ¬çªïŒã«åãããŠãã®ã³ã°ã容æã«èª¿æŽã§ããŸãã
ã«ã¹ã¿ã ãã©ãŒããã¿ïŒãã°ã¡ãã»ãŒãžã調æŽãã
ãã©ãŒããã¿ã¯ããã°ã¡ãã»ãŒãžã®æ§é ãšå 容ãå¶åŸ¡ããŸãããã°ã«è¡šç€ºãããæ å ±ãã«ã¹ã¿ãã€ãºããã¢ããªã±ãŒã·ã§ã³ã®æ¯ãèããçè§£ãããããåæããããããŸãããã©ãŒããã¿ã¯ãã©ã®è©³çްïŒã¿ã€ã ã¹ã¿ã³ãããã¬ãŒåããã°ã¬ãã«ãã¡ãã»ãŒãžãªã©ïŒãå«ãããããããŠããããã©ã®ããã«è¡šç€ºããããæ±ºå®ããŸãã
ãã©ãŒããã¿ã³ã³ããŒãã³ãã®çè§£ïŒ
ãã©ãŒããã¿ã¯ããã°ã¬ã³ãŒããã©ã®ããã«ãã©ãŒããããããããå®çŸ©ãããã©ãŒãããæååã䜿çšããŸãã以äžã¯äžè¬çã«äœ¿çšããããã©ãŒãããæå®åã§ãã
%(asctime)s: ãã°ã¬ã³ãŒããäœæãããæå»ïŒäŸïŒ'2024-01-01 12:00:00,000'ïŒã%(name)s: ãã¬ãŒã®ååïŒäŸïŒ'my_app.module1'ïŒã%(levelname)s: ãã°ã¬ãã«ïŒäŸïŒ'INFO', 'WARNING', 'ERROR'ïŒã%(message)s: ãã°ã¡ãã»ãŒãžã%(filename)s: ãã°ã¡ãã»ãŒãžãçºçãããã¡ã€ã«åã%(lineno)d: ãã°ã¡ãã»ãŒãžãçºçããè¡çªå·ã%(funcName)s: ãã°ã¡ãã»ãŒãžãçºçãã颿°åã%(pathname)s: ãœãŒã¹ãã¡ã€ã«ã®ãã«ãã¹åã%(threadName)s: ã¹ã¬ããåã%(process)d: ããã»ã¹IDã
ã«ã¹ã¿ã ãã©ãŒããã¿ã®äœæïŒ
ã¢ããªã±ãŒã·ã§ã³ã®ããŒãºã«åãããŠç¹å®ã®æ
å ±ãå«ããããã«ãã«ã¹ã¿ã ãã©ãŒããã¿ãäœæã§ããŸãããã㯠logging.Formatter ã¯ã©ã¹ããµãã¯ã©ã¹åãããã® `format()` ã¡ãœããããªãŒããŒã©ã€ãããããšã§å®çŸããŸãã`format()` ã¡ãœããå
ã§ããã°ã¬ã³ãŒãã®å±æ§ã«ã¢ã¯ã»ã¹ããå¿
èŠã«å¿ããŠã¡ãã»ãŒãžããã©ãŒãããã§ããŸãã
import logging
class CustomFormatter(logging.Formatter):
def format(self, record):
# Get the original formatted message
log_fmt = super().format(record)
# Add custom information
custom_info = f' - User: {record.user_id if hasattr(record, "user_id") else "Guest"}' # Example customization
return log_fmt + custom_info
# Example Usage (Illustrative: Requires setting up a handler and attaching the custom formatter)
if __name__ == '__main__':
logger = logging.getLogger('custom_logger')
logger.setLevel(logging.INFO)
# Create a console handler
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
# Set the custom formatter on the handler
formatter = CustomFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
# Add the handler to the logger
logger.addHandler(ch)
# Create a log record with custom attribute (simulated for demonstration)
class LogRecordWithUser(logging.LogRecord):
def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func, sinfo, user_id=None):
super().__init__(name, level, pathname, lineno, msg, args, exc_info, func, sinfo)
self.user_id = user_id
#Example message with a user id
record = LogRecordWithUser('custom_logger', logging.INFO, 'example.py', 10, 'User logged in', (), None, 'main', None, user_id='12345')
logger.handle(record)
# Example message without a user id
logger.info('Guest user accessed the page.')
ã«ã¹ã¿ã ãã©ãŒããã¿ã®äŸã®èª¬æïŒ
logging.Formatterãç¶æ¿ãã `CustomFormatter` ãšããã¯ã©ã¹ãäœæããŸãã- `format()` ã¡ãœããããªãŒããŒã©ã€ãããŸããããã«ã«ã¹ã¿ã ãã©ãŒãããã®ããžãã¯ãèšè¿°ããŸãã
- ãŸã
super().format(record)ã䜿çšããŠæšæºã®ãã©ãŒãããæžã¿ã¡ãã»ãŒãžãååŸããŸãã - ã«ã¹ã¿ã æ å ±ã远å ããŸãããã®äŸã§ã¯ããã°ã¬ã³ãŒãã®å±æ§ãšããŠãŠãŒã¶ãŒæ å ±ïŒãŠãŒã¶ãŒIDïŒãååšããå Žåã«ããã远å ããŸããååšããªãå ŽåïŒã²ã¹ããŠãŒã¶ãŒãªã©ïŒã¯ããGuestããšè¡šç€ºããŸãã`hasattr()` ã«ãããã§ãã¯ãš user_id 屿§ã®æ¡ä»¶ä»ãå å«ãã屿§ãå®çŸ©ãããŠããªãå Žåã«ãšã©ãŒãåé¿ããã®ã«åœ¹ç«ã€ããšã«æ³šæããŠãã ããã
- ãã®äŸã¯ãçŸåšãã°ã€ã³ããŠãããŠãŒã¶ãŒã«é¢ããæ å ±ãå«ããã°ã¡ãã»ãŒãžãåŠçããæ¹æ³ã瀺ããŠããŸãã
ããŸããŸãªãŠãŒã¹ã±ãŒã¹ã®ããã®ãã°ã¡ãã»ãŒãžã®ãã©ãŒãããïŒ
ããŒãºã«æãé©ãããã©ãŒããããéžæããã®ã«åœ¹ç«ã€ãããŸããŸãªãã©ãŒããã¿ã¹ã¿ã€ã«ã®äŸãããã€ã玹ä»ããŸãã
- åºæ¬çãªãã©ãŒãããïŒéçºçšïŒïŒ
ãã®ãã©ãŒãããã¯ãåçŽãªã¿ã€ã ã¹ã¿ã³ãããã°ã¬ãã«ãã¡ãã»ãŒãžãæäŸããŸããè¿ éãªãããã°ã«é©ããŠããŸãã
'%(asctime)s - %(levelname)s - %(message)s' - 詳现ãªãã©ãŒãããïŒæ¬çªçšããã¡ã€ã«/è¡çªå·ä»ãïŒïŒ
ãã®ãã©ãŒãããã¯ããã¬ãŒåããã¡ã€ã«åãè¡çªå·ããã°ã¡ãã»ãŒãžãå«ã¿ããã°ã®çºçæºã远跡ããããããŸãã
'%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s' - JSONãã©ãŒãããïŒæ©æ¢°è§£æçšïŒïŒ
èªåãã°åæïŒäŸïŒãã°éçŽã·ã¹ãã ïŒã«ã¯ãJSONãã©ãŒããããéåžžã«å¹æçã§ããããã«ãããæ§é åããŒã¿ãå¯èœã«ãªããè§£æãšåæã容æã«ãªããŸããã«ã¹ã¿ã ãã©ãŒããã¿ã¯ã©ã¹ãäœæãã`json.dumps()` ã䜿çšããŠãã°ã¬ã³ãŒããJSONãšããŠãšã³ã³ãŒãããå¿ èŠããããŸãã
import json import logging class JsonFormatter(logging.Formatter): def format(self, record): log_record = { 'timestamp': self.formatTime(record, self.datefmt), 'name': record.name, 'levelname': record.levelname, 'message': record.getMessage(), 'filename': record.filename, 'lineno': record.lineno, 'funcName': record.funcName } return json.dumps(log_record)ãã®ãã©ãŒããã¿ã¯ãé¢é£ãããã°ããŒã¿ãå«ãJSONæ§é ãäœæããŸãããã¡ã€ã«ãè¡çªå·ã颿°åã«ããããœãŒã¹ã³ãŒãå ã§ã®è¿œè·¡ã容æã«ãªããŸãããã®ãã©ãŒããããããåºåã¯ããã°åæããŒã«ã«ãã£ãŠç°¡åã«è§£æãããŸãã
- ç¹å®ã®ã¢ããªã±ãŒã·ã§ã³åãã®ãã©ãŒãããïŒ
ã³ã³ããã¹ãåºæã®æ å ±ãå«ããããã«ãã©ãŒããã¿ã調æŽããŸããã¢ããªã±ãŒã·ã§ã³ããŠãŒã¶ãŒèªèšŒãåŠçããå Žåã¯ããŠãŒã¶ãŒIDãå«ããŸããéèååŒãåŠçããå Žåã¯ãååŒIDãå«ããŸããããžãã¹ã³ã³ããã¹ããçŽé¢ããå¯èœæ§ãæãé«ãåé¡ã®çš®é¡ã«åºã¥ããŠããã®ã³ã°åºåã調æŽããŸãã
Pythonãã®ã³ã°ã®ãã¹ããã©ã¯ãã£ã¹
ãã¹ããã©ã¯ãã£ã¹ã«åŸãããšã§ããã®ã³ã°ã广çã§ãä¿å®å¯èœã§ã䟡å€ã®ãããã®ã«ãªããŸãã以äžã«äž»èŠãªæšå¥šäºé ãæããŸãã
- ãã°ã¬ãã«ã®ç²åºŠïŒ é©åãªãã°ã¬ãã«ãäžè²«ããŠäœ¿çšããŸãã
DEBUG: 詳现æ å ±ãéåžžã¯ãããã°çšãINFO: ã¢ããªã±ãŒã·ã§ã³ã®åäœã«é¢ããäžè¬æ å ±ãWARNING: æœåšçãªåé¡ãäºæããªãã€ãã³ããERROR: äœããã®æ©èœãæ©èœæ§ã®å®è¡ã劚ããŠãããšã©ãŒãCRITICAL: ã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ãã·ã¥ãäžå®å®åãåŒãèµ·ããå¯èœæ§ã®ããæ·±å»ãªãšã©ãŒã
ãã°ã«èšé²ããã€ãã³ãã®éèŠåºŠãæ£ç¢ºã«åæ ããã¬ãã«ãéžæããŠãã ããã
- ã³ã³ããã¹ãæ å ±ïŒ ãã°ã¡ãã»ãŒãžã«é¢é£ã³ã³ããã¹ããå«ããŸãããŠãŒã¶ãŒIDããªã¯ãšã¹ãIDããã©ã³ã¶ã¯ã·ã§ã³IDãªã©ãåé¡ã®æ ¹æ¬åå ã远跡ããã®ã«åœ¹ç«ã€æ å ±ãå«ããŠãã ããã
- ãšã©ãŒåŠçïŒ åžžã«
logger.exception()ã䜿çšããããäŸå€æ å ±ããã°ã¡ãã»ãŒãžã«å«ããŠäŸå€ããã°ã«èšé²ããŸããããã«ããããããã°ã«éåžžã«åœ¹ç«ã€ã¹ã¿ãã¯ãã¬ãŒã¹ãæäŸãããŸãã - éäžãã®ã³ã°ïŒåæ£ã·ã¹ãã çšïŒïŒ éäžãã®ã³ã°ã·ã¹ãã ïŒäŸïŒElasticsearchãFluentdãSplunkããŸãã¯ELKã¹ã¿ã㯠-- ElasticsearchãLogstashãKibanaïŒã®äœ¿çšãæ€èšããŠãã ãããããã«ãããè€æ°ã®ã¢ããªã±ãŒã·ã§ã³ããµãŒããŒããã®ãã°ãéçŽããã·ã¹ãã ã®æ€çŽ¢ãåæãç£èŠã容æã«ãªããŸããã¯ã©ãŠãã³ã³ãã¥ãŒãã£ã³ã°ã®äžçã§ã¯ãAWS CloudWatchãAzure MonitorãGoogle Cloud Loggingãªã©ãããŸããŸãªãµãŒãã¹ããããŒãžããã®ã³ã°ãæäŸããŠããŸãã
- ããŒããŒã·ã§ã³ãšä¿æïŒ ãã°ãã¡ã€ã«ã倧ãããªããããã®ãé²ãããã«ããã°ããŒããŒã·ã§ã³ïŒ`RotatingFileHandler` ãŸã㯠`TimedRotatingFileHandler` ã䜿çšïŒãå®è£ ããŸããæå®ãããæéãçµéããåŸã«ãã°ãèªåçã«åé€ãŸãã¯ã¢ãŒã«ã€ãããããã®ä¿æããªã·ãŒã確ç«ããŸããããã¯ãã³ã³ãã©ã€ã¢ã³ã¹ãã»ãã¥ãªãã£ãããã³ã¹ãã¬ãŒãžç®¡çã«ãšã£ãŠéèŠã§ãã
- æ©å¯æ å ±ãé¿ããïŒ ãã¹ã¯ãŒããAPIããŒãå人ããŒã¿ãªã©ã®æ©å¯æ å ±ãæ±ºããŠãã°ã«èšé²ããªãã§ãã ãããGDPRãCCPAãªã©ã®ãã©ã€ãã·ãŒèŠå¶ãžã®æºæ ã培åºããŠãã ãããã¢ããªã±ãŒã·ã§ã³ãæ©å¯ããŒã¿ãæ±ãå Žåã¯ãæ éãªãã£ã«ã¿ãªã³ã°ãå®è£ ããŠãã ããã
- èšå®é§åã®ãã®ã³ã°ïŒ èšå®ãã¡ã€ã«ïŒYAMLãJSONããŸãã¯INIïŒã䜿çšããŠãã®ã³ã°èšå®ã管çããŸããããã«ãããã³ãŒãã倿Žããããšãªããã°ã¬ãã«ããã³ãã©ããã©ãŒããã¿ã倿Žãããããªããç°ãªãç°å¢ã«åãããŠãã®ã³ã°ãã«ã¹ã¿ãã€ãºã§ããŸãã
- ããã©ãŒãã³ã¹ã«é¢ããèæ ®äºé ïŒ ç¹ã«ããã©ãŒãã³ã¹ãéèŠãªã³ãŒãã»ã¯ã·ã§ã³ã§ã®éå°ãªãã®ã³ã°ã¯é¿ããŠãã ããããã®ã³ã°ã¯ãªãŒããŒããããçºçãããå¯èœæ§ããããããã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãžã®åœ±é¿ã«æ³šæããŠãã ãããé©åãªãã°ã¬ãã«ã䜿çšããå¿ èŠã«å¿ããŠã¡ãã»ãŒãžããã£ã«ã¿ãªã³ã°ããŠãã ããã
- ãã®ã³ã°ã®ãã¹ãïŒ ãã®ã³ã°èšå®ãšãã°ã¡ãã»ãŒãžãæ£ããçæãããããšãæ€èšŒããããã®åäœãã¹ããèšè¿°ããŸããé©åãªåäœãä¿èšŒããããã«ãããŸããŸãªãã°ã¬ãã«ãã·ããªãªããã¹ãããããšãæ€èšããŠãã ããã
- ããã¥ã¡ã³ããŒã·ã§ã³ïŒ ãã°ã¬ãã«ããã³ãã©ããã©ãŒããã¿ãå«ããã®ã³ã°èšå®ãææžåããŸããããã«ãããä»ã®éçºè ããã®ã³ã°èšå®ãçè§£ãããããªããã³ãŒãã®ä¿å®ããã©ãã«ã·ã¥ãŒãã£ã³ã°ã容æã«ãªããŸãã
- ãŠãŒã¶ãŒIDãšãªã¯ãšã¹ãIDã®çžé¢ïŒ Webã¢ããªã±ãŒã·ã§ã³ãè€æ°ã®ãªã¯ãšã¹ããåŠçãããµãŒãã¹ã§ã¯ãäžæã®ãªã¯ãšã¹ãIDãçæããç¹å®ã®ãªã¯ãšã¹ãã«é¢é£ãããã¹ãŠã®ãã°ã¡ãã»ãŒãžã«ãããå«ããŸããåæ§ã«ãé©åãªå Žåã«ã¯ãŠãŒã¶ãŒIDãå«ããŸããããã«ãããè€æ°ã®ãµãŒãã¹ã«ãŸããããªã¯ãšã¹ãã远跡ããç¹å®ã®ãŠãŒã¶ãŒã«é¢é£ããåé¡ããããã°ããã®ã«åœ¹ç«ã¡ãŸãã
å®è·µçãªäŸãšãŠãŒã¹ã±ãŒã¹
广çãªãã®ã³ã°ãäžå¯æ¬ ãªããã€ãã®å®äžçã®ã·ããªãªãæ¢ã£ãŠã¿ãŸãããã
1. Webã¢ããªã±ãŒã·ã§ã³ã®ç£èŠïŒ
Webã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã®ã³ã°ã䜿çšããŠãŠãŒã¶ãŒãªã¯ãšã¹ããç£èŠãããšã©ãŒã远跡ããããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ã§ããŸãã
import logging
from flask import Flask, request
app = Flask(__name__)
# Configure logging (using a config file, or a programmatic example here)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
@app.route('/')
def index():
# Generate a request ID (for example)
request_id = request.headers.get('X-Request-Id')
if not request_id:
request_id = 'unknown'
logger.info(f'Request received, Request ID: {request_id}')
try:
# Simulate an error condition
if request.args.get('error'):
raise ValueError('Simulated error')
return 'Hello, World!'
except Exception as e:
logger.error(f'Error processing request {request_id}: {str(e)}')
return 'Internal Server Error', 500
if __name__ == '__main__':
app.run(debug=True) # Be very careful using debug=True in production.
ãã®äŸã§ã¯ã次ã®ããšãè¡ã£ãŠããŸãã
- åã ã®ãªã¯ãšã¹ãã远跡ããããã«ãªã¯ãšã¹ãIDãçæïŒãŸãã¯åä¿¡ïŒããŸãã
- ãªã¯ãšã¹ãIDãšå ±ã«ãªã¯ãšã¹ãããã°ã«èšé²ããŸãã
- äŸå€ãšãªã¯ãšã¹ãIDãå«ããšã©ãŒããã°ã«èšé²ããŸãã
2. ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ / ã¹ã±ãžã¥ãŒã«ããããžã§ãïŒ
ãã®ã³ã°ã¯ãã¹ã±ãžã¥ãŒã«ããããžã§ããããŒã¿åŠçãã€ãã©ã€ã³ãªã©ã®ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ãç£èŠããããã«äžå¯æ¬ ã§ãã
import logging
import time
from datetime import datetime
# Configure logging (again, using config file is generally better)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def my_scheduled_task():
start_time = datetime.now()
logger.info(f'Starting scheduled task at {start_time}')
try:
# Simulate some work
time.sleep(2) # Simulate work
# Simulate a potential error
if datetime.now().minute % 5 == 0:
raise ValueError('Simulated error in task')
logger.info('Task completed successfully')
except Exception as e:
logger.error(f'Task failed: {str(e)}')
finally:
end_time = datetime.now()
logger.info(f'Task finished at {end_time}. Duration: {end_time - start_time}')
if __name__ == '__main__':
my_scheduled_task()
ããã¯ã¿ã¹ã¯ã®å®è¡åãå®è¡äžãå®è¡åŸã®ãã®ã³ã°ã瀺ããæåãšå€±æã衚瀺ããŸããããã«ãããã¹ã±ãžã¥ãŒãªã³ã°ã®åé¡ãç°¡åã«èšºæã§ããŸãã
3. ããŒã¿åŠçãã€ãã©ã€ã³ïŒ
ããŒã¿åŠçãã€ãã©ã€ã³ã§ã¯ããã®ã³ã°ã¯ããŒã¿å€æã远跡ãããšã©ãŒãæ€åºãããã€ãã©ã€ã³å šäœã®å¥å šæ§ãç£èŠããã®ã«åœ¹ç«ã¡ãŸãã
import logging
import pandas as pd
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def load_data(file_path):
try:
df = pd.read_csv(file_path) # Replace with your file type
logger.info(f'Data loaded from {file_path}, shape: {df.shape}')
return df
except FileNotFoundError:
logger.error(f'File not found: {file_path}')
return None
except Exception as e:
logger.error(f'Error loading data: {str(e)}')
return None
def transform_data(df):
if df is None:
return None
try:
# Apply some transformation
df['processed_column'] = df['some_column'] * 2 # Example
logger.info('Data transformation completed.')
return df
except Exception as e:
logger.error(f'Error transforming data: {str(e)}')
return None
def save_data(df, output_file):
if df is None:
return
try:
df.to_csv(output_file, index=False) # Modify for different output format
logger.info(f'Data saved to {output_file}')
except Exception as e:
logger.error(f'Error saving data: {str(e)}')
# Example Usage (replace with your actual file paths and data)
if __name__ == '__main__':
input_file = 'input.csv'
output_file = 'output.csv'
data = load_data(input_file)
transformed_data = transform_data(data)
save_data(transformed_data, output_file)
ãã®ãã€ãã©ã€ã³ã®äŸã§ã¯ãããŒã¿ã®èªã¿èŸŒã¿ã倿ãä¿åããã°ã«èšé²ããŸãããã®ã³ã°ã¹ããŒãã¡ã³ãã«ãããããã»ã¹ãç£èŠããäœãåé¡ãçºçããå Žåã«åé¡ãç°¡åã«èšºæã§ããŸãã
é«åºŠãªãã®ã³ã°æè¡
åºæ¬ãè¶ ããŠããã®ã³ã°èœåãæå€§éã«æŽ»çšããããã«ããããã®é«åºŠãªæè¡ãæ€èšããŠãã ããã
- Logging ContextVars: `contextvars` ã¢ãžã¥ãŒã«ïŒPython 3.7+ã§å©çšå¯èœïŒã䜿çšãããšãã³ã³ããã¹ãåºæã®ããŒã¿ïŒäŸïŒãªã¯ãšã¹ãIDããŠãŒã¶ãŒIDïŒãä¿åãããã°ã¡ãã»ãŒãžã«èªåçã«å«ããããšãã§ããŸããããã«ããããã¹ãŠã®ãã®ã³ã°åŒã³åºãã«æåã§æž¡ãããšãªããã³ã³ããã¹ãæ å ±ããã°ã«è¿œå ããããã»ã¹ãç°¡çŽ åãããŸããããã«ãããå®åçãªã³ãŒããæžããã³ãŒãã®ä¿å®æ§ãåäžããŸãã
- Logging Filters: ãã£ã«ã¿ã䜿çšããŠããã³ãã©ã«ãã£ãŠåŠçããããã°ã¡ãã»ãŒãžãããã«çµã蟌ã¿ãŸãããã£ã«ã¿ã¯ãäŸãã°ãçºçå ã®ã¢ãžã¥ãŒã«ãç¹å®ã®å€æ°ã®å€ãªã©ãã«ã¹ã¿ã åºæºã«åºã¥ããŠæ¡ä»¶ä»ãã§ã¡ãã»ãŒãžããã°ã«èšé²ããããã«äœ¿çšã§ããŸãã
- Logging Libraries Integration: ãã®ã³ã°ããããžã§ã¯ãã§äœ¿çšãããŠããä»ã®ã©ã€ãã©ãªããã¬ãŒã ã¯ãŒã¯ãšçµ±åããŸããäŸãã°ãFlaskãDjangoã®ãããªWebãã¬ãŒã ã¯ãŒã¯ã䜿çšããŠããå ŽåãHTTPãªã¯ãšã¹ããã¬ã¹ãã³ã¹ã«é¢ããæ å ±ãèªåçã«ãã°ã«èšé²ããããã«ãã®ã³ã°ãèšå®ã§ããŸãã
- Log Aggregation and Analysis (ELK Stack, etc.): ãã°éçŽã·ã¹ãã ãå®è£ ããŸããELKã¹ã¿ãã¯ïŒElasticsearchãLogstashãKibanaïŒããã®ä»ã®ã¯ã©ãŠãããŒã¹ã®ãœãªã¥ãŒã·ã§ã³ã®äœ¿çšãæ€èšããŠãã ããããããã®ã·ã¹ãã ã䜿çšãããšãããŸããŸãªãœãŒã¹ããã®ãã°ãåéãéäžç®¡çãåæã§ãã匷åãªæ€çŽ¢ããã£ã«ã¿ãªã³ã°ãå¯èŠåæ©èœãæäŸããŸããããã«ããããã¬ã³ãã®ç¹å®ãç°åžžã®æ€åºãåé¡ã®ãã©ãã«ã·ã¥ãŒãã£ã³ã°èœåãåäžããŸãã
- Tracing and Distributed Tracing: ãã€ã¯ããµãŒãã¹ã忣ã¢ããªã±ãŒã·ã§ã³ã®å Žåããªã¯ãšã¹ããè€æ°ã®ãµãŒãã¹ãééããéã«è¿œè·¡ããããã®ãã¬ãŒã·ã³ã°ãå®è£ ããŸããJaegerãZipkinãOpenTelemetryãªã©ã®ã©ã€ãã©ãªããã¬ãŒã·ã³ã°ã«åœ¹ç«ã¡ãŸããããã«ãããç°ãªããµãŒãã¹éã®ãã°ã¡ãã»ãŒãžãçžé¢ãããã¢ããªã±ãŒã·ã§ã³ã®ãšã³ãããŒãšã³ãã®æ¯ãèãã«é¢ããæŽå¯ãæäŸããè€éãªåæ£ã·ã¹ãã ã«ãããããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ã§ããŸãã
çµè«ïŒæåã®ããã®ãã®ã³ã°
广çãªãã®ã³ã°ã¯ããœãããŠã§ã¢éçºã®åºæ¬çãªåŽé¢ã§ããPythonã®ãã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ã«å æ¬çãªãã®ã³ã°ãå®è£ ããããã«å¿ èŠãªããŒã«ãæäŸããŸãããã³ãã©èšå®ãã«ã¹ã¿ã ãã©ãŒããã¿ããã¹ããã©ã¯ãã£ã¹ãçè§£ããããšã§ãå ç¢ã§å¹ççãªãã®ã³ã°ãœãªã¥ãŒã·ã§ã³ãäœæã§ãã以äžã®ããšãå¯èœã«ãªããŸãã
- 广çãªãããã°ïŒ åé¡ã®æ ¹æ¬åå ãããè¿ éã«ç¹å®ããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®å¥å šæ§ã®ç£èŠïŒ æœåšçãªåé¡ãç©æ¥µçã«ç¹å®ããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹åäžïŒ ãã®ã³ã°ããåŸãããæŽå¯ã«åºã¥ããŠã³ãŒããæé©åããŸãã
- 貎éãªæŽå¯ã®ç²åŸïŒ ã¢ããªã±ãŒã·ã§ã³ãã©ã®ããã«äœ¿çšãããŠããããçè§£ããŸãã
- èŠå¶èŠä»¶ã®éµå®ïŒ ãã®ã³ã°ããã³ç£æ»åºæºã«æºæ ããŸãã
ããªããæ ãå§ããã°ããã®ãžã¥ãã¢éçºè ã§ãããå€§èŠæš¡ãªåæ£ã·ã¹ãã ãæ§ç¯ããŠããçµéšè±å¯ãªãããã§ãã·ã§ãã«ã§ãããPythonã®ãã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã«é¢ãã確ããªçè§£ã¯éåžžã«è²Žéã§ãããããã®æŠå¿µãé©çšããç¹å®ã®ããŒãºã«åãããŠäŸã調æŽãããã®ã³ã°ã®åãæŽ»çšããŠãã°ããŒãã«ãªç°å¢ã§ããä¿¡é Œæ§ãé«ããä¿å®ãããããœãããŠã§ã¢ãäœæããŠãã ãããäžè²«ãããã®ã³ã°ã¯ãçç£æ§ãåäžãããã¢ããªã±ãŒã·ã§ã³ãæåãåããããã«å¿ èŠãªéèŠãªæŽå¯ãæäŸããŸãã