~homeworkprod/byceps

ref: 4237b3ec9496efe95dcce82bea3207ab9de4d520 byceps/byceps/services/metrics/service.py -rw-r--r-- 6.4 KiB
4237b3ec — Jochen Kupperschmidt Move ticketing blueprint into `site` subpackage 1 year, 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
"""
byceps.metrics.service
~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2020 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from typing import Iterator, List, Set

from ...services.brand import service as brand_service
from ...services.board import (
    board_service,
    topic_query_service as board_topic_query_service,
    posting_query_service as board_posting_query_service,
)
from ...services.consent import consent_service
from ...services.metrics.models import Label, Metric
from ...services.party.transfer.models import Party
from ...services.party import service as party_service
from ...services.seating import seat_service
from ...services.shop.order import service as order_service
from ...services.shop.article import service as shop_article_service
from ...services.shop.shop import service as shop_service
from ...services.shop.shop.transfer.models import Shop, ShopID
from ...services.ticketing import ticket_service
from ...services.user import stats_service as user_stats_service
from ...typing import BrandID, PartyID


def serialize(metrics: Iterator[Metric]) -> Iterator[str]:
    """Serialize metric objects to text lines."""
    for metric in metrics:
        yield metric.serialize() + '\n'


def collect_metrics() -> Iterator[Metric]:
    brand_ids = [brand.id for brand in brand_service.get_brands()]

    active_parties = party_service.get_active_parties()
    active_party_ids = [p.id for p in active_parties]

    active_shops = shop_service.get_active_shops()
    active_shop_ids = {shop.id for shop in active_shops}

    yield from _collect_board_metrics(brand_ids)
    yield from _collect_consent_metrics()
    yield from _collect_shop_ordered_article_metrics(active_shop_ids)
    yield from _collect_shop_order_metrics(active_shops)
    yield from _collect_seating_metrics(active_party_ids)
    yield from _collect_ticket_metrics(active_parties)
    yield from _collect_user_metrics()


def _collect_board_metrics(brand_ids: List[BrandID]) -> Iterator[Metric]:
    for brand_id in brand_ids:
        boards = board_service.get_boards_for_brand(brand_id)
        board_ids = [board.id for board in boards]

        for board_id in board_ids:
            labels = [Label('board', board_id)]

            topic_count = board_topic_query_service.count_topics_for_board(
                board_id
            )
            yield Metric('board_topic_count', topic_count, labels=labels)

            posting_count = board_posting_query_service.count_postings_for_board(
                board_id
            )
            yield Metric('board_posting_count', posting_count, labels=labels)


def _collect_consent_metrics() -> Iterator[Metric]:
    consents_per_subject = consent_service.count_consents_by_subject()
    for subject_name, consent_count in consents_per_subject.items():
        yield Metric(
            'consent_count',
            consent_count,
            labels=[Label('subject_name', subject_name)],
        )


def _collect_shop_ordered_article_metrics(
    shop_ids: Set[ShopID],
) -> Iterator[Metric]:
    """Provide ordered article quantities for shops."""
    stats = shop_article_service.sum_ordered_articles_by_payment_state(shop_ids)

    for shop_id, article_number, description, payment_state, quantity in stats:
        yield Metric(
            'shop_ordered_article_quantity',
            quantity,
            labels=[
                Label('shop', shop_id),
                Label('article_number', article_number),
                Label('description', description),
                Label('payment_state', payment_state.name),
            ],
        )


def _collect_shop_order_metrics(shops: List[Shop]) -> Iterator[Metric]:
    """Provide order counts grouped by payment state for shops."""
    for shop in shops:
        order_counts_per_payment_state = order_service.count_orders_per_payment_state(
            shop.id
        )

        for payment_state, quantity in order_counts_per_payment_state.items():
            yield Metric(
                'shop_order_quantity',
                quantity,
                labels=[
                    Label('shop', shop.id),
                    Label('payment_state', payment_state.name),
                ],
            )


def _collect_seating_metrics(
    active_party_ids: List[PartyID],
) -> Iterator[Metric]:
    """Provide seat occupation counts per party and category."""
    for party_id in active_party_ids:
        occupied_seat_counts_by_category = seat_service.count_occupied_seats_by_category(
            party_id
        )

        for category, count in occupied_seat_counts_by_category:
            yield Metric(
                'occupied_seat_count',
                count,
                labels=[
                    Label('party', party_id),
                    Label('category_title', category.title),
                ],
            )


def _collect_ticket_metrics(active_parties: List[Party]) -> Iterator[Metric]:
    """Provide ticket counts for active parties."""
    for party in active_parties:
        party_id = party.id
        labels = [Label('party', party_id)]

        max_ticket_quantity = party.max_ticket_quantity
        if max_ticket_quantity is not None:
            yield Metric('tickets_max', max_ticket_quantity, labels=labels)

        tickets_revoked_count = ticket_service.count_revoked_tickets_for_party(
            party_id
        )
        yield Metric(
            'tickets_revoked_count', tickets_revoked_count, labels=labels
        )

        tickets_sold_count = ticket_service.count_sold_tickets_for_party(
            party_id
        )
        yield Metric('tickets_sold_count', tickets_sold_count, labels=labels)

        tickets_checked_in_count = ticket_service.count_tickets_checked_in_for_party(
            party_id
        )
        yield Metric(
            'tickets_checked_in_count', tickets_checked_in_count, labels=labels
        )


def _collect_user_metrics() -> Iterator[Metric]:
    users_active = user_stats_service.count_active_users()
    users_uninitialized = user_stats_service.count_uninitialized_users()
    users_suspended = user_stats_service.count_suspended_users()
    users_deleted = user_stats_service.count_deleted_users()
    users_total = user_stats_service.count_users()

    yield Metric('users_active_count', users_active)
    yield Metric('users_uninitialized_count', users_uninitialized)
    yield Metric('users_suspended_count', users_suspended)
    yield Metric('users_deleted_count', users_deleted)
    yield Metric('users_total_count', users_total)