GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — kale/submit-debug-info ( c0cb8c...f2d693 )
by
unknown
08:15
created

st2common.find_caller()   B

Complexity

Conditions 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 24
rs 8.6845
cc 4
1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
from __future__ import absolute_import
17
18
import os
19
import sys
20
import logging
21
import logging.config
22
import logging.handlers
23
import traceback
24
from functools import wraps
25
26
import six
27
28
from st2common.logging.filters import ExclusionFilter
29
30
# Those are here for backward compatibility reasons
31
from st2common.logging.handlers import FormatNamedFileHandler
32
from st2common.logging.handlers import ConfigurableSyslogHandler
33
from st2common.util.misc import prefix_dict_keys
34
from st2common.util.misc import get_normalized_file_path
35
36
__all__ = [
37
    'getLogger',
38
    'setup',
39
40
    'FormatNamedFileHandler',
41
    'ConfigurableSyslogHandler',
42
43
    'LoggingStream'
44
]
45
46
logging.AUDIT = logging.CRITICAL + 10
47
logging.addLevelName(logging.AUDIT, 'AUDIT')
48
49
LOGGER_KEYS = [
50
    'debug',
51
    'info',
52
    'warning',
53
    'error',
54
    'critical',
55
    'exception',
56
    'log',
57
58
    'audit'
59
]
60
61
# Note: This attribute is used by "find_caller" so it can correctly exclude this file when looking
62
# for the logger method caller frame.
63
_srcfile = get_normalized_file_path(__file__)
64
65
66
def find_caller():
67
    """
68
    Find the stack frame of the caller so that we can note the source file name, line number and
69
    function name.
70
71
    Note: This is based on logging/__init__.py:findCaller and modified so it takes into account
72
    this file - https://hg.python.org/cpython/file/2.7/Lib/logging/__init__.py#l1233
73
    """
74
    rv = '(unknown file)', 0, '(unknown function)'
75
76
    try:
77
        f = logging.currentframe().f_back
78
        while hasattr(f, 'f_code'):
79
            co = f.f_code
80
            filename = os.path.normcase(co.co_filename)
81
            if filename in (_srcfile, logging._srcfile):  # This line is modified.
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _srcfile was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
82
                f = f.f_back
83
                continue
84
            rv = (filename, f.f_lineno, co.co_name)
85
            break
86
    except Exception:
87
        pass
88
89
    return rv
90
91
92
def decorate_log_method(func):
93
    @wraps(func)
94
    def func_wrapper(*args, **kwargs):
95
        # Prefix extra keys with underscore
96
        if 'extra' in kwargs:
97
            kwargs['extra'] = prefix_dict_keys(dictionary=kwargs['extra'], prefix='_')
98
99
        try:
100
            return func(*args, **kwargs)
101
        except TypeError as e:
102
            # In some version of Python 2.7, logger.exception doesn't take any kwargs so we need
103
            # this hack :/
104
            # See:
105
            # - https://docs.python.org/release/2.7.3/library/logging.html#logging.Logger.exception
106
            # - https://docs.python.org/release/2.7.7/library/logging.html#logging.Logger.exception
107
            if 'got an unexpected keyword argument \'extra\'' in str(e):
108
                kwargs.pop('extra', None)
109
                return func(*args, **kwargs)
110
            raise e
111
    return func_wrapper
112
113
114
def decorate_logger_methods(logger):
115
    """
116
    Decorate all the logger methods so all the keys in the extra dictionary are
117
    automatically prefixed with an underscore to avoid clashes with standard log
118
    record attributes.
119
    """
120
121
    # Note: We override findCaller with our custom implementation which takes into account this
122
    # module.
123
    # This way filename, module, funcName and lineno LogRecord attributes contain correct values
124
    # instead of all pointing to decorate_log_method.
125
    logger.findCaller = find_caller
126
    for key in LOGGER_KEYS:
127
        log_method = getattr(logger, key)
128
        log_method = decorate_log_method(log_method)
129
        setattr(logger, key, log_method)
130
131
    return logger
132
133
134
def getLogger(name):
135
    # make sure that prefix isn't appended multiple times to preserve logging name hierarchy
136
    prefix = 'st2.'
137
    if name.startswith(prefix):
138
        logger = logging.getLogger(name)
139
    else:
140
        logger_name = '{}{}'.format(prefix, name)
141
        logger = logging.getLogger(logger_name)
142
143
    logger = decorate_logger_methods(logger=logger)
144
    return logger
145
146
147
class LoggingStream(object):
148
149
    def __init__(self, name, level=logging.ERROR):
150
        self._logger = getLogger(name)
151
        self._level = level
152
153
    def write(self, message):
154
        self._logger._log(self._level, message, None)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _log was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
155
156
157
def _audit(logger, msg, *args, **kwargs):
158
    if logger.isEnabledFor(logging.AUDIT):
159
        logger._log(logging.AUDIT, msg, args, **kwargs)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _log was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
160
161
logging.Logger.audit = _audit
162
163
164
def _add_exclusion_filters(handlers, excludes=None):
165
    if excludes:
166
        for h in handlers:
167
            h.addFilter(ExclusionFilter(excludes))
168
169
170
def _redirect_stderr():
171
    # It is ok to redirect stderr as none of the st2 handlers write to stderr.
172
    sys.stderr = LoggingStream('STDERR')
173
174
175
def setup(config_file, redirect_stderr=True, excludes=None, disable_existing_loggers=False):
176
    """
177
    Configure logging from file.
178
    """
179
    try:
180
        logging.config.fileConfig(config_file,
181
                                  defaults=None,
182
                                  disable_existing_loggers=disable_existing_loggers)
183
        handlers = logging.getLoggerClass().manager.root.handlers
184
        _add_exclusion_filters(handlers)
185
        if redirect_stderr:
186
            _redirect_stderr()
187
    except Exception as exc:
188
        # revert stderr redirection since there is no logger in place.
189
        sys.stderr = sys.__stderr__
190
        # No logger yet therefore write to stderr
191
        sys.stderr.write('ERROR: %s' % traceback.format_exc())
192
        raise Exception(six.text_type(exc))
193