|
| 1 | +import csv |
1 | 2 | import logging |
| 3 | +import os |
| 4 | +from datetime import datetime |
| 5 | +from pathlib import Path |
2 | 6 |
|
3 | 7 | from localstack import config |
4 | 8 | from localstack.aws.api import RequestContext |
5 | 9 | from localstack.aws.chain import HandlerChain |
| 10 | +from localstack.constants import ENV_INTERNAL_TEST_STORE_METRICS_PATH |
6 | 11 | from localstack.http import Response |
| 12 | +from localstack.utils.strings import short_uid |
7 | 13 |
|
8 | 14 | LOG = logging.getLogger(__name__) |
9 | 15 |
|
@@ -137,6 +143,32 @@ class MetricHandler: |
137 | 143 |
|
138 | 144 | def __init__(self) -> None: |
139 | 145 | 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 |
140 | 172 |
|
141 | 173 | def create_metric_handler_item( |
142 | 174 | self, chain: HandlerChain, context: RequestContext, response: Response |
@@ -194,7 +226,15 @@ def update_metric_collection( |
194 | 226 | ) |
195 | 227 | # refrain from adding duplicates |
196 | 228 | if metric not in MetricHandler.metric_data: |
197 | | - MetricHandler.metric_data.append(metric) |
| 229 | + self.append_metric(metric) |
198 | 230 |
|
199 | 231 | # cleanup |
200 | 232 | 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) |
0 commit comments