localstack-core 4.5.1.dev21__py3-none-any.whl → 4.5.1.dev22__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. localstack/services/apigateway/analytics.py +2 -2
  2. localstack/services/apigateway/next_gen/execute_api/handlers/analytics.py +3 -3
  3. localstack/services/cloudformation/{usage.py → analytics.py} +2 -2
  4. localstack/services/cloudformation/resource_provider.py +3 -3
  5. localstack/services/events/analytics.py +4 -2
  6. localstack/services/lambda_/analytics.py +4 -4
  7. localstack/services/sns/analytics.py +4 -2
  8. localstack/services/stepfunctions/{usage.py → analytics.py} +2 -2
  9. localstack/services/stepfunctions/asl/static_analyser/usage_metrics_static_analyser.py +2 -2
  10. localstack/utils/analytics/metrics/__init__.py +6 -0
  11. localstack/utils/analytics/metrics/api.py +42 -0
  12. localstack/utils/analytics/metrics/counter.py +209 -0
  13. localstack/utils/analytics/metrics/publisher.py +36 -0
  14. localstack/utils/analytics/metrics/registry.py +97 -0
  15. localstack/version.py +2 -2
  16. {localstack_core-4.5.1.dev21.dist-info → localstack_core-4.5.1.dev22.dist-info}/METADATA +1 -1
  17. {localstack_core-4.5.1.dev21.dist-info → localstack_core-4.5.1.dev22.dist-info}/RECORD +25 -21
  18. {localstack_core-4.5.1.dev21.dist-info → localstack_core-4.5.1.dev22.dist-info}/entry_points.txt +1 -1
  19. localstack_core-4.5.1.dev22.dist-info/plux.json +1 -0
  20. localstack/utils/analytics/metrics.py +0 -373
  21. localstack_core-4.5.1.dev21.dist-info/plux.json +0 -1
  22. {localstack_core-4.5.1.dev21.data → localstack_core-4.5.1.dev22.data}/scripts/localstack +0 -0
  23. {localstack_core-4.5.1.dev21.data → localstack_core-4.5.1.dev22.data}/scripts/localstack-supervisor +0 -0
  24. {localstack_core-4.5.1.dev21.data → localstack_core-4.5.1.dev22.data}/scripts/localstack.bat +0 -0
  25. {localstack_core-4.5.1.dev21.dist-info → localstack_core-4.5.1.dev22.dist-info}/WHEEL +0 -0
  26. {localstack_core-4.5.1.dev21.dist-info → localstack_core-4.5.1.dev22.dist-info}/licenses/LICENSE.txt +0 -0
  27. {localstack_core-4.5.1.dev21.dist-info → localstack_core-4.5.1.dev22.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
- from localstack.utils.analytics.metrics import Counter
1
+ from localstack.utils.analytics.metrics import LabeledCounter
2
2
 
3
- invocation_counter = Counter(
3
+ invocation_counter = LabeledCounter(
4
4
  namespace="apigateway", name="rest_api_execute", labels=["invocation_type"]
5
5
  )
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
 
3
3
  from localstack.http import Response
4
- from localstack.utils.analytics.metrics import LabeledCounterMetric
4
+ from localstack.utils.analytics.metrics import LabeledCounter
5
5
 
6
6
  from ..api import RestApiGatewayHandler, RestApiGatewayHandlerChain
7
7
  from ..context import RestApiInvocationContext
@@ -10,9 +10,9 @@ LOG = logging.getLogger(__name__)
10
10
 
11
11
 
12
12
  class IntegrationUsageCounter(RestApiGatewayHandler):
13
- counter: LabeledCounterMetric
13
+ counter: LabeledCounter
14
14
 
15
- def __init__(self, counter: LabeledCounterMetric):
15
+ def __init__(self, counter: LabeledCounter):
16
16
  self.counter = counter
17
17
 
18
18
  def __call__(
@@ -1,7 +1,7 @@
1
- from localstack.utils.analytics.metrics import Counter
1
+ from localstack.utils.analytics.metrics import LabeledCounter
2
2
 
3
3
  COUNTER_NAMESPACE = "cloudformation"
4
4
 
5
- resources = Counter(
5
+ resources = LabeledCounter(
6
6
  namespace=COUNTER_NAMESPACE, name="resources", labels=["resource_type", "missing"]
7
7
  )
@@ -19,7 +19,7 @@ from plux import Plugin, PluginManager
19
19
 
20
20
  from localstack import config
21
21
  from localstack.aws.connect import InternalClientFactory, ServiceLevelClientFactory
22
- from localstack.services.cloudformation import usage
22
+ from localstack.services.cloudformation import analytics
23
23
  from localstack.services.cloudformation.deployment_utils import (
24
24
  check_not_found_exception,
25
25
  convert_data_types,
@@ -581,7 +581,7 @@ class ResourceProviderExecutor:
581
581
  # 2. try to load community resource provider
582
582
  try:
583
583
  plugin = plugin_manager.load(resource_type)
584
- usage.resources.labels(resource_type=resource_type, missing=False).increment()
584
+ analytics.resources.labels(resource_type=resource_type, missing=False).increment()
585
585
  return plugin.factory()
586
586
  except ValueError:
587
587
  # could not find a plugin for that name
@@ -600,7 +600,7 @@ class ResourceProviderExecutor:
600
600
  f'No resource provider found for "{resource_type}"',
601
601
  )
602
602
 
603
- usage.resources.labels(resource_type=resource_type, missing=True).increment()
603
+ analytics.resources.labels(resource_type=resource_type, missing=True).increment()
604
604
 
605
605
  if config.CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES:
606
606
  # TODO: figure out a better way to handle non-implemented here?
@@ -1,6 +1,6 @@
1
1
  from enum import StrEnum
2
2
 
3
- from localstack.utils.analytics.metrics import Counter
3
+ from localstack.utils.analytics.metrics import LabeledCounter
4
4
 
5
5
 
6
6
  class InvocationStatus(StrEnum):
@@ -11,4 +11,6 @@ class InvocationStatus(StrEnum):
11
11
  # number of EventBridge rule invocations per target (e.g., aws:lambda)
12
12
  # - status label can be `success` or `error`, see InvocationStatus
13
13
  # - service label is the target service name
14
- rule_invocation = Counter(namespace="events", name="rule_invocations", labels=["status", "service"])
14
+ rule_invocation = LabeledCounter(
15
+ namespace="events", name="rule_invocations", labels=["status", "service"]
16
+ )
@@ -1,12 +1,12 @@
1
1
  from enum import StrEnum
2
2
 
3
- from localstack.utils.analytics.metrics import Counter
3
+ from localstack.utils.analytics.metrics import LabeledCounter
4
4
 
5
5
  NAMESPACE = "lambda"
6
6
 
7
- hotreload_counter = Counter(namespace=NAMESPACE, name="hotreload", labels=["operation"])
7
+ hotreload_counter = LabeledCounter(namespace=NAMESPACE, name="hotreload", labels=["operation"])
8
8
 
9
- function_counter = Counter(
9
+ function_counter = LabeledCounter(
10
10
  namespace=NAMESPACE,
11
11
  name="function",
12
12
  labels=[
@@ -38,7 +38,7 @@ class FunctionStatus(StrEnum):
38
38
  invocation_error = "invocation_error"
39
39
 
40
40
 
41
- esm_counter = Counter(namespace=NAMESPACE, name="esm", labels=["source", "status"])
41
+ esm_counter = LabeledCounter(namespace=NAMESPACE, name="esm", labels=["source", "status"])
42
42
 
43
43
 
44
44
  class EsmExecutionStatus(StrEnum):
@@ -2,8 +2,10 @@
2
2
  Usage analytics for SNS internal endpoints
3
3
  """
4
4
 
5
- from localstack.utils.analytics.metrics import Counter
5
+ from localstack.utils.analytics.metrics import LabeledCounter
6
6
 
7
7
  # number of times SNS internal endpoint per resource types
8
8
  # (e.g. PlatformMessage invoked 10x times, SMSMessage invoked 3x times, SubscriptionToken...)
9
- internal_api_calls = Counter(namespace="sns", name="internal_api_call", labels=["resource_type"])
9
+ internal_api_calls = LabeledCounter(
10
+ namespace="sns", name="internal_api_call", labels=["resource_type"]
11
+ )
@@ -2,10 +2,10 @@
2
2
  Usage reporting for StepFunctions service
3
3
  """
4
4
 
5
- from localstack.utils.analytics.metrics import Counter
5
+ from localstack.utils.analytics.metrics import LabeledCounter
6
6
 
7
7
  # Initialize a counter to record the usage of language features for each state machine.
8
- language_features_counter = Counter(
8
+ language_features_counter = LabeledCounter(
9
9
  namespace="stepfunctions",
10
10
  name="language_features_used",
11
11
  labels=["query_language", "uses_variables"],
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
  from typing import Final
5
5
 
6
- import localstack.services.stepfunctions.usage as UsageMetrics
6
+ from localstack.services.stepfunctions import analytics
7
7
  from localstack.services.stepfunctions.asl.antlr.runtime.ASLParser import ASLParser
8
8
  from localstack.services.stepfunctions.asl.component.common.query_language import (
9
9
  QueryLanguageMode,
@@ -40,7 +40,7 @@ class UsageMetricsStaticAnalyser(StaticAnalyser):
40
40
  uses_variables = analyser.uses_variables
41
41
 
42
42
  # Count.
43
- UsageMetrics.language_features_counter.labels(
43
+ analytics.language_features_counter.labels(
44
44
  query_language=language_used, uses_variables=uses_variables
45
45
  ).increment()
46
46
  except Exception as e:
@@ -0,0 +1,6 @@
1
+ """LocalStack metrics instrumentation framework"""
2
+
3
+ from .counter import Counter, LabeledCounter
4
+ from .registry import MetricRegistry, MetricRegistryKey
5
+
6
+ __all__ = ["Counter", "LabeledCounter", "MetricRegistry", "MetricRegistryKey"]
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import Any, Protocol
5
+
6
+
7
+ class Payload(Protocol):
8
+ def as_dict(self) -> dict[str, Any]: ...
9
+
10
+
11
+ class Metric(ABC):
12
+ """
13
+ Base class for all metrics (e.g., Counter, Gauge).
14
+ Each subclass must implement the `collect()` method.
15
+ """
16
+
17
+ _namespace: str
18
+ _name: str
19
+
20
+ def __init__(self, namespace: str, name: str):
21
+ if not namespace or namespace.strip() == "":
22
+ raise ValueError("Namespace must be non-empty string.")
23
+ self._namespace = namespace
24
+
25
+ if not name or name.strip() == "":
26
+ raise ValueError("Metric name must be non-empty string.")
27
+ self._name = name
28
+
29
+ @property
30
+ def namespace(self) -> str:
31
+ return self._namespace
32
+
33
+ @property
34
+ def name(self) -> str:
35
+ return self._name
36
+
37
+ @abstractmethod
38
+ def collect(self) -> list[Payload]:
39
+ """
40
+ Collects and returns metric data. Subclasses must implement this to return collected metric data.
41
+ """
42
+ pass
@@ -0,0 +1,209 @@
1
+ import threading
2
+ from collections import defaultdict
3
+ from dataclasses import dataclass
4
+ from typing import Any, Optional, Union
5
+
6
+ from localstack import config
7
+
8
+ from .api import Metric
9
+ from .registry import MetricRegistry
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class CounterPayload:
14
+ """A data object storing the value of a Counter metric."""
15
+
16
+ namespace: str
17
+ name: str
18
+ value: int
19
+ type: str
20
+
21
+ def as_dict(self) -> dict[str, Any]:
22
+ return {
23
+ "namespace": self.namespace,
24
+ "name": self.name,
25
+ "value": self.value,
26
+ "type": self.type,
27
+ }
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class LabeledCounterPayload:
32
+ """A data object storing the value of a LabeledCounter metric."""
33
+
34
+ namespace: str
35
+ name: str
36
+ value: int
37
+ type: str
38
+ labels: dict[str, Union[str, float]]
39
+
40
+ def as_dict(self) -> dict[str, Any]:
41
+ payload_dict = {
42
+ "namespace": self.namespace,
43
+ "name": self.name,
44
+ "value": self.value,
45
+ "type": self.type,
46
+ }
47
+
48
+ for i, (label_name, label_value) in enumerate(self.labels.items(), 1):
49
+ payload_dict[f"label_{i}"] = label_name
50
+ payload_dict[f"label_{i}_value"] = label_value
51
+
52
+ return payload_dict
53
+
54
+
55
+ class ThreadSafeCounter:
56
+ """
57
+ A thread-safe counter for any kind of tracking.
58
+ This class should not be instantiated directly, use Counter or LabeledCounter instead.
59
+ """
60
+
61
+ _mutex: threading.Lock
62
+ _count: int
63
+
64
+ def __init__(self):
65
+ super(ThreadSafeCounter, self).__init__()
66
+ self._mutex = threading.Lock()
67
+ self._count = 0
68
+
69
+ @property
70
+ def count(self) -> int:
71
+ return self._count
72
+
73
+ def increment(self, value: int = 1) -> None:
74
+ """Increments the counter unless events are disabled."""
75
+ if config.DISABLE_EVENTS:
76
+ return
77
+
78
+ if value <= 0:
79
+ raise ValueError("Increment value must be positive.")
80
+
81
+ with self._mutex:
82
+ self._count += value
83
+
84
+ def reset(self) -> None:
85
+ """Resets the counter to zero unless events are disabled."""
86
+ if config.DISABLE_EVENTS:
87
+ return
88
+
89
+ with self._mutex:
90
+ self._count = 0
91
+
92
+
93
+ class Counter(Metric, ThreadSafeCounter):
94
+ """
95
+ A thread-safe, unlabeled counter for tracking the total number of occurrences of a specific event.
96
+ This class is intended for metrics that do not require differentiation across dimensions.
97
+ For use cases where metrics need to be grouped or segmented by labels, use `LabeledCounter` instead.
98
+ """
99
+
100
+ _type: str
101
+
102
+ def __init__(self, namespace: str, name: str):
103
+ Metric.__init__(self, namespace=namespace, name=name)
104
+ ThreadSafeCounter.__init__(self)
105
+
106
+ self._type = "counter"
107
+
108
+ MetricRegistry().register(self)
109
+
110
+ def collect(self) -> list[CounterPayload]:
111
+ """Collects the metric unless events are disabled."""
112
+ if config.DISABLE_EVENTS:
113
+ return list()
114
+
115
+ if self._count == 0:
116
+ # Return an empty list if the count is 0, as there are no metrics to send to the analytics backend.
117
+ return list()
118
+
119
+ return [
120
+ CounterPayload(
121
+ namespace=self._namespace, name=self.name, value=self._count, type=self._type
122
+ )
123
+ ]
124
+
125
+
126
+ class LabeledCounter(Metric):
127
+ """
128
+ A thread-safe counter for tracking occurrences of an event across multiple combinations of label values.
129
+ It enables fine-grained metric collection and analysis, with each unique label set stored and counted independently.
130
+ Use this class when you need dimensional insights into event occurrences.
131
+ For simpler, unlabeled use cases, see the `Counter` class.
132
+ """
133
+
134
+ _type: str
135
+ _labels: list[str]
136
+ _label_values: tuple[Optional[Union[str, float]], ...]
137
+ _counters_by_label_values: defaultdict[
138
+ tuple[Optional[Union[str, float]], ...], ThreadSafeCounter
139
+ ]
140
+
141
+ def __init__(self, namespace: str, name: str, labels: list[str]):
142
+ super(LabeledCounter, self).__init__(namespace=namespace, name=name)
143
+
144
+ if not labels:
145
+ raise ValueError("At least one label is required; the labels list cannot be empty.")
146
+
147
+ if any(not label for label in labels):
148
+ raise ValueError("Labels must be non-empty strings.")
149
+
150
+ if len(labels) > 6:
151
+ raise ValueError("Too many labels: counters allow a maximum of 6.")
152
+
153
+ self._type = "counter"
154
+ self._labels = labels
155
+ self._counters_by_label_values = defaultdict(ThreadSafeCounter)
156
+ MetricRegistry().register(self)
157
+
158
+ def labels(self, **kwargs: Union[str, float, None]) -> ThreadSafeCounter:
159
+ """
160
+ Create a scoped counter instance with specific label values.
161
+
162
+ This method assigns values to the predefined labels of a labeled counter and returns
163
+ a ThreadSafeCounter object that allows tracking metrics for that specific
164
+ combination of label values.
165
+
166
+ :raises ValueError:
167
+ - If the set of keys provided labels does not match the expected set of labels.
168
+ """
169
+ if set(self._labels) != set(kwargs.keys()):
170
+ raise ValueError(f"Expected labels {self._labels}, got {list(kwargs.keys())}")
171
+
172
+ _label_values = tuple(kwargs[label] for label in self._labels)
173
+
174
+ return self._counters_by_label_values[_label_values]
175
+
176
+ def collect(self) -> list[LabeledCounterPayload]:
177
+ if config.DISABLE_EVENTS:
178
+ return list()
179
+
180
+ payload = []
181
+ num_labels = len(self._labels)
182
+
183
+ for label_values, counter in self._counters_by_label_values.items():
184
+ if counter.count == 0:
185
+ continue # Skip items with a count of 0, as they should not be sent to the analytics backend.
186
+
187
+ if len(label_values) != num_labels:
188
+ raise ValueError(
189
+ f"Label count mismatch: expected {num_labels} labels {self._labels}, "
190
+ f"but got {len(label_values)} values {label_values}."
191
+ )
192
+
193
+ # Create labels dictionary
194
+ labels_dict = {
195
+ label_name: label_value
196
+ for label_name, label_value in zip(self._labels, label_values)
197
+ }
198
+
199
+ payload.append(
200
+ LabeledCounterPayload(
201
+ namespace=self._namespace,
202
+ name=self.name,
203
+ value=counter.count,
204
+ type=self._type,
205
+ labels=labels_dict,
206
+ )
207
+ )
208
+
209
+ return payload
@@ -0,0 +1,36 @@
1
+ from datetime import datetime
2
+
3
+ from localstack import config
4
+ from localstack.runtime import hooks
5
+ from localstack.utils.analytics import get_session_id
6
+ from localstack.utils.analytics.events import Event, EventMetadata
7
+ from localstack.utils.analytics.publisher import AnalyticsClientPublisher
8
+
9
+ from .registry import MetricRegistry
10
+
11
+
12
+ @hooks.on_infra_shutdown()
13
+ def publish_metrics() -> None:
14
+ """
15
+ Collects all the registered metrics and immediately sends them to the analytics service.
16
+ Skips execution if event tracking is disabled (`config.DISABLE_EVENTS`).
17
+
18
+ This function is automatically triggered on infrastructure shutdown.
19
+ """
20
+ if config.DISABLE_EVENTS:
21
+ return
22
+
23
+ collected_metrics = MetricRegistry().collect()
24
+ if not collected_metrics.payload: # Skip publishing if no metrics remain after filtering
25
+ return
26
+
27
+ metadata = EventMetadata(
28
+ session_id=get_session_id(),
29
+ client_time=str(datetime.now()),
30
+ )
31
+
32
+ if collected_metrics:
33
+ publisher = AnalyticsClientPublisher()
34
+ publisher.publish(
35
+ [Event(name="ls_metrics", metadata=metadata, payload=collected_metrics.as_dict())]
36
+ )
@@ -0,0 +1,97 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import threading
5
+ from dataclasses import dataclass
6
+ from typing import Any
7
+
8
+ from .api import Metric, Payload
9
+
10
+ LOG = logging.getLogger(__name__)
11
+
12
+
13
+ @dataclass
14
+ class MetricPayload:
15
+ """
16
+ A data object storing the value of all metrics collected during the execution of the application.
17
+ """
18
+
19
+ _payload: list[Payload]
20
+
21
+ @property
22
+ def payload(self) -> list[Payload]:
23
+ return self._payload
24
+
25
+ def __init__(self, payload: list[Payload]):
26
+ self._payload = payload
27
+
28
+ def as_dict(self) -> dict[str, list[dict[str, Any]]]:
29
+ return {"metrics": [payload.as_dict() for payload in self._payload]}
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class MetricRegistryKey:
34
+ """A unique identifier for a metric, composed of namespace and name."""
35
+
36
+ namespace: str
37
+ name: str
38
+
39
+
40
+ class MetricRegistry:
41
+ """
42
+ A Singleton class responsible for managing all registered metrics.
43
+ Provides methods for retrieving and collecting metrics.
44
+ """
45
+
46
+ _instance: "MetricRegistry" = None
47
+ _mutex: threading.Lock = threading.Lock()
48
+
49
+ def __new__(cls):
50
+ # avoid locking if the instance already exist
51
+ if cls._instance is None:
52
+ with cls._mutex:
53
+ # Prevents race conditions when multiple threads enter the first check simultaneously
54
+ if cls._instance is None:
55
+ cls._instance = super().__new__(cls)
56
+ return cls._instance
57
+
58
+ def __init__(self):
59
+ if not hasattr(self, "_registry"):
60
+ self._registry = dict()
61
+
62
+ @property
63
+ def registry(self) -> dict[MetricRegistryKey, Metric]:
64
+ return self._registry
65
+
66
+ def register(self, metric: Metric) -> None:
67
+ """
68
+ Registers a metric instance.
69
+
70
+ Raises a TypeError if the object is not a Metric,
71
+ or a ValueError if a metric with the same namespace and name is already registered
72
+ """
73
+ if not isinstance(metric, Metric):
74
+ raise TypeError("Only subclasses of `Metric` can be registered.")
75
+
76
+ if not metric.namespace:
77
+ raise ValueError("Metric 'namespace' must be defined and non-empty.")
78
+
79
+ registry_unique_key = MetricRegistryKey(namespace=metric.namespace, name=metric.name)
80
+ if registry_unique_key in self._registry:
81
+ raise ValueError(
82
+ f"A metric named '{metric.name}' already exists in the '{metric.namespace}' namespace"
83
+ )
84
+
85
+ self._registry[registry_unique_key] = metric
86
+
87
+ def collect(self) -> MetricPayload:
88
+ """
89
+ Collects all registered metrics.
90
+ """
91
+ payload = [
92
+ metric
93
+ for metric_instance in self._registry.values()
94
+ for metric in metric_instance.collect()
95
+ ]
96
+
97
+ return MetricPayload(payload=payload)
localstack/version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '4.5.1.dev21'
21
- __version_tuple__ = version_tuple = (4, 5, 1, 'dev21')
20
+ __version__ = version = '4.5.1.dev22'
21
+ __version_tuple__ = version_tuple = (4, 5, 1, 'dev22')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: localstack-core
3
- Version: 4.5.1.dev21
3
+ Version: 4.5.1.dev22
4
4
  Summary: The core library and runtime of LocalStack
5
5
  Author-email: LocalStack Contributors <info@localstack.cloud>
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ localstack/deprecations.py,sha256=mNXTebZ8kSbQjFKz0LbT-g1Kdr0CE8bhEgZfHV3IX0s,15
4
4
  localstack/openapi.yaml,sha256=B803NmpwsxG8PHpHrdZYBrUYjnrRh7B_JX0XuNynuFs,30237
5
5
  localstack/plugins.py,sha256=BIJC9dlo0WbP7lLKkCiGtd_2q5oeqiHZohvoRTcejXM,2457
6
6
  localstack/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- localstack/version.py,sha256=c0NgWavpnqr6YKBtMu2OVHya_pe-N-RNeQ8Vo33YKlY,526
7
+ localstack/version.py,sha256=lXi2oP3WjfbD5AUOXQVp4xos_Gr66jB4qRu9bgAiIoc,526
8
8
  localstack/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  localstack/aws/accounts.py,sha256=102zpGowOxo0S6UGMpfjw14QW7WCLVAGsnFK5xFMLoo,3043
10
10
  localstack/aws/app.py,sha256=n9bJCfJRuMz_gLGAH430c3bIQXgUXeWO5NPfcdL2MV8,5145
@@ -182,7 +182,7 @@ localstack/services/stores.py,sha256=20YcOS3_tR_PRg4jd5X9PmW0m9q-Slk41zguCRLuMXM
182
182
  localstack/services/acm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
183
183
  localstack/services/acm/provider.py,sha256=Wflar6XwvglR3rsYQs2rk0F5yZNktCbxfRN_wYHVSBA,5317
184
184
  localstack/services/apigateway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
185
- localstack/services/apigateway/analytics.py,sha256=0KcsDIw7WCb3OnHZVo-nwHi81iIxbdf43eV0kvocowQ,168
185
+ localstack/services/apigateway/analytics.py,sha256=b6AIdtIfUAuLeXQZfL_DIOfQVLOpczj7ZWUDxaeFRYo,182
186
186
  localstack/services/apigateway/exporter.py,sha256=HV0lSZ1t7Sc2ck3Lc-UvBbQmrun6Lky5C6qrZt1snYc,13973
187
187
  localstack/services/apigateway/helpers.py,sha256=J1QsR4Cp725zXmJXO16H3P52ITgNswjCjrMfzwTXTJ0,45313
188
188
  localstack/services/apigateway/models.py,sha256=RHyjlVwRQHPI02J3XBD3cWCcYvt_jZewKX0zE6W-O88,5479
@@ -211,7 +211,7 @@ localstack/services/apigateway/next_gen/execute_api/template_mapping.py,sha256=i
211
211
  localstack/services/apigateway/next_gen/execute_api/test_invoke.py,sha256=vzaCUu4RdVNdipcl-Iro3IOpoBkm_m-aAI1XxwgbztA,9574
212
212
  localstack/services/apigateway/next_gen/execute_api/variables.py,sha256=ixEXZWYEjf7RFqPCr1sEZq2PiarvQZjVAD69i7BOhRc,7903
213
213
  localstack/services/apigateway/next_gen/execute_api/handlers/__init__.py,sha256=6a7jt0l36AifxHho9WGBBiQZoEtHiiYsSYLBWUSBNJ4,1338
214
- localstack/services/apigateway/next_gen/execute_api/handlers/analytics.py,sha256=5vVSXK3fPRiXt4WwuSoH1s8p2lQr27um7Te-jBZobsc,1733
214
+ localstack/services/apigateway/next_gen/execute_api/handlers/analytics.py,sha256=xhixUsSSCA-6OTXdX37QN66JrhZxiqzUWGZVSN8SQUw,1715
215
215
  localstack/services/apigateway/next_gen/execute_api/handlers/api_key_validation.py,sha256=Kz_1CqIHv4assRWoO_SPCxe1EZqDjH-kxuXqhfi4oXs,4916
216
216
  localstack/services/apigateway/next_gen/execute_api/handlers/gateway_exception.py,sha256=7FQ7rgxBdu6kH49dG8pGB7EDPZX3QRBXi-k7k_NDNn8,3746
217
217
  localstack/services/apigateway/next_gen/execute_api/handlers/integration.py,sha256=kHt1hHHj_y9MpTjs1uIwq9zxDxlVqbLZx0E2tjnz_Fo,1097
@@ -281,6 +281,7 @@ localstack/services/certificatemanager/resource_providers/aws_certificatemanager
281
281
  localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate.schema.json,sha256=3KNWtj-XYpLudjdjrx3_8MrvGLYKjhIToMoNKMwiXNM,1978
282
282
  localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate_plugin.py,sha256=2xZ4ySZUHt9F-YhFgrcIy-78yFoNgxZ39HBOOVPkKTY,655
283
283
  localstack/services/cloudformation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
284
+ localstack/services/cloudformation/analytics.py,sha256=7i5_wuEtWlyMIIdDJ4HVHwtEbnWY2ga33oMmBgMZBy8,218
284
285
  localstack/services/cloudformation/api_utils.py,sha256=VUREEwfGtsiCQ3bwFkI_a6fgbG37ZLX0E0YYoEhXR2w,6255
285
286
  localstack/services/cloudformation/cfn_utils.py,sha256=2pBhJLIgjkagixfLoPy9xcvOR5EQCC5M0djJmKD2Ppk,2468
286
287
  localstack/services/cloudformation/deploy.html,sha256=g_t0nI5Z44bsPYFynbisF3GLl8GZagAP40O7nD2NGdg,6247
@@ -289,10 +290,9 @@ localstack/services/cloudformation/deployment_utils.py,sha256=86NQNVZ7fwFHPrtV_H
289
290
  localstack/services/cloudformation/plugins.py,sha256=8E1i9U65RnjZJoXz214ceV8OXcnpHNU44unK3raXkWs,336
290
291
  localstack/services/cloudformation/provider.py,sha256=uMLNL5fUvX9IMkcnku_oH4BSOoaMBu6_o3-jNqEiVvQ,52245
291
292
  localstack/services/cloudformation/provider_utils.py,sha256=37GrPaTuLEqOT57J1AVETQl6pav0bC7ItiRzyyZgstc,8994
292
- localstack/services/cloudformation/resource_provider.py,sha256=K6hP-Bxy52OSlzbkPIvLnqmGf36WLYFTqlSV2G94PjQ,23547
293
+ localstack/services/cloudformation/resource_provider.py,sha256=IisbxzzVfSwJe0sSUeWhY5nMpm_UpsLnYavrmc6gGUQ,23559
293
294
  localstack/services/cloudformation/service_models.py,sha256=uo2sr2PIazsdE0-PfdoaaG9BEbKpjPP8ChCIJfX0pm8,5186
294
295
  localstack/services/cloudformation/stores.py,sha256=gu3VsMgl0jtLHxoUxnsJItHbBDZgAl_KrA2fdxGJWJk,4971
295
- localstack/services/cloudformation/usage.py,sha256=bkCnwHnyR0H92RZRulZEWlUV-WV0yfBhCn4m5DsApdM,204
296
296
  localstack/services/cloudformation/engine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
297
297
  localstack/services/cloudformation/engine/changes.py,sha256=xeRkoHuf9hdqgWzIwfpjExAyjh622hmjX8ehNh3rfDs,363
298
298
  localstack/services/cloudformation/engine/entities.py,sha256=RlrIjSPZYSDxAopsW5zqkiIy5v4pvPMEZwWAVznSasQ,15661
@@ -438,7 +438,7 @@ localstack/services/es/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
438
438
  localstack/services/es/plugins.py,sha256=fAWYNZQwQhciZE6cfNCn4ww3_SZjIKL0BaLJ1PG4XdI,234
439
439
  localstack/services/es/provider.py,sha256=OZVhFZUGm_2m4xUO3OcOL_zUUAh8pQqcCEsUvPKSkkw,17509
440
440
  localstack/services/events/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
441
- localstack/services/events/analytics.py,sha256=-S4N23u4GZSNeNKl7GnQ4oEJVGJPW-CrWPhCEJrzeYA,446
441
+ localstack/services/events/analytics.py,sha256=ONgUjcAu0fqFK9ghoIpJCfbc5tC-FKCrCkx3pOwB0nA,466
442
442
  localstack/services/events/api_destination.py,sha256=55S5t23Kt3wHWk8RxLHhHoGGcISC24x4gFFxJbXwvcw,11831
443
443
  localstack/services/events/archive.py,sha256=QWqz-VoyaUuzYtIVFlPKZnsgJckMuVNuLZAvnGTPwFY,6163
444
444
  localstack/services/events/connection.py,sha256=TecqnyT9xiewVWN9RRsLA7075W7TOopp8HXPoSbeuJU,13378
@@ -537,7 +537,7 @@ localstack/services/kms/resource_providers/aws_kms_key.py,sha256=bqaRvA0Ab6ltGsW
537
537
  localstack/services/kms/resource_providers/aws_kms_key.schema.json,sha256=tfh8quEHohcWoyOkYLvDcygxfW6lywFgLKT1Uubcuas,5752
538
538
  localstack/services/kms/resource_providers/aws_kms_key_plugin.py,sha256=EYWFqmJ3fCCwUMfTY7j3PspeQK81znlClxHu6PEFSXY,500
539
539
  localstack/services/lambda_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
540
- localstack/services/lambda_/analytics.py,sha256=q2mlY6yKF-pRM62ALHKPrd03WBdSQSndyEPZONj4Rxo,1578
540
+ localstack/services/lambda_/analytics.py,sha256=akoypJaRwEcj5JT_Q11W3H3v7AGMDdxvuk7PZtpt2jk,1606
541
541
  localstack/services/lambda_/api_utils.py,sha256=2LJEkylloVQ-0fik5kBgWSC9PpaqkBao2z519lbfZW4,29763
542
542
  localstack/services/lambda_/custom_endpoints.py,sha256=eNnQ4FyfWxiK2ZZtjcAxrtEqscWGowPFei_RHh-qH3E,2017
543
543
  localstack/services/lambda_/hooks.py,sha256=mSthgopfc3XHVC-DBmMlQ56EhNRPZK6CtUo9ftUekI8,1146
@@ -733,7 +733,7 @@ localstack/services/ses/resource_providers/aws_ses_emailidentity.py,sha256=R_oS_
733
733
  localstack/services/ses/resource_providers/aws_ses_emailidentity.schema.json,sha256=V2e0GQp6xp8kjmyaBe-uTVl3_Za3DDrKXoDyA5ZCcTI,6093
734
734
  localstack/services/ses/resource_providers/aws_ses_emailidentity_plugin.py,sha256=J3Yoh1xxPs5y3Wmm-_c7Ep5HECCLINdNdwlmNIXMpVw,575
735
735
  localstack/services/sns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
736
- localstack/services/sns/analytics.py,sha256=V4397csx8ZZTw_IwYPubASgc4giiAxvucv7clyOhYBk,359
736
+ localstack/services/sns/analytics.py,sha256=ecVRQ1l722ppZiKPny3m3rbNM0SKxO90rdyYWE5SI78,379
737
737
  localstack/services/sns/certificate.py,sha256=g30Pi4CMu9u4hFTGUPua6JG5f-kOFmRIJdDu0RpIj7I,1882
738
738
  localstack/services/sns/constants.py,sha256=iAQLU6qVkA6DumYytm3pHkNLzjh4BubXHIHBK91Ix_M,1216
739
739
  localstack/services/sns/executor.py,sha256=hP8vf0C8xlBLGNJozzI_ZzE0l-O0f_4bYjSQIz1Fzwg,3960
@@ -785,12 +785,12 @@ localstack/services/ssm/resource_providers/aws_ssm_patchbaseline.py,sha256=XWe4Y
785
785
  localstack/services/ssm/resource_providers/aws_ssm_patchbaseline.schema.json,sha256=UuVEh9rzGsaEoYHCU0jy02fjmCjhbXPU0TeDmGKlvyM,3788
786
786
  localstack/services/ssm/resource_providers/aws_ssm_patchbaseline_plugin.py,sha256=inMCRhLMB1du7L8YqsaKq_Eydt7YJTxAFRmrTPs4gPc,575
787
787
  localstack/services/stepfunctions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
788
+ localstack/services/stepfunctions/analytics.py,sha256=xc23IY6CZ1xzB_YLh8pQWWqBWo74Q8gn3nLaxBwItLQ,363
788
789
  localstack/services/stepfunctions/packages.py,sha256=RZblddr9VARCXqtCeFn_Z6FmyLerWP1-REkJ-spi1Ko,1705
789
790
  localstack/services/stepfunctions/plugins.py,sha256=oY-qlTgrZHUalqoeIV4v9mkpC5cpMRUN_PX4YMPFMMI,324
790
791
  localstack/services/stepfunctions/provider.py,sha256=yEV5eVLA-aiu1Zfu6Nxt3fE_dpc5F6zJzCMFnCjVP0w,70120
791
792
  localstack/services/stepfunctions/quotas.py,sha256=FprfsAD-_IziguWQnR-b3VA7QYhFdQzItuMLOwl9_FU,484
792
793
  localstack/services/stepfunctions/stepfunctions_utils.py,sha256=8LUfXJ3N1LC_y2QIe_TgHIVIkoQLhS0R4i6aXiSMink,2340
793
- localstack/services/stepfunctions/usage.py,sha256=rcn58eYuAEb8KRmj4YMcjO4eXryqUo8bV9wvo7xyhjg,349
794
794
  localstack/services/stepfunctions/asl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
795
795
  localstack/services/stepfunctions/asl/antlr/Makefile,sha256=F6c38ZQvtoX9hz4DW4x6gz496fkyrARrVIJChtg9QBE,1306
796
796
  localstack/services/stepfunctions/asl/antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1105,7 +1105,7 @@ localstack/services/stepfunctions/asl/parse/test_state/preprocessor.py,sha256=c9
1105
1105
  localstack/services/stepfunctions/asl/static_analyser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1106
1106
  localstack/services/stepfunctions/asl/static_analyser/express_static_analyser.py,sha256=DFOnApfcCOmXZz_4uAymhDfiOLZiwSoC-cfWNDICga8,1570
1107
1107
  localstack/services/stepfunctions/asl/static_analyser/static_analyser.py,sha256=kF9Rf-EOTETfjYwHDCMW07chrsbNSbCusQm9osVvF_I,419
1108
- localstack/services/stepfunctions/asl/static_analyser/usage_metrics_static_analyser.py,sha256=jc9k2-F2D-bWQRNuLB-suyZRRkP9t9wC_6qAFp2gYpM,3233
1108
+ localstack/services/stepfunctions/asl/static_analyser/usage_metrics_static_analyser.py,sha256=DDPn6LO6r0rLOKlJ3ZvlrO6LhULfSrRLbTgWIE7-pDU,3223
1109
1109
  localstack/services/stepfunctions/asl/static_analyser/variable_references_static_analyser.py,sha256=ffmU5o1U4E8dkyw3O9186mEQcucCjv15zkJ5svskY5g,3310
1110
1110
  localstack/services/stepfunctions/asl/static_analyser/intrinsic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1111
1111
  localstack/services/stepfunctions/asl/static_analyser/intrinsic/intrinsic_static_analyser.py,sha256=vwhKDs0WDhU1-bowBAWxZTb7gmVn4h-3gJs6IHNRr1M,460
@@ -1246,9 +1246,13 @@ localstack/utils/analytics/client.py,sha256=6bUWMpS42dUCRcRhkJuqHhlx_OSJegQJ4WJo
1246
1246
  localstack/utils/analytics/events.py,sha256=XMzrrcJc-p-6DxQfALHWO4lZco_I30dt_5MbCR_sKJc,582
1247
1247
  localstack/utils/analytics/logger.py,sha256=-sA_zjptY7o2kOXP2sDduQPzfNwULYIRnoqwKGgsg2Q,1397
1248
1248
  localstack/utils/analytics/metadata.py,sha256=tup9FurX-SlDGGY0at4YBcfdavz5C4pLet-gaqZltfM,7151
1249
- localstack/utils/analytics/metrics.py,sha256=uZsURjLybX2qQ5g6BTUe7OCZ7MpHPGCsBUKZvjUHl8c,11850
1250
1249
  localstack/utils/analytics/publisher.py,sha256=Y_xbaM-cZjZVtTRSCQWpGLU4KrSiLJ7TC-iaIyBOufw,8629
1251
1250
  localstack/utils/analytics/service_request_aggregator.py,sha256=QhgvA79wDjrXq3FI7EP9ziTHYEOspot7fy6D0yfVKDw,3926
1251
+ localstack/utils/analytics/metrics/__init__.py,sha256=APJa7ulgGseR4dl4EPAhKOEuXxxNiP0f_MwLbNmgc4Y,233
1252
+ localstack/utils/analytics/metrics/api.py,sha256=xXuKWbEMY7QcgliR3mFlxZWHaqW6h4UCI1RkYAllLdU,1061
1253
+ localstack/utils/analytics/metrics/counter.py,sha256=N1MsH8wRzYeb2f1Hi59KWFUnM2mp91JGIG1AuwIpgWc,6608
1254
+ localstack/utils/analytics/metrics/publisher.py,sha256=Y-oOFi3eVjPE4PoSdk6pvtBdhv0yqBafWJARFXc_7Z4,1178
1255
+ localstack/utils/analytics/metrics/registry.py,sha256=ByQXl8THZ746f5iN8nI14yTlJas_6LPwsQP2P3rii_s,2828
1252
1256
  localstack/utils/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1253
1257
  localstack/utils/aws/arns.py,sha256=mPHxOYR6MyZtTyGzqNX7nySqiGSi6xQaUpDqJWV3DWQ,16884
1254
1258
  localstack/utils/aws/aws_responses.py,sha256=FUvUz-cTHNlgsE-1PiZJ780SBFvIHzS8K2tzvRkJWZs,7781
@@ -1279,13 +1283,13 @@ localstack/utils/server/tcp_proxy.py,sha256=rR6d5jR0ozDvIlpHiqW0cfyY9a2fRGdOzyA8
1279
1283
  localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1280
1284
  localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
1281
1285
  localstack/utils/xray/traceid.py,sha256=SQSsMV2rhbTNK6ceIoozZYuGU7Fg687EXcgqxoDl1Fw,1106
1282
- localstack_core-4.5.1.dev21.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1283
- localstack_core-4.5.1.dev21.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1284
- localstack_core-4.5.1.dev21.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1285
- localstack_core-4.5.1.dev21.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1286
- localstack_core-4.5.1.dev21.dist-info/METADATA,sha256=SJqSydMRw3r6JJky4tJxysbd04U8OERkt5FPhhUzAxs,5539
1287
- localstack_core-4.5.1.dev21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1288
- localstack_core-4.5.1.dev21.dist-info/entry_points.txt,sha256=fdk6rMb2jN3PjkJH_YtXRF_-xhDYAz6__Osec6Z7tW0,20561
1289
- localstack_core-4.5.1.dev21.dist-info/plux.json,sha256=iktmcx4zWKiohAYWYXPTbDNCczYvS_4AejJfWhjucLg,20783
1290
- localstack_core-4.5.1.dev21.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1291
- localstack_core-4.5.1.dev21.dist-info/RECORD,,
1286
+ localstack_core-4.5.1.dev22.data/scripts/localstack,sha256=WyL11vp5CkuP79iIR-L8XT7Cj8nvmxX7XRAgxhbmXNE,529
1287
+ localstack_core-4.5.1.dev22.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1288
+ localstack_core-4.5.1.dev22.data/scripts/localstack.bat,sha256=tlzZTXtveHkMX_s_fa7VDfvdNdS8iVpEz2ER3uk9B_c,29
1289
+ localstack_core-4.5.1.dev22.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1290
+ localstack_core-4.5.1.dev22.dist-info/METADATA,sha256=g_vz3QtXpSWa1PvQe0QJ7KcaDYlCfxJZ5Br1bzDiIp8,5539
1291
+ localstack_core-4.5.1.dev22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1292
+ localstack_core-4.5.1.dev22.dist-info/entry_points.txt,sha256=tsZ2TeV3-omCfAUEXmTWXu_D40b_17a9FDAEpbeaoNw,20571
1293
+ localstack_core-4.5.1.dev22.dist-info/plux.json,sha256=O-YgBP9Vr5E6bwnWXnGrf7FJd1NkT8bVDYbilugZlSc,20793
1294
+ localstack_core-4.5.1.dev22.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1295
+ localstack_core-4.5.1.dev22.dist-info/RECORD,,
@@ -159,7 +159,7 @@ _run_init_scripts_on_ready = localstack.runtime.init:_run_init_scripts_on_ready
159
159
 
160
160
  [localstack.hooks.on_infra_shutdown]
161
161
  _run_init_scripts_on_shutdown = localstack.runtime.init:_run_init_scripts_on_shutdown
162
- publish_metrics = localstack.utils.analytics.metrics:publish_metrics
162
+ publish_metrics = localstack.utils.analytics.metrics.publisher:publish_metrics
163
163
  remove_custom_endpoints = localstack.services.lambda_.plugins:remove_custom_endpoints
164
164
  run_on_after_service_shutdown_handlers = localstack.runtime.shutdown:run_on_after_service_shutdown_handlers
165
165
  run_shutdown_handlers = localstack.runtime.shutdown:run_shutdown_handlers
@@ -0,0 +1 @@
1
+ {"localstack.cloudformation.resource_providers": ["AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.hooks.on_infra_start": ["delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "eager_load_services=localstack.services.plugins:eager_load_services", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "_patch_botocore_endpoint_in_memory=localstack.aws.client:_patch_botocore_endpoint_in_memory", "_patch_botocore_json_parser=localstack.aws.client:_patch_botocore_json_parser", "_patch_cbor2=localstack.aws.client:_patch_cbor2"], "localstack.packages": ["ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "terraform/community=localstack.packages.plugins:terraform_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.aws.provider": ["acm:default=localstack.services.providers:acm", "apigateway:default=localstack.services.providers:apigateway", "apigateway:legacy=localstack.services.providers:apigateway_legacy", "apigateway:next_gen=localstack.services.providers:apigateway_next_gen", "config:default=localstack.services.providers:awsconfig", "cloudformation:default=localstack.services.providers:cloudformation", "cloudformation:engine-v2=localstack.services.providers:cloudformation_v2", "cloudwatch:default=localstack.services.providers:cloudwatch", "cloudwatch:v1=localstack.services.providers:cloudwatch_v1", "cloudwatch:v2=localstack.services.providers:cloudwatch_v2", "dynamodb:default=localstack.services.providers:dynamodb", "dynamodb:v2=localstack.services.providers:dynamodb_v2", "dynamodbstreams:default=localstack.services.providers:dynamodbstreams", "dynamodbstreams:v2=localstack.services.providers:dynamodbstreams_v2", "ec2:default=localstack.services.providers:ec2", "es:default=localstack.services.providers:es", "events:default=localstack.services.providers:events", "events:legacy=localstack.services.providers:events_legacy", "events:v1=localstack.services.providers:events_v1", "events:v2=localstack.services.providers:events_v2", "firehose:default=localstack.services.providers:firehose", "iam:default=localstack.services.providers:iam", "kinesis:default=localstack.services.providers:kinesis", "kms:default=localstack.services.providers:kms", "lambda:default=localstack.services.providers:lambda_", "lambda:asf=localstack.services.providers:lambda_asf", "lambda:v2=localstack.services.providers:lambda_v2", "logs:default=localstack.services.providers:logs", "opensearch:default=localstack.services.providers:opensearch", "redshift:default=localstack.services.providers:redshift", "resource-groups:default=localstack.services.providers:resource_groups", "resourcegroupstaggingapi:default=localstack.services.providers:resourcegroupstaggingapi", "route53:default=localstack.services.providers:route53", "route53resolver:default=localstack.services.providers:route53resolver", "s3:default=localstack.services.providers:s3", "s3control:default=localstack.services.providers:s3control", "scheduler:default=localstack.services.providers:scheduler", "secretsmanager:default=localstack.services.providers:secretsmanager", "ses:default=localstack.services.providers:ses", "sns:default=localstack.services.providers:sns", "sqs:default=localstack.services.providers:sqs", "ssm:default=localstack.services.providers:ssm", "stepfunctions:default=localstack.services.providers:stepfunctions", "stepfunctions:v2=localstack.services.providers:stepfunctions_v2", "sts:default=localstack.services.providers:sts", "support:default=localstack.services.providers:support", "swf:default=localstack.services.providers:swf", "transcribe:default=localstack.services.providers:transcribe"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"], "localstack.hooks.on_infra_shutdown": ["publish_metrics=localstack.utils.analytics.metrics.publisher:publish_metrics", "run_on_after_service_shutdown_handlers=localstack.runtime.shutdown:run_on_after_service_shutdown_handlers", "run_shutdown_handlers=localstack.runtime.shutdown:run_shutdown_handlers", "shutdown_services=localstack.runtime.shutdown:shutdown_services", "stop_server=localstack.dns.plugins:stop_server", "_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints"], "localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.hooks.on_infra_ready": ["_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.hooks.configure_localstack_container": ["_mount_machine_file=localstack.utils.analytics.metadata:_mount_machine_file"], "localstack.hooks.prepare_host": ["prepare_host_machine_id=localstack.utils.analytics.metadata:prepare_host_machine_id"]}
@@ -1,373 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import datetime
4
- import logging
5
- import threading
6
- from abc import ABC, abstractmethod
7
- from collections import defaultdict
8
- from dataclasses import dataclass
9
- from typing import Any, Optional, Union, overload
10
-
11
- from localstack import config
12
- from localstack.runtime import hooks
13
- from localstack.utils.analytics import get_session_id
14
- from localstack.utils.analytics.events import Event, EventMetadata
15
- from localstack.utils.analytics.publisher import AnalyticsClientPublisher
16
-
17
- LOG = logging.getLogger(__name__)
18
-
19
-
20
- @dataclass(frozen=True)
21
- class MetricRegistryKey:
22
- namespace: str
23
- name: str
24
-
25
-
26
- @dataclass(frozen=True)
27
- class CounterPayload:
28
- """An immutable snapshot of a counter metric at the time of collection."""
29
-
30
- namespace: str
31
- name: str
32
- value: int
33
- type: str
34
- labels: Optional[dict[str, Union[str, float]]] = None
35
-
36
- def as_dict(self) -> dict[str, Any]:
37
- result = {
38
- "namespace": self.namespace,
39
- "name": self.name,
40
- "value": self.value,
41
- "type": self.type,
42
- }
43
-
44
- if self.labels:
45
- # Convert labels to the expected format (label_1, label_1_value, etc.)
46
- for i, (label_name, label_value) in enumerate(self.labels.items(), 1):
47
- result[f"label_{i}"] = label_name
48
- result[f"label_{i}_value"] = label_value
49
-
50
- return result
51
-
52
-
53
- @dataclass
54
- class MetricPayload:
55
- """
56
- Stores all metric payloads collected during the execution of the LocalStack emulator.
57
- Currently, supports only counter-type metrics, but designed to accommodate other types in the future.
58
- """
59
-
60
- _payload: list[CounterPayload] # support for other metric types may be added in the future.
61
-
62
- @property
63
- def payload(self) -> list[CounterPayload]:
64
- return self._payload
65
-
66
- def __init__(self, payload: list[CounterPayload]):
67
- self._payload = payload
68
-
69
- def as_dict(self) -> dict[str, list[dict[str, Any]]]:
70
- return {"metrics": [payload.as_dict() for payload in self._payload]}
71
-
72
-
73
- class MetricRegistry:
74
- """
75
- A Singleton class responsible for managing all registered metrics.
76
- Provides methods for retrieving and collecting metrics.
77
- """
78
-
79
- _instance: "MetricRegistry" = None
80
- _mutex: threading.Lock = threading.Lock()
81
-
82
- def __new__(cls):
83
- # avoid locking if the instance already exist
84
- if cls._instance is None:
85
- with cls._mutex:
86
- # Prevents race conditions when multiple threads enter the first check simultaneously
87
- if cls._instance is None:
88
- cls._instance = super().__new__(cls)
89
- return cls._instance
90
-
91
- def __init__(self):
92
- if not hasattr(self, "_registry"):
93
- self._registry = dict()
94
-
95
- @property
96
- def registry(self) -> dict[MetricRegistryKey, "Metric"]:
97
- return self._registry
98
-
99
- def register(self, metric: Metric) -> None:
100
- """
101
- Registers a new metric.
102
-
103
- :param metric: The metric instance to register.
104
- :type metric: Metric
105
- :raises TypeError: If the provided metric is not an instance of `Metric`.
106
- :raises ValueError: If a metric with the same name already exists.
107
- """
108
- if not isinstance(metric, Metric):
109
- raise TypeError("Only subclasses of `Metric` can be registered.")
110
-
111
- if not metric.namespace:
112
- raise ValueError("Metric 'namespace' must be defined and non-empty.")
113
-
114
- registry_unique_key = MetricRegistryKey(namespace=metric.namespace, name=metric.name)
115
- if registry_unique_key in self._registry:
116
- raise ValueError(
117
- f"A metric named '{metric.name}' already exists in the '{metric.namespace}' namespace"
118
- )
119
-
120
- self._registry[registry_unique_key] = metric
121
-
122
- def collect(self) -> MetricPayload:
123
- """
124
- Collects all registered metrics.
125
- """
126
- payload = [
127
- metric
128
- for metric_instance in self._registry.values()
129
- for metric in metric_instance.collect()
130
- ]
131
-
132
- return MetricPayload(payload=payload)
133
-
134
-
135
- class Metric(ABC):
136
- """
137
- Base class for all metrics (e.g., Counter, Gauge).
138
-
139
- Each subclass must implement the `collect()` method.
140
- """
141
-
142
- _namespace: str
143
- _name: str
144
-
145
- def __init__(self, namespace: str, name: str):
146
- if not namespace or namespace.strip() == "":
147
- raise ValueError("Namespace must be non-empty string.")
148
- self._namespace = namespace
149
-
150
- if not name or name.strip() == "":
151
- raise ValueError("Metric name must be non-empty string.")
152
- self._name = name
153
-
154
- @property
155
- def namespace(self) -> str:
156
- return self._namespace
157
-
158
- @property
159
- def name(self) -> str:
160
- return self._name
161
-
162
- @abstractmethod
163
- def collect(
164
- self,
165
- ) -> list[CounterPayload]: # support for other metric types may be added in the future.
166
- """
167
- Collects and returns metric data. Subclasses must implement this to return collected metric data.
168
- """
169
- pass
170
-
171
-
172
- class BaseCounter:
173
- """
174
- A thread-safe counter for any kind of tracking.
175
- This class should not be instantiated directly, use the Counter class instead.
176
- """
177
-
178
- _mutex: threading.Lock
179
- _count: int
180
-
181
- def __init__(self):
182
- super(BaseCounter, self).__init__()
183
- self._mutex = threading.Lock()
184
- self._count = 0
185
-
186
- @property
187
- def count(self) -> int:
188
- return self._count
189
-
190
- def increment(self, value: int = 1) -> None:
191
- """Increments the counter unless events are disabled."""
192
- if config.DISABLE_EVENTS:
193
- return
194
-
195
- if value <= 0:
196
- raise ValueError("Increment value must be positive.")
197
-
198
- with self._mutex:
199
- self._count += value
200
-
201
- def reset(self) -> None:
202
- """Resets the counter to zero unless events are disabled."""
203
- if config.DISABLE_EVENTS:
204
- return
205
-
206
- with self._mutex:
207
- self._count = 0
208
-
209
-
210
- class CounterMetric(Metric, BaseCounter):
211
- """
212
- A thread-safe counter for tracking occurrences of an event without labels.
213
- This class should not be instantiated directly, use the Counter class instead.
214
- """
215
-
216
- _type: str
217
-
218
- def __init__(self, namespace: str, name: str):
219
- Metric.__init__(self, namespace=namespace, name=name)
220
- BaseCounter.__init__(self)
221
-
222
- self._type = "counter"
223
- MetricRegistry().register(self)
224
-
225
- def collect(self) -> list[CounterPayload]:
226
- """Collects the metric unless events are disabled."""
227
- if config.DISABLE_EVENTS:
228
- return list()
229
-
230
- if self._count == 0:
231
- # Return an empty list if the count is 0, as there are no metrics to send to the analytics backend.
232
- return list()
233
-
234
- return [
235
- CounterPayload(
236
- namespace=self._namespace, name=self.name, value=self._count, type=self._type
237
- )
238
- ]
239
-
240
-
241
- class LabeledCounterMetric(Metric):
242
- """
243
- A labeled counter that tracks occurrences of an event across different label combinations.
244
- This class should not be instantiated directly, use the Counter class instead.
245
- """
246
-
247
- _type: str
248
- _unit: str
249
- _labels: list[str]
250
- _label_values: tuple[Optional[Union[str, float]], ...]
251
- _counters_by_label_values: defaultdict[tuple[Optional[Union[str, float]], ...], BaseCounter]
252
-
253
- def __init__(self, namespace: str, name: str, labels: list[str]):
254
- super(LabeledCounterMetric, self).__init__(namespace=namespace, name=name)
255
-
256
- if not labels:
257
- raise ValueError("At least one label is required; the labels list cannot be empty.")
258
-
259
- if any(not label for label in labels):
260
- raise ValueError("Labels must be non-empty strings.")
261
-
262
- if len(labels) > 6:
263
- raise ValueError("Too many labels: counters allow a maximum of 6.")
264
-
265
- self._type = "counter"
266
- self._labels = labels
267
- self._counters_by_label_values = defaultdict(BaseCounter)
268
- MetricRegistry().register(self)
269
-
270
- def labels(self, **kwargs: Union[str, float, None]) -> BaseCounter:
271
- """
272
- Create a scoped counter instance with specific label values.
273
-
274
- This method assigns values to the predefined labels of a labeled counter and returns
275
- a BaseCounter object that allows tracking metrics for that specific
276
- combination of label values.
277
-
278
- :raises ValueError:
279
- - If the set of keys provided labels does not match the expected set of labels.
280
- """
281
- if set(self._labels) != set(kwargs.keys()):
282
- raise ValueError(f"Expected labels {self._labels}, got {list(kwargs.keys())}")
283
-
284
- _label_values = tuple(kwargs[label] for label in self._labels)
285
-
286
- return self._counters_by_label_values[_label_values]
287
-
288
- def collect(self) -> list[CounterPayload]:
289
- if config.DISABLE_EVENTS:
290
- return list()
291
-
292
- payload = []
293
- num_labels = len(self._labels)
294
-
295
- for label_values, counter in self._counters_by_label_values.items():
296
- if counter.count == 0:
297
- continue # Skip items with a count of 0, as they should not be sent to the analytics backend.
298
-
299
- if len(label_values) != num_labels:
300
- raise ValueError(
301
- f"Label count mismatch: expected {num_labels} labels {self._labels}, "
302
- f"but got {len(label_values)} values {label_values}."
303
- )
304
-
305
- # Create labels dictionary
306
- labels_dict = {
307
- label_name: label_value
308
- for label_name, label_value in zip(self._labels, label_values)
309
- }
310
-
311
- payload.append(
312
- CounterPayload(
313
- namespace=self._namespace,
314
- name=self.name,
315
- value=counter.count,
316
- type=self._type,
317
- labels=labels_dict,
318
- )
319
- )
320
-
321
- return payload
322
-
323
-
324
- class Counter:
325
- """
326
- A factory class for creating counter instances.
327
-
328
- This class provides a flexible way to create either a simple counter
329
- (`CounterMetric`) or a labeled counter (`LabeledCounterMetric`) based on
330
- whether labels are provided.
331
- """
332
-
333
- @overload
334
- def __new__(cls, namespace: str, name: str) -> CounterMetric:
335
- return CounterMetric(namespace=namespace, name=name)
336
-
337
- @overload
338
- def __new__(cls, namespace: str, name: str, labels: list[str]) -> LabeledCounterMetric:
339
- return LabeledCounterMetric(namespace=namespace, name=name, labels=labels)
340
-
341
- def __new__(
342
- cls, namespace: str, name: str, labels: Optional[list[str]] = None
343
- ) -> Union[CounterMetric, LabeledCounterMetric]:
344
- if labels is not None:
345
- return LabeledCounterMetric(namespace=namespace, name=name, labels=labels)
346
- return CounterMetric(namespace=namespace, name=name)
347
-
348
-
349
- @hooks.on_infra_shutdown()
350
- def publish_metrics() -> None:
351
- """
352
- Collects all the registered metrics and immediately sends them to the analytics service.
353
- Skips execution if event tracking is disabled (`config.DISABLE_EVENTS`).
354
-
355
- This function is automatically triggered on infrastructure shutdown.
356
- """
357
- if config.DISABLE_EVENTS:
358
- return
359
-
360
- collected_metrics = MetricRegistry().collect()
361
- if not collected_metrics.payload: # Skip publishing if no metrics remain after filtering
362
- return
363
-
364
- metadata = EventMetadata(
365
- session_id=get_session_id(),
366
- client_time=str(datetime.datetime.now()),
367
- )
368
-
369
- if collected_metrics:
370
- publisher = AnalyticsClientPublisher()
371
- publisher.publish(
372
- [Event(name="ls_metrics", metadata=metadata, payload=collected_metrics.as_dict())]
373
- )
@@ -1 +0,0 @@
1
- {"localstack.init.runner": ["py=localstack.runtime.init:PythonScriptRunner", "sh=localstack.runtime.init:ShellScriptRunner"], "localstack.hooks.on_infra_ready": ["_run_init_scripts_on_ready=localstack.runtime.init:_run_init_scripts_on_ready"], "localstack.hooks.on_infra_shutdown": ["_run_init_scripts_on_shutdown=localstack.runtime.init:_run_init_scripts_on_shutdown", "remove_custom_endpoints=localstack.services.lambda_.plugins:remove_custom_endpoints", "publish_metrics=localstack.utils.analytics.metrics:publish_metrics", "stop_server=localstack.dns.plugins:stop_server", "run_on_after_service_shutdown_handlers=localstack.runtime.shutdown:run_on_after_service_shutdown_handlers", "run_shutdown_handlers=localstack.runtime.shutdown:run_shutdown_handlers", "shutdown_services=localstack.runtime.shutdown:shutdown_services"], "localstack.hooks.on_infra_start": ["_run_init_scripts_on_start=localstack.runtime.init:_run_init_scripts_on_start", "conditionally_enable_debugger=localstack.dev.debugger.plugins:conditionally_enable_debugger", "delete_cached_certificate=localstack.plugins:delete_cached_certificate", "deprecation_warnings=localstack.plugins:deprecation_warnings", "eager_load_services=localstack.services.plugins:eager_load_services", "register_custom_endpoints=localstack.services.lambda_.plugins:register_custom_endpoints", "validate_configuration=localstack.services.lambda_.plugins:validate_configuration", "_patch_botocore_endpoint_in_memory=localstack.aws.client:_patch_botocore_endpoint_in_memory", "_patch_botocore_json_parser=localstack.aws.client:_patch_botocore_json_parser", "_patch_cbor2=localstack.aws.client:_patch_cbor2", "register_cloudformation_deploy_ui=localstack.services.cloudformation.plugins:register_cloudformation_deploy_ui", "setup_dns_configuration_on_host=localstack.dns.plugins:setup_dns_configuration_on_host", "start_dns_server=localstack.dns.plugins:start_dns_server", "_publish_config_as_analytics_event=localstack.runtime.analytics:_publish_config_as_analytics_event", "_publish_container_info=localstack.runtime.analytics:_publish_container_info", "apply_runtime_patches=localstack.runtime.patches:apply_runtime_patches", "apply_aws_runtime_patches=localstack.aws.patches:apply_aws_runtime_patches", "register_swagger_endpoints=localstack.http.resources.swagger.plugins:register_swagger_endpoints"], "localstack.cloudformation.resource_providers": ["AWS::ApiGateway::Deployment=localstack.services.apigateway.resource_providers.aws_apigateway_deployment_plugin:ApiGatewayDeploymentProviderPlugin", "AWS::CDK::Metadata=localstack.services.cdk.resource_providers.cdk_metadata_plugin:LambdaAliasProviderPlugin", "AWS::SES::EmailIdentity=localstack.services.ses.resource_providers.aws_ses_emailidentity_plugin:SESEmailIdentityProviderPlugin", "AWS::CloudFormation::Macro=localstack.services.cloudformation.resource_providers.aws_cloudformation_macro_plugin:CloudFormationMacroProviderPlugin", "AWS::CloudWatch::CompositeAlarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_compositealarm_plugin:CloudWatchCompositeAlarmProviderPlugin", "AWS::ApiGateway::Account=localstack.services.apigateway.resource_providers.aws_apigateway_account_plugin:ApiGatewayAccountProviderPlugin", "AWS::IAM::Group=localstack.services.iam.resource_providers.aws_iam_group_plugin:IAMGroupProviderPlugin", "AWS::Lambda::Url=localstack.services.lambda_.resource_providers.aws_lambda_url_plugin:LambdaUrlProviderPlugin", "AWS::EC2::KeyPair=localstack.services.ec2.resource_providers.aws_ec2_keypair_plugin:EC2KeyPairProviderPlugin", "AWS::ECR::Repository=localstack.services.ecr.resource_providers.aws_ecr_repository_plugin:ECRRepositoryProviderPlugin", "AWS::EC2::VPCGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_vpcgatewayattachment_plugin:EC2VPCGatewayAttachmentProviderPlugin", "AWS::ApiGateway::GatewayResponse=localstack.services.apigateway.resource_providers.aws_apigateway_gatewayresponse_plugin:ApiGatewayGatewayResponseProviderPlugin", "AWS::IAM::User=localstack.services.iam.resource_providers.aws_iam_user_plugin:IAMUserProviderPlugin", "AWS::Logs::LogStream=localstack.services.logs.resource_providers.aws_logs_logstream_plugin:LogsLogStreamProviderPlugin", "AWS::IAM::AccessKey=localstack.services.iam.resource_providers.aws_iam_accesskey_plugin:IAMAccessKeyProviderPlugin", "AWS::SSM::MaintenanceWindow=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindow_plugin:SSMMaintenanceWindowProviderPlugin", "AWS::Lambda::LayerVersion=localstack.services.lambda_.resource_providers.aws_lambda_layerversion_plugin:LambdaLayerVersionProviderPlugin", "AWS::ApiGateway::RequestValidator=localstack.services.apigateway.resource_providers.aws_apigateway_requestvalidator_plugin:ApiGatewayRequestValidatorProviderPlugin", "AWS::SSM::PatchBaseline=localstack.services.ssm.resource_providers.aws_ssm_patchbaseline_plugin:SSMPatchBaselineProviderPlugin", "AWS::EC2::RouteTable=localstack.services.ec2.resource_providers.aws_ec2_routetable_plugin:EC2RouteTableProviderPlugin", "AWS::KinesisFirehose::DeliveryStream=localstack.services.kinesisfirehose.resource_providers.aws_kinesisfirehose_deliverystream_plugin:KinesisFirehoseDeliveryStreamProviderPlugin", "AWS::ApiGateway::DomainName=localstack.services.apigateway.resource_providers.aws_apigateway_domainname_plugin:ApiGatewayDomainNameProviderPlugin", "AWS::Route53::HealthCheck=localstack.services.route53.resource_providers.aws_route53_healthcheck_plugin:Route53HealthCheckProviderPlugin", "AWS::IAM::ServiceLinkedRole=localstack.services.iam.resource_providers.aws_iam_servicelinkedrole_plugin:IAMServiceLinkedRoleProviderPlugin", "AWS::IAM::ServerCertificate=localstack.services.iam.resource_providers.aws_iam_servercertificate_plugin:IAMServerCertificateProviderPlugin", "AWS::Logs::LogGroup=localstack.services.logs.resource_providers.aws_logs_loggroup_plugin:LogsLogGroupProviderPlugin", "AWS::EC2::VPC=localstack.services.ec2.resource_providers.aws_ec2_vpc_plugin:EC2VPCProviderPlugin", "AWS::SSM::Parameter=localstack.services.ssm.resource_providers.aws_ssm_parameter_plugin:SSMParameterProviderPlugin", "AWS::Lambda::Alias=localstack.services.lambda_.resource_providers.lambda_alias_plugin:LambdaAliasProviderPlugin", "AWS::ApiGateway::Method=localstack.services.apigateway.resource_providers.aws_apigateway_method_plugin:ApiGatewayMethodProviderPlugin", "AWS::Events::Rule=localstack.services.events.resource_providers.aws_events_rule_plugin:EventsRuleProviderPlugin", "AWS::SecretsManager::Secret=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secret_plugin:SecretsManagerSecretProviderPlugin", "AWS::EC2::NatGateway=localstack.services.ec2.resource_providers.aws_ec2_natgateway_plugin:EC2NatGatewayProviderPlugin", "AWS::EC2::VPCEndpoint=localstack.services.ec2.resource_providers.aws_ec2_vpcendpoint_plugin:EC2VPCEndpointProviderPlugin", "AWS::ResourceGroups::Group=localstack.services.resource_groups.resource_providers.aws_resourcegroups_group_plugin:ResourceGroupsGroupProviderPlugin", "AWS::EC2::NetworkAcl=localstack.services.ec2.resource_providers.aws_ec2_networkacl_plugin:EC2NetworkAclProviderPlugin", "AWS::DynamoDB::Table=localstack.services.dynamodb.resource_providers.aws_dynamodb_table_plugin:DynamoDBTableProviderPlugin", "AWS::SNS::Subscription=localstack.services.sns.resource_providers.aws_sns_subscription_plugin:SNSSubscriptionProviderPlugin", "AWS::EC2::TransitGatewayAttachment=localstack.services.ec2.resource_providers.aws_ec2_transitgatewayattachment_plugin:EC2TransitGatewayAttachmentProviderPlugin", "AWS::SecretsManager::SecretTargetAttachment=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_secrettargetattachment_plugin:SecretsManagerSecretTargetAttachmentProviderPlugin", "AWS::EC2::Instance=localstack.services.ec2.resource_providers.aws_ec2_instance_plugin:EC2InstanceProviderPlugin", "AWS::EC2::PrefixList=localstack.services.ec2.resource_providers.aws_ec2_prefixlist_plugin:EC2PrefixListProviderPlugin", "AWS::SNS::TopicPolicy=localstack.services.sns.resource_providers.aws_sns_topicpolicy_plugin:SNSTopicPolicyProviderPlugin", "AWS::Events::EventBusPolicy=localstack.services.events.resource_providers.aws_events_eventbuspolicy_plugin:EventsEventBusPolicyProviderPlugin", "AWS::ApiGateway::Resource=localstack.services.apigateway.resource_providers.aws_apigateway_resource_plugin:ApiGatewayResourceProviderPlugin", "AWS::KMS::Alias=localstack.services.kms.resource_providers.aws_kms_alias_plugin:KMSAliasProviderPlugin", "AWS::Lambda::LayerVersionPermission=localstack.services.lambda_.resource_providers.aws_lambda_layerversionpermission_plugin:LambdaLayerVersionPermissionProviderPlugin", "AWS::SNS::Topic=localstack.services.sns.resource_providers.aws_sns_topic_plugin:SNSTopicProviderPlugin", "AWS::Events::EventBus=localstack.services.events.resource_providers.aws_events_eventbus_plugin:EventsEventBusProviderPlugin", "AWS::EC2::DHCPOptions=localstack.services.ec2.resource_providers.aws_ec2_dhcpoptions_plugin:EC2DHCPOptionsProviderPlugin", "AWS::EC2::SecurityGroup=localstack.services.ec2.resource_providers.aws_ec2_securitygroup_plugin:EC2SecurityGroupProviderPlugin", "AWS::OpenSearchService::Domain=localstack.services.opensearch.resource_providers.aws_opensearchservice_domain_plugin:OpenSearchServiceDomainProviderPlugin", "AWS::ApiGateway::ApiKey=localstack.services.apigateway.resource_providers.aws_apigateway_apikey_plugin:ApiGatewayApiKeyProviderPlugin", "AWS::ApiGateway::Model=localstack.services.apigateway.resource_providers.aws_apigateway_model_plugin:ApiGatewayModelProviderPlugin", "AWS::IAM::Policy=localstack.services.iam.resource_providers.aws_iam_policy_plugin:IAMPolicyProviderPlugin", "AWS::SecretsManager::ResourcePolicy=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_resourcepolicy_plugin:SecretsManagerResourcePolicyProviderPlugin", "AWS::SSM::MaintenanceWindowTarget=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtarget_plugin:SSMMaintenanceWindowTargetProviderPlugin", "AWS::Route53::RecordSet=localstack.services.route53.resource_providers.aws_route53_recordset_plugin:Route53RecordSetProviderPlugin", "AWS::CloudFormation::WaitConditionHandle=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitconditionhandle_plugin:CloudFormationWaitConditionHandleProviderPlugin", "AWS::Lambda::CodeSigningConfig=localstack.services.lambda_.resource_providers.aws_lambda_codesigningconfig_plugin:LambdaCodeSigningConfigProviderPlugin", "AWS::EC2::TransitGateway=localstack.services.ec2.resource_providers.aws_ec2_transitgateway_plugin:EC2TransitGatewayProviderPlugin", "AWS::Lambda::EventSourceMapping=localstack.services.lambda_.resource_providers.aws_lambda_eventsourcemapping_plugin:LambdaEventSourceMappingProviderPlugin", "AWS::Lambda::EventInvokeConfig=localstack.services.lambda_.resource_providers.aws_lambda_eventinvokeconfig_plugin:LambdaEventInvokeConfigProviderPlugin", "AWS::IAM::ManagedPolicy=localstack.services.iam.resource_providers.aws_iam_managedpolicy_plugin:IAMManagedPolicyProviderPlugin", "AWS::Scheduler::ScheduleGroup=localstack.services.scheduler.resource_providers.aws_scheduler_schedulegroup_plugin:SchedulerScheduleGroupProviderPlugin", "AWS::StepFunctions::Activity=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_activity_plugin:StepFunctionsActivityProviderPlugin", "AWS::IAM::Role=localstack.services.iam.resource_providers.aws_iam_role_plugin:IAMRoleProviderPlugin", "AWS::Kinesis::StreamConsumer=localstack.services.kinesis.resource_providers.aws_kinesis_streamconsumer_plugin:KinesisStreamConsumerProviderPlugin", "AWS::CloudFormation::WaitCondition=localstack.services.cloudformation.resource_providers.aws_cloudformation_waitcondition_plugin:CloudFormationWaitConditionProviderPlugin", "AWS::CertificateManager::Certificate=localstack.services.certificatemanager.resource_providers.aws_certificatemanager_certificate_plugin:CertificateManagerCertificateProviderPlugin", "AWS::EC2::Route=localstack.services.ec2.resource_providers.aws_ec2_route_plugin:EC2RouteProviderPlugin", "AWS::Scheduler::Schedule=localstack.services.scheduler.resource_providers.aws_scheduler_schedule_plugin:SchedulerScheduleProviderPlugin", "AWS::SecretsManager::RotationSchedule=localstack.services.secretsmanager.resource_providers.aws_secretsmanager_rotationschedule_plugin:SecretsManagerRotationScheduleProviderPlugin", "AWS::S3::BucketPolicy=localstack.services.s3.resource_providers.aws_s3_bucketpolicy_plugin:S3BucketPolicyProviderPlugin", "AWS::EC2::Subnet=localstack.services.ec2.resource_providers.aws_ec2_subnet_plugin:EC2SubnetProviderPlugin", "AWS::Elasticsearch::Domain=localstack.services.opensearch.resource_providers.aws_elasticsearch_domain_plugin:ElasticsearchDomainProviderPlugin", "AWS::Logs::SubscriptionFilter=localstack.services.logs.resource_providers.aws_logs_subscriptionfilter_plugin:LogsSubscriptionFilterProviderPlugin", "AWS::StepFunctions::StateMachine=localstack.services.stepfunctions.resource_providers.aws_stepfunctions_statemachine_plugin:StepFunctionsStateMachineProviderPlugin", "AWS::EC2::InternetGateway=localstack.services.ec2.resource_providers.aws_ec2_internetgateway_plugin:EC2InternetGatewayProviderPlugin", "AWS::ApiGateway::BasePathMapping=localstack.services.apigateway.resource_providers.aws_apigateway_basepathmapping_plugin:ApiGatewayBasePathMappingProviderPlugin", "AWS::ApiGateway::UsagePlan=localstack.services.apigateway.resource_providers.aws_apigateway_usageplan_plugin:ApiGatewayUsagePlanProviderPlugin", "AWS::SQS::QueuePolicy=localstack.services.sqs.resource_providers.aws_sqs_queuepolicy_plugin:SQSQueuePolicyProviderPlugin", "AWS::CloudFormation::Stack=localstack.services.cloudformation.resource_providers.aws_cloudformation_stack_plugin:CloudFormationStackProviderPlugin", "AWS::ApiGateway::UsagePlanKey=localstack.services.apigateway.resource_providers.aws_apigateway_usageplankey_plugin:ApiGatewayUsagePlanKeyProviderPlugin", "AWS::Lambda::Permission=localstack.services.lambda_.resource_providers.aws_lambda_permission_plugin:LambdaPermissionProviderPlugin", "AWS::Events::ApiDestination=localstack.services.events.resource_providers.aws_events_apidestination_plugin:EventsApiDestinationProviderPlugin", "AWS::SSM::MaintenanceWindowTask=localstack.services.ssm.resource_providers.aws_ssm_maintenancewindowtask_plugin:SSMMaintenanceWindowTaskProviderPlugin", "AWS::S3::Bucket=localstack.services.s3.resource_providers.aws_s3_bucket_plugin:S3BucketProviderPlugin", "AWS::ApiGateway::RestApi=localstack.services.apigateway.resource_providers.aws_apigateway_restapi_plugin:ApiGatewayRestApiProviderPlugin", "AWS::Kinesis::Stream=localstack.services.kinesis.resource_providers.aws_kinesis_stream_plugin:KinesisStreamProviderPlugin", "AWS::Lambda::Version=localstack.services.lambda_.resource_providers.aws_lambda_version_plugin:LambdaVersionProviderPlugin", "AWS::Events::Connection=localstack.services.events.resource_providers.aws_events_connection_plugin:EventsConnectionProviderPlugin", "AWS::Lambda::Function=localstack.services.lambda_.resource_providers.aws_lambda_function_plugin:LambdaFunctionProviderPlugin", "AWS::CloudWatch::Alarm=localstack.services.cloudwatch.resource_providers.aws_cloudwatch_alarm_plugin:CloudWatchAlarmProviderPlugin", "AWS::DynamoDB::GlobalTable=localstack.services.dynamodb.resource_providers.aws_dynamodb_globaltable_plugin:DynamoDBGlobalTableProviderPlugin", "AWS::Redshift::Cluster=localstack.services.redshift.resource_providers.aws_redshift_cluster_plugin:RedshiftClusterProviderPlugin", "AWS::KMS::Key=localstack.services.kms.resource_providers.aws_kms_key_plugin:KMSKeyProviderPlugin", "AWS::EC2::SubnetRouteTableAssociation=localstack.services.ec2.resource_providers.aws_ec2_subnetroutetableassociation_plugin:EC2SubnetRouteTableAssociationProviderPlugin", "AWS::IAM::InstanceProfile=localstack.services.iam.resource_providers.aws_iam_instanceprofile_plugin:IAMInstanceProfileProviderPlugin", "AWS::SQS::Queue=localstack.services.sqs.resource_providers.aws_sqs_queue_plugin:SQSQueueProviderPlugin", "AWS::ApiGateway::Stage=localstack.services.apigateway.resource_providers.aws_apigateway_stage_plugin:ApiGatewayStageProviderPlugin"], "localstack.packages": ["ffmpeg/community=localstack.packages.plugins:ffmpeg_package", "java/community=localstack.packages.plugins:java_package", "terraform/community=localstack.packages.plugins:terraform_package", "opensearch/community=localstack.services.opensearch.plugins:opensearch_package", "vosk/community=localstack.services.transcribe.plugins:vosk_package", "lambda-java-libs/community=localstack.services.lambda_.plugins:lambda_java_libs", "lambda-runtime/community=localstack.services.lambda_.plugins:lambda_runtime_package", "jpype-jsonata/community=localstack.services.stepfunctions.plugins:jpype_jsonata_package", "dynamodb-local/community=localstack.services.dynamodb.plugins:dynamodb_local_package", "kinesis-mock/community=localstack.services.kinesis.plugins:kinesismock_package", "elasticsearch/community=localstack.services.es.plugins:elasticsearch_package"], "localstack.openapi.spec": ["localstack=localstack.plugins:CoreOASPlugin"], "localstack.hooks.configure_localstack_container": ["_mount_machine_file=localstack.utils.analytics.metadata:_mount_machine_file"], "localstack.hooks.prepare_host": ["prepare_host_machine_id=localstack.utils.analytics.metadata:prepare_host_machine_id"], "localstack.runtime.components": ["aws=localstack.aws.components:AwsComponents"], "localstack.aws.provider": ["acm:default=localstack.services.providers:acm", "apigateway:default=localstack.services.providers:apigateway", "apigateway:legacy=localstack.services.providers:apigateway_legacy", "apigateway:next_gen=localstack.services.providers:apigateway_next_gen", "config:default=localstack.services.providers:awsconfig", "cloudformation:default=localstack.services.providers:cloudformation", "cloudformation:engine-v2=localstack.services.providers:cloudformation_v2", "cloudwatch:default=localstack.services.providers:cloudwatch", "cloudwatch:v1=localstack.services.providers:cloudwatch_v1", "cloudwatch:v2=localstack.services.providers:cloudwatch_v2", "dynamodb:default=localstack.services.providers:dynamodb", "dynamodb:v2=localstack.services.providers:dynamodb_v2", "dynamodbstreams:default=localstack.services.providers:dynamodbstreams", "dynamodbstreams:v2=localstack.services.providers:dynamodbstreams_v2", "ec2:default=localstack.services.providers:ec2", "es:default=localstack.services.providers:es", "events:default=localstack.services.providers:events", "events:legacy=localstack.services.providers:events_legacy", "events:v1=localstack.services.providers:events_v1", "events:v2=localstack.services.providers:events_v2", "firehose:default=localstack.services.providers:firehose", "iam:default=localstack.services.providers:iam", "kinesis:default=localstack.services.providers:kinesis", "kms:default=localstack.services.providers:kms", "lambda:default=localstack.services.providers:lambda_", "lambda:asf=localstack.services.providers:lambda_asf", "lambda:v2=localstack.services.providers:lambda_v2", "logs:default=localstack.services.providers:logs", "opensearch:default=localstack.services.providers:opensearch", "redshift:default=localstack.services.providers:redshift", "resource-groups:default=localstack.services.providers:resource_groups", "resourcegroupstaggingapi:default=localstack.services.providers:resourcegroupstaggingapi", "route53:default=localstack.services.providers:route53", "route53resolver:default=localstack.services.providers:route53resolver", "s3:default=localstack.services.providers:s3", "s3control:default=localstack.services.providers:s3control", "scheduler:default=localstack.services.providers:scheduler", "secretsmanager:default=localstack.services.providers:secretsmanager", "ses:default=localstack.services.providers:ses", "sns:default=localstack.services.providers:sns", "sqs:default=localstack.services.providers:sqs", "ssm:default=localstack.services.providers:ssm", "stepfunctions:default=localstack.services.providers:stepfunctions", "stepfunctions:v2=localstack.services.providers:stepfunctions_v2", "sts:default=localstack.services.providers:sts", "support:default=localstack.services.providers:support", "swf:default=localstack.services.providers:swf", "transcribe:default=localstack.services.providers:transcribe"], "localstack.lambda.runtime_executor": ["docker=localstack.services.lambda_.invocation.plugins:DockerRuntimeExecutorPlugin"], "localstack.runtime.server": ["hypercorn=localstack.runtime.server.plugins:HypercornRuntimeServerPlugin", "twisted=localstack.runtime.server.plugins:TwistedRuntimeServerPlugin"]}