- ãã®è¨äºã¯ä½ï¼
- Slackéç¥ç¨ãã³ãã©ã®å®ç¾©
- Slackã«éç¥ãããã°ãæ¯ãåãã
- ãã°ã¬ãã«ã§Slackã«éç¥ãããã°ãæ¯ãåããã®ã¯ï¼
- åè
ãã®è¨äºã¯ä½ï¼
Pythonã§ãã°ãSlackã«éç¥ãããã¨ããlogging.handlers.HTTPHandler
ãç¶æ¿ããSlackHandler
ã®ãããªSlackéç¥ç¨ãã³ãã©ãå®ç¾©ããããªãã¨æãã¾ãã
ããã§ãSlackã«ãªãã§ãããã§ããã°ãéç¥ãã¦ãã¾ãã¨Slackã®ã¡ãã»ã¼ã¸ãã©ãã©ãæµãã¦ãã¾ããããéè¦ãªãã°ã ãéç¥ããããªãã¾ãã
ãããå®ç¾ããæ¹æ³ã¨ãã¦ãä¾ãã°ãã°ã¬ãã«ãWARN
以ä¸ã®ãã°ãé£ã°ããªã©ãèãããã¾ãã
ãããINFO
ã®ãã°ãéç¥ããããã¨ã¯ããINFO
ã®ãã°ãå
¨ã¦éç¥ãã¦ãã¾ãã¨ã¡ãã»ã¼ã¸ãæµãã¦ãã¾ãâ¦ã¨ããåé¡ãåºã¦ãã¾ãã
ããã§ãã®è¨äºã§ã¯ããã£ã«ã¿ãå©ç¨ãã¦Slackã«éç¥ãããã°ãæ¯ãåããæ¹æ³ãç´¹ä»ãã¾ãã
Slackéç¥ç¨ãã³ãã©ã®å®ç¾©
ã¾ãã¯Slackã«ãã°ãé£ã°ãããã®ãã³ãã©ãå®ç¾©ãã¾ãã
ä»åã¯Incoming Webhooksãå©ç¨ãã¾ãã
import logging from logging.handlers import HTTPHandler HOST = "hooks.slack.com" PATH = "/services/xxx" # Webhook URLãæå® class SlackHandler(HTTPHandler): def __init__(self): super().__init__(HOST, PATH, method="POST", secure=True) def mapLogRecord(self, record): text = self.format(record) return {"payload": {"text": text}}
HTTPHandler
ãç¶æ¿ããmapLogRecord
ããªã¼ãã¼ã©ã¤ããã¦ãããã°OKã§ãã
以ä¸ã®ã³ã¼ãã§Slackã«ãã°ãé£ã°ãã¾ãã
logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) slack_handler = SlackHandler() formatter = logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s") slack_handler.setFormatter(formatter) logger.addHandler(slack_handler) logger.addHandler(logging.StreamHandler()) logger.info("Hello Slack!") logger.info("This message should not be posted on slack.")
Slackã«éç¥ãããã°ãæ¯ãåãã
ä¸ã³ã¼ãã§ã¯Hello Slack!
ããã³This message should not be posted on slack.
ã®2ã¤ã®ã¡ãã»ã¼ã¸ãSlackã«éç¥ããã¾ãã
ããã§ã1ã¤ç®ã®ã¡ãã»ã¼ã¸Hello Slack!
ã¯Slackã«éç¥ããããã2ã¤ç®ã®ã¡ãã»ã¼ã¸This message should not be posted on slack.
ã¯éç¥ããããªãã¨ãã¾ãã
ãããå®ç¾ããããã«ãSlackã«ãã°ãéç¥ãããã©ããå¤å®ãããã£ã«ã¿ãå®ç¾©ãããã¨æãã¾ãã
ãã£ã«ã¿ã«é¢ãã説æãããã¥ã¡ã³ãããå¼ç¨ãã¾ãã
ãã£ã«ã¿ (Filter) ã¯ããã³ãã© ã ãã¬ã¼ ã«ãã£ã¦ä½¿ãããã¬ãã«ã«ãã£ã¦æä¾ãããã®ãããæ´ç·´ããããã£ã«ã¿ãªã³ã°ãå®ç¾ãã¾ããåºåºã®ãã£ã«ã¿ã¯ã©ã¹ã¯ããã¬ã¼é層æ§é å ã®ç¹å®å°ç¹ã®é ä¸ã«ããã¤ãã³ãã ãã許å¯ãã¾ããä¾ãã°ã'A.B' ã§åæåããããã£ã«ã¿ã¯ããã¬ã¼ 'A.B', 'A.B.C', 'A.B.C.D', 'A.B.D' çã«ãã£ã¦è¨é²ãããã¤ãã³ãã¯è¨±å¯ãã¾ããã'A.BB', 'B.A.B' ãªã©ã¯è¨±å¯ãã¾ããã空ã®æååã§åæåãããå ´åããã¹ã¦ã®ã¤ãã³ããééããã¾ãã
https://docs.python.org/ja/3/library/logging.html#filter-objects
ãã£ã«ã¿ã¯é¢æ°ã¨ãã¦ãå®ç¾©ãããã¨ãã§ãã¾ãã
ãã¼ã¸ã§ã³ 3.2 ã§å¤æ´: ç¹æ®ãª Filter ã¯ã©ã¹ãä½ã£ããã filter ã¡ã½ãããæã¤ä»ã®ã¯ã©ã¹ã使ãå¿ è¦ã¯ããã¾ãã: é¢æ° (ãããã¯ä»ã® callable) ããã£ã«ã¿ã¨ãã¦ä½¿ç¨ãããã¨ãã§ãã¾ãããã£ã«ã¿ãã¸ãã¯ã¯ããã£ã«ã¿ãªãã¸ã§ã¯ãã filter å±æ§ãæã£ã¦ãããã©ãããã§ãã¯ãã¾ã: ãã filter å±æ§ãæã£ã¦ãããããã㯠Filter ã§ããã¨ä»®å®ããããã® filter() ã¡ã½ãããå¼ã³åºããã¾ããããã§ãªããã°ããã㯠callable ã§ããã¨ä»®å®ãããã¬ã³ã¼ããåä¸ã®ãã©ã¡ã¼ã¿ã¨ãã¦å¼ã³åºããã¾ããè¿ãããå¤ã¯ filter() ã«ãã£ã¦è¿ããããã®ã¨ä¸è´ãã¹ãã§ãã
ä»åã¯ãSlackã«ãã°ãéç¥ãããã©ããå¤å®ãããã£ã«ã¿ãé¢æ°ã§å®ç¾©ãã¾ããã
def slack_filter(record): return getattr(record, "notify_slack", False)
ãã®é¢æ°ã¯ãæå®ãããrecord
ã®notify_slack
å±æ§ï¼Booleanã§ãããã¨ãæå¾
ï¼ãåå¾ãã¦è¿ãã¾ãã
ããã§ãrecord
ã«notify_slack
å±æ§ãæãããããã«ããã®ã³ã°é¢æ°ãå®è¡ããéã«ãã¼ã¯ã¼ãå¼æ°extra
ãæå®ãã¾ãã
ãã¼ã¯ã¼ãå¼æ°extra
ã«é¢ãã説æãããã¥ã¡ã³ãããå¼ç¨ãã¾ãã
3çªç®ã®ãã¼ã¯ã¼ãå¼æ°ã¯ extra ã§ãå½è©²ãã°ã¤ãã³ãç¨ã«ä½ããã LogRecoed ã® __dict__ ã«ã¦ã¼ã¶ã¼å®ç¾©å±æ§ãå ããã®ã«ä½¿ãããè¾æ¸ã渡ãããã«ç¨ãããã¾ãããããã®å±æ§ã¯å¥½ããªããã«ä½¿ãã¾ãã
https://docs.python.org/ja/3/library/logging.html#logging.debug
以ä¸ã®ããã«ãlogger.info
ãå®è¡ããéã«ãã¼ã¯ã¼ãå¼æ°extra
ã§notify_slack
å±æ§ãã¬ã³ã¼ãã«å ãã¾ãã
logger.info("Hello Slack!", extra={"notify_slack": True})
{"notify_slack": True}
ãªã®ã§ãä¸ã®ã¡ãã»ã¼ã¸ã¯Slackã«éç¥ããããã¨ãæå¾
ããã¾ãã
ã³ã¼ãå ¨ä½ã¯ä»¥ä¸ã®ããã«ãªãã¾ãã
import logging from logging.handlers import HTTPHandler HOST = "hooks.slack.com" PATH = "/services/xxx" # Webhook URLãæå® class SlackHandler(HTTPHandler): def __init__(self): super().__init__(HOST, PATH, method="POST", secure=True) def mapLogRecord(self, record): text = self.format(record) return {"payload": {"text": text}} def slack_filter(record): return getattr(record, "notify_slack", False) logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) slack_handler = SlackHandler() formatter = logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s") slack_handler.setFormatter(formatter) slack_handler.addFilter(slack_filter) logger.addHandler(slack_handler) logger.addHandler(logging.StreamHandler()) logger.info("Hello Slack!", extra={"notify_slack": True}) logger.info("This message should not be posted on slack.")
slack_handler.addFilter(slack_filter)
ã§ãã£ã«ã¿ã追å ãã¦ãã¾ãã
ä¸è¨ã³ã¼ããå®è¡ããã¨ã1ã¤ç®ã®ã¡ãã»ã¼ã¸ã ãSlackã«éç¥ããã¾ããã2ã¤ç®ã®ã¡ãã»ã¼ã¸ã¯Slackã«éç¥ããã¾ããã
ã¨ããããã§ããããããã¨ãéæã§ãã¾ããã
ãã°ã¬ãã«ã§Slackã«éç¥ãããã°ãæ¯ãåããã®ã¯ï¼
以ä¸ã®è¨äºã§ã¯ãSlackã«éç¥ãããã°ãæ¯ãåããæ¹æ³ã¨ãã¦ããã°ã¬ãã«INFO
ã¨WARNING
ã®ä¸éã®ãã°ã¬ãã«ãç¬èªå®ç¾©ãã対象ã®ãã°ã¬ãã«ã«ã¤ãã¦Slackã«éç¥ããã¨ããæ¹æ³ãç´¹ä»ãã¦ãã¾ãã
jun-networks.hatenablog.com
ãã®æ¹æ³ã§ãSlackã«éç¥ãããã°ãæ¯ãåãããã¨ãã§ããã®ã§ãããããã¥ã¡ã³ãã«ããã¨ãã°ã¬ãã«ãç¬èªå®ç¾©ããã®ã¯éæ¨å¥¨ã®ããã§ãã
ç¬èªã®ã¬ãã«ãå®ç¾©ãããã¨ã¯å¯è½ã§ãããå¿ é ã§ã¯ãªããå®çµé¨ä¸ã¯æ¢åã®ã¬ãã«ãé¸ã°ãã¾ããããããã«ã¹ã¿ã ã¬ãã«ãå¿ è¦ã ã¨ç¢ºä¿¡ãããªããã¬ãã«ã®å®ç¾©ã«ã¯å¤å¤§ãªæ³¨æãæãã¹ãã§ãã©ã¤ãã©ãªã®éçºã®éãã«ã¹ã¿ã ã¬ãã«ãå®ç¾©ãããã¨ã¯ã¨ã¦ãæªãã¢ã¤ã㢠ã«ãªãå¾ã¾ããããã¯ãè¤æ°ã®ã©ã¤ãã©ãªã®ä½è ãã¿ãªç¬èªã®ã«ã¹ã¿ã ã¬ãã«ãå®ç¾©ããã¨ãä¸ããããæ°å¤ãç°ãªãã©ã¤ãã©ãªã§ç°ãªãæå³ã«ãªããããããéçºè ããããå¶å¾¡ã¾ãã¯è§£éããã®ãé£ãããªãããã§ãã
https://docs.python.org/ja/3/howto/logging.html#custom-levels
åè
以ä¸ã®ããã¸ã§ã¯ãã大ãã«åèã«ããã¦ããã ãã¾ããã
https://github.com/junhwi/python-slack-loggergithub.com