Skip to content

Commit 343d436

Browse files
Allow storing test metrics in local filesystem of LocalStack container (#13188)
1 parent 69ed784 commit 343d436

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

localstack-core/localstack/aws/handlers/metric_handler.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1+
import csv
12
import logging
3+
import os
4+
from datetime import datetime
5+
from pathlib import Path
26

37
from localstack import config
48
from localstack.aws.api import RequestContext
59
from localstack.aws.chain import HandlerChain
10+
from localstack.constants import ENV_INTERNAL_TEST_STORE_METRICS_PATH
611
from localstack.http import Response
12+
from localstack.utils.strings import short_uid
713

814
LOG = logging.getLogger(__name__)
915

@@ -137,6 +143,32 @@ class MetricHandler:
137143

138144
def __init__(self) -> None:
139145
self.metrics_handler_items = {}
146+
self.local_filename = None
147+
148+
if self.should_store_metric_locally():
149+
self.local_filename = self.create_local_file()
150+
151+
@staticmethod
152+
def should_store_metric_locally() -> bool:
153+
return config.is_collect_metrics_mode() and config.store_test_metrics_in_local_filesystem()
154+
155+
@staticmethod
156+
def create_local_file():
157+
folder = Path(
158+
os.environ.get(ENV_INTERNAL_TEST_STORE_METRICS_PATH, "/tmp/localstack-metrics")
159+
)
160+
if not folder.exists():
161+
folder.mkdir(parents=True, exist_ok=True)
162+
LOG.debug("Metric reports will be stored in %s", folder)
163+
filename = (
164+
folder
165+
/ f"metric-report-raw-data-{datetime.utcnow().strftime('%Y-%m-%d__%H_%M_%S')}-{short_uid()}.csv"
166+
)
167+
with open(filename, "w") as fd:
168+
LOG.debug("Creating new metric data file %s", filename)
169+
writer = csv.writer(fd)
170+
writer.writerow(Metric.RAW_DATA_HEADER)
171+
return filename
140172

141173
def create_metric_handler_item(
142174
self, chain: HandlerChain, context: RequestContext, response: Response
@@ -194,7 +226,15 @@ def update_metric_collection(
194226
)
195227
# refrain from adding duplicates
196228
if metric not in MetricHandler.metric_data:
197-
MetricHandler.metric_data.append(metric)
229+
self.append_metric(metric)
198230

199231
# cleanup
200232
del self.metrics_handler_items[context]
233+
234+
def append_metric(self, metric: Metric):
235+
if self.should_store_metric_locally():
236+
with open(self.local_filename, "a") as fd:
237+
writer = csv.writer(fd)
238+
writer.writerow(metric)
239+
else:
240+
MetricHandler.metric_data.append(metric)

localstack-core/localstack/config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
DEFAULT_VOLUME_DIR,
2020
ENV_INTERNAL_TEST_COLLECT_METRIC,
2121
ENV_INTERNAL_TEST_RUN,
22+
ENV_INTERNAL_TEST_STORE_METRICS_IN_LOCALSTACK,
2223
FALSE_STRINGS,
2324
LOCALHOST,
2425
LOCALHOST_IP,
@@ -1451,6 +1452,11 @@ def is_collect_metrics_mode() -> bool:
14511452
return is_env_true(ENV_INTERNAL_TEST_COLLECT_METRIC)
14521453

14531454

1455+
def store_test_metrics_in_local_filesystem() -> bool:
1456+
"""Returns True if test metrics should be stored in the local filesystem (instead of the system that runs pytest)."""
1457+
return is_env_true(ENV_INTERNAL_TEST_STORE_METRICS_IN_LOCALSTACK)
1458+
1459+
14541460
def collect_config_items() -> list[tuple[str, Any]]:
14551461
"""Returns a list of key-value tuples of LocalStack configuration values."""
14561462
none = object() # sentinel object

localstack-core/localstack/constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@
8080
# environment variable name to tag collect metrics during a test run
8181
ENV_INTERNAL_TEST_COLLECT_METRIC = "LOCALSTACK_INTERNAL_TEST_COLLECT_METRIC"
8282

83+
# environment variable name to indicate that metrics should be stored within the container
84+
ENV_INTERNAL_TEST_STORE_METRICS_IN_LOCALSTACK = "LOCALSTACK_INTERNAL_TEST_METRICS_IN_LOCALSTACK"
85+
ENV_INTERNAL_TEST_STORE_METRICS_PATH = "LOCALSTACK_INTERNAL_TEST_STORE_METRICS_PATH"
86+
8387
# environment variable that flags whether pro was activated. do not use it for security purposes!
8488
ENV_PRO_ACTIVATED = "PRO_ACTIVATED"
8589

0 commit comments

Comments
 (0)