summaryrefslogtreecommitdiff
path: root/ncserver/base/log.py
blob: 411fa1000b96f1c31396d2b2fb7e14f7a8e60424 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"""
NETCONF for APK Distributions server:
    Logging setup and routines.

Copyright © 2020 Adélie Software in the Public Benefit, Inc.

Released under the terms of the NCSA license.  See the LICENSE file included
with this source distribution for more information.

SPDX-License-Identifier: NCSA
"""


import logging

from socket import gethostname
from taillight import Signal

from ncserver.base.util import user_for_session


HOSTNAME_CHANGED = Signal(('node_changed', 'sys:hostname'))
"""The signal that will fire when the hostname is changed."""

HANDLER = logging.StreamHandler()
"""The root log handler."""

LOG_AUTH = logging.getLogger('ncserver.auth')
"""The authentication logger."""

LOG_CONFIG = logging.getLogger('ncserver.config')
"""The configuration logger."""

LOG_OPERATIONAL = logging.getLogger('ncserver.operational')
"""The operational logger."""


def log_config_change(session, node, info):
    """Log a configuration change."""
    LOG_CONFIG.notice(
            '%s on session %d is editing %s: %s',
            user_for_session(session), session.session_id, node, info
    )


def configure_format(hostname: str):
    """Configure the formatter for the root log handler."""
    fmt = logging.Formatter('%(asctime)s ' + hostname +
                            ' %(name)s %(levelname)s: %(message)s',
                            '%Y-%m-%dT%H:%M:%S')
    HANDLER.setFormatter(fmt)


def configure_logging(level: int):
    """Configure the logging system."""
    configure_format(gethostname())

    root = logging.getLogger()

    HANDLER.setLevel(level)
    root.setLevel(level)

    root.addHandler(HANDLER)


HOSTNAME_CHANGED.add(configure_format)

if not hasattr(logging, 'NOTICE'):
    logging.addLevelName(25, 'NOTICE')
    logging.NOTICE = 25

    def log_notice(self, message, *args, **kwargs):
        """Log a NOTICE message."""
        if self.isEnabledFor(25):
            self._log(25, message, args, **kwargs)  # pylint: disable=W0212
    logging.getLoggerClass().notice = log_notice

    def root_notice(message, *args, **kwargs):
        """Log a NOTICE message."""
        logging.log(25, message, *args, **kwargs)
    logging.notice = root_notice