Passed
Push — master ( 14177f...432f3e )
by Daniil
01:53
created

logger.Logger.__init__()   A

Complexity

Conditions 2

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
"""
2
3
Info about logging levels:
4
5
DEBUG: Detailed information, typically of interest only when diagnosing problems.
6
7
INFO: Confirmation that things are working as expected.
8
9
WARNING: An indication that something unexpected happened, or indicative of some
10
problem in the near future (e.g. ‘disk space low’). The software is still working
11
as expected.
12
13
ERROR: Due to a more serious problem, the software has not been able to perform
14
some function.
15
16
CRITICAL: A serious error, indicating that the program itself may be unable to
17
continue running.
18
19
"""
20
21
import logging
22
from logging import Handler
23
from logging import LogRecord
24
from logging import Formatter
25
import os
26
from datetime import datetime, timezone, timedelta
27
28
import requests
29
30
31
class TelegramHandler(Handler):
32
    def emit(self, record: LogRecord) -> None:
33
        log_entry = self.format(record)
34
        token = os.environ["TG_TOKEN"]
35
        chat_ids = os.environ["TG_CHATS"].split(",")
36
        notifications = False
37
        if record.levelno < 30:
38
            notifications = True
39
        for chat in chat_ids:
40
            requests.get(
41
                f"https://api.telegram.org/bot{token}/sendMessage",
42
                params={
43
                    "chat_id": chat,
44
                    "text": log_entry,
45
                    "parse_mode": "markdown",
46
                    "disable_notification": notifications,
47
                },
48
            )
49
50
51
class TelegramFormatter(Formatter):
52
    def format(self, record: LogRecord) -> str:
53
        message = record.msg
54
        levelname = record.levelname
55
        module = record.module
56
        timestamp = datetime.utcfromtimestamp(record.created)
57
        ts = (
58
            timestamp.replace(tzinfo=timezone.utc)
59
            .astimezone(tz=timezone(timedelta(hours=3)))
60
            .strftime("%d.%m.%Y %H:%M:%S")
61
        )
62
        fmt = f"[{levelname}] ({module}): {ts}\n{message}"
63
        if record.exc_info:
64
            fmt += f"\n{record.exc_info[1].__repr__()}"
65
        return fmt
66
67
68
class Logger:
69
    def __init__(self):
70
        self.logger = logging.getLogger(__name__)
71
        if self.logger.hasHandlers():
72
            self.logger.handlers.clear()
73
74
    def init(self):
75
        self.logger.setLevel("INFO")
76
        console = logging.StreamHandler()
77
        formatter = TelegramFormatter()
78
        console.setFormatter(formatter)
79
        self.logger.addHandler(console)
80
        if "PRODUCTION" in os.environ:
81
            tg = TelegramHandler()
82
            tg.setFormatter(formatter)
83
            self.logger.addHandler(tg)
84
        return self.logger
85