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

kytos.core.apm.ElasticAPM.init_flask_app()   A

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0185

Importance

Changes 0
Metric Value
cc 2
eloc 6
nop 2
dl 0
loc 7
ccs 5
cts 6
cp 0.8333
crap 2.0185
rs 10
c 0
b 0
f 0
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