Passed
Pull Request — master (#209)
by Vinicius
13:06 queued 09:04
created

kytos.core.apm.begin_span()   A

Complexity

Conditions 3

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 11
nop 2
dl 0
loc 14
ccs 11
cts 11
cp 1
crap 3
rs 9.85
c 0
b 0
f 0
1
"""APM module."""
2 1
import os
3 1
from functools import wraps
4
5 1
from elasticapm import Client
6 1
from elasticapm.contrib.flask import ElasticAPM as FlaskAPM
7 1
from elasticapm.traces import execution_context
8
9 1
from kytos.core.exceptions import KytosAPMInitException
10
11
12 1
def init_apm(apm_backend="es", **kwargs):
13
    """Init APM backend."""
14 1
    backends = {"es": ElasticAPM}
15 1
    try:
16 1
        return backends[apm_backend].init_client(**kwargs)
17 1
    except KeyError:
18 1
        client_names = ",".join(list(backends.keys()))
19 1
        raise KytosAPMInitException(
20
            f"APM backend '{apm_backend}' isn't supported."
21
            f" Current supported APMs: {client_names}"
22
        )
23
24
25 1
def begin_span(func, span_type="custom"):
26
    """APM transaction begin_span decorator."""
27
28 1
    @wraps(func)
29 1
    def wrapper(*args, **kwds):
30 1
        transaction = execution_context.get_transaction()
31 1
        if transaction:
32 1
            transaction.begin_span(func.__name__, span_type)
33 1
        result = func(*args, **kwds)
34 1
        if transaction:
35 1
            transaction.end_span()
36 1
        return result
37
38 1
    return wrapper
39
40
41 1
class ElasticAPM:
42
    """ElasticAPM Client instance."""
43
44 1
    _flask_apm: FlaskAPM = None
45 1
    _client: Client = None
46
47 1
    @classmethod
48 1
    def get_client(cls, **kwargs) -> Client:
49
        """Get client."""
50 1
        if not cls._client:
51 1
            return cls.init_client(**kwargs)
52 1
        return cls._client
53
54 1
    @classmethod
55 1
    def init_flask_app(cls, app) -> FlaskAPM:
56
        """Init Flask APM Client."""
57 1
        if not cls._flask_apm:
58
            return None
59 1
        cls._flask_apm.init_app(app)
60 1
        return cls._flask_apm
61
62 1
    @classmethod
63 1
    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 1
        app = kwargs.pop("app", None)
73 1
        if not cls._client:
74 1
            cls._client = Client(
75
                service_name=service_name,
76
                server_url=server_url,
77
                secret_token=secret_token,
78
                **kwargs,
79
            )
80 1
        if not cls._flask_apm:
81 1
            cls._flask_apm = FlaskAPM(client=cls._client, app=app)
82
        return cls._client
83