1from . import ffi, librtmp
2from .utils import add_signal_handler
3
4__all__ = ["set_log_level", "get_log_level",
5           "set_log_output", "add_log_callback", "remove_log_callback",
6           "LOG_CRIT", "LOG_ERROR", "LOG_WARNING",
7           "LOG_INFO", "LOG_DEBUG", "LOG_DEBUG2",
8           "LOG_ALL"]
9
10(LOG_CRIT, LOG_ERROR, LOG_WARNING, LOG_INFO, LOG_DEBUG,
11 LOG_DEBUG2, LOG_ALL) = range(1, 8)
12
13_log_callbacks = set()
14_log_level = LOG_ALL
15_log_output = None
16
17
18def set_log_level(level):
19    """Sets log level."""
20
21    global _log_level
22    _log_level = level
23
24
25def get_log_level():
26    """Returns current log level."""
27    return _log_level
28
29
30def set_log_output(fd):
31    """Sets log output to a open file-object."""
32    global _log_output
33    _log_output = fd
34
35
36def add_log_callback(callback):
37    """Adds a log callback."""
38    global _log_callbacks
39
40    if not callable(callback):
41        raise ValueError("Callback must be callable")
42
43    _log_callbacks.add(callback)
44    return callback
45
46
47def remove_log_callback(callback):
48    """Removes a log callback."""
49    global _log_callbacks
50    _log_callbacks.remove(callback)
51
52
53@ffi.callback("void(int,char*)")
54def _log_callback(level, msg):
55    msg = ffi.string(msg)
56    msg = msg.decode("utf8", "ignore")
57
58    for callback in _log_callbacks:
59        callback(level, msg)
60
61    if hasattr(_log_output, "write") and level <= _log_level:
62        _log_output.write(msg + "\n")
63
64librtmp.python_log_callback = _log_callback
65librtmp.RTMP_LogSetCallback(librtmp.c_log_callback)
66
67add_signal_handler()
68