Passed
Pull Request — master (#209)
by Vinicius
14:29 queued 06:00
created

kytos.core.apm   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Test Coverage

Coverage 97.78%

Importance

Changes 0
Metric Value
eloc 58
dl 0
loc 83
ccs 44
cts 45
cp 0.9778
rs 10
c 0
b 0
f 0
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A ElasticAPM.init_flask_app() 0 7 2
A ElasticAPM.init_client() 0 21 3
A ElasticAPM.get_client() 0 6 2

2 Functions

Rating   Name   Duplication   Size   Complexity  
A init_apm() 0 9 2
A begin_span() 0 14 3
1
"""APM module."""
2 2
import os
3 2
from functools import wraps
4
5 2
from elasticapm import Client
6 2
from elasticapm.contrib.flask import ElasticAPM as FlaskAPM
7 2
from elasticapm.traces import execution_context
8
9 2
from kytos.core.exceptions import KytosAPMInitException
10
11
12 2
def init_apm(apm_backend="es", **kwargs):
13
    """Init APM backend."""
14 2
    backends = {"es": ElasticAPM}
15 2
    try:
16 2
        return backends[apm_backend].init_client(**kwargs)
17 2
    except KeyError:
18 2
        client_names = ",".join(list(backends.keys()))
19 2
        raise KytosAPMInitException(
20
            f"APM backend '{apm_backend}' isn't supported."
21
            f" Current supported APMs: {client_names}"
22
        )
23
24
25 2
def begin_span(func, span_type="custom"):
26
    """APM transaction begin_span decorator."""
27
28 2
    @wraps(func)
29
    def wrapper(*args, **kwds):
30 2
        transaction = execution_context.get_transaction()
31 2
        if transaction:
32 2
            transaction.begin_span(func.__name__, span_type)
33 2
        result = func(*args, **kwds)
34 2
        if transaction:
35 2
            transaction.end_span()
36 2
        return result
37
38 2
    return wrapper
39
40
41 2
class ElasticAPM:
42
    """ElasticAPM Client instance."""
43
44 2
    _flask_apm: FlaskAPM = None
45 2
    _client: Client = None
46
47 2
    @classmethod
48 2
    def get_client(cls, **kwargs) -> Client:
49
        """Get client."""
50 2
        if not cls._client:
51 2
            return cls.init_client(**kwargs)
52 2
        return cls._client
53
54 2
    @classmethod
55 2
    def init_flask_app(cls, app) -> FlaskAPM:
56
        """Init Flask APM Client."""
57 2
        if not cls._flask_apm:
58
            return None
59 2
        cls._flask_apm.init_app(app)
60 2
        return cls._flask_apm
61
62 2
    @classmethod
63 2
    def init_client(
64
        cls,
65
        service_name=os.environ.get("ELASTIC_APM_SERVICE_NAME", "kytos"),
66
        server_url=os.environ.get("ELASTIC_APM_URL", "http://localhost:8200"),
67
        secret_token=os.environ.get("ELASTIC_APM_SECRET_TOKEN",
68
                                    "elasticapm_token"),
69
        **kwargs,
70
    ) -> Client:
71
        """Init APM Client."""
72 2
        app = kwargs.pop("app", None)
73 2
        if not cls._client:
74 2
            cls._client = Client(
75
                service_name=service_name,
76
                server_url=server_url,
77
                secret_token=secret_token,
78
                **kwargs,
79
            )
80 2
        if not cls._flask_apm:
81 2
            cls._flask_apm = FlaskAPM(client=cls._client, app=app)
82
        return cls._client
83