Вопрос или проблема
Я собираю метрики по 6 REST-сервисам из архитектуры микросервисов. Для каждого собранного момента я извлекаю два CSV-файла из каждого сервиса. Один CSV содержит три метрики задержки (99-й процентиль, 50-й процентиль, среднее значение). А другой CSV содержит количество ответов в секунду, которые сервис вернул с HTTP-кодами 200 и 400.
Примеры каждого из CSV:
Задержка:
"Время", "99-й процентиль", "50-й процентиль", "Среднее", "Ошибка"
2023-02-23 15:20:30,2.45,0.577,0.602,True
2023-02-23 15:21:00,0.939,0.424,0.457,True
2023-02-23 15:21:30,0.740,0.417,0.456,True
2023-02-23 15:22:00,0.965,0.396,0.443,True
2023-02-23 15:22:30,2.34,0.438,0.547,True
QPS:
"Время","2xx","4xx/5xx","Ошибка"
2023-02-22 21:18:30,216,0,False
2023-02-22 21:19:00,280,0,False
2023-02-22 21:19:30,242,0,False
2023-02-22 21:20:00,311,0,False
В дополнение к метрикам есть столбец с Временем и столбец с отметкой, является ли это булевым значением.
Имена CSV-файлов всегда начинаются с названия сервиса и содержат слово “latency” в случае метрик задержки и “QPS” в случае запрашиваемого за секунду.
Пример:
Cart latency-data-as-seriestocolumns-2023-02-23 15_53_38.csv
Cart QPS-data-2023-02-23 15_53_26.csv
Catalogue latency-data-as-seriestocolumns-2023-02-23 15_53_20.csv
Catalogue QPS-data-2023-02-23 15_53_13.csv
Frontend latency-data-as-seriestocolumns-2023-02-23 15_54_54.csv
Frontend QPS-data-as-seriestocolumns-2023-02-23 15_54_48.csv
Orders latency-data-as-seriestocolumns-2023-02-23 15_53_54.csv
Orders QPS-data-2023-02-23 15_53_47.csv
Payment latency-data-as-seriestocolumns-2023-02-23 15_54_10.csv
Payment QPS-data-2023-02-23 15_54_00.csv
Shipping latency-data-as-seriestocolumns-2023-02-23 15_54_24.csv
Shipping QPS-data-2023-02-23 15_54_17.csv
User latency-data-as-seriestocolumns-2023-02-23 15_54_40.csv
User QPS-data-as-seriestocolumns-2023-02-23 15_54_32.csv
Я хотел сделать набор данных, в котором читаются все CSV из вставки и создается весь набор данных для обучения и валидации.
В конце концов, у меня будет набор данных со следующим форматом:
"Время","99-й процентиль","50-й процентиль","Среднее","2xx","4xx/5xx","Ошибка","Сервис"
2023-02-06 16:13:00,0.0970,0.00402,0.00771,254,0,True,Orders
2023-02-06 16:13:30,0.0700,0.00377,0.00614,267,0,True,Orders
2023-02-06 16:14:00,0.0208,0.00328,0.00388,251,0,True,Orders
2023-02-06 16:14:30,0.0971,0.00349,0.00655,273,0,True,Orders
2023-02-06 16:15:00,0.0232,0.00323,0.00443,276,0,True,Orders
2023-02-06 16:15:30,0.00995,0.00309,0.00380,69,0,True,Orders
2023-02-06 16:16:00,0.00957,0.00283,0.00316,171,0,True,Orders
Можно ли собрать всю эту информацию в одном DataFrame? Учитывая, что собранный момент представлен двумя CSV, и что в одной папке у меня будет несколько периодов сбора времени.
Если я правильно понимаю ваш вопрос, это должно дать вам то, что вы ищете:
from glob import glob
dfs = {'latency': [], 'qts': []}
for file_path in glob('*.csv'):
service, data_type = file_path.split('_')[0:2]
df = pd.read_csv(file_path)
df['Service'] = service
df = df.rename(columns={'IsError': f'IsError_{data_type}'})
dfs[data_type].append(df)
# объединить все датафреймы для задержки и qts
latency, qts = pd.concat(dfs['latency']), pd.concat(dfs['qts'])
# присоединить задержку и qts по Сервису и Времени
dataset = qts.join(latency, on=['Service', 'Timestamp'], how='inner').reset_index()
# это предполагает, что ошибка возникает, если либо задержка, либо qts является ошибкой
dataset['IsError'] = dataset['IsError_latency'] | dataset['IsError_qts']
dataset = dataset.drop(columns=['IsError_latency', 'IsError_qts'])
Ответ или решение
Для создания единого DataFrame, который объединит метрики из нескольких CSV файлов, содержащих данные о латентности и количестве ответов на HTTP коды, следуйте данному пошаговому руководству. Этот процесс поможет вам собрать и структурировать данные из микросервисной архитектуры для дальнейшего анализа и обучения моделей.
Шаг 1: Подготовка окружения
Для начала убедитесь, что у вас установлены необходимые библиотеки. Мы используем pandas
для работы с данными и glob
для поиска файлов.
import pandas as pd
from glob import glob
Шаг 2: Чтение и группировка CSV файлов
Создадим два списка, в которых будут храниться DataFrame для метрик латентности и QPS. Каждый файл будет загружен в соответствующий DataFrame, а также добавлена информация о сервисе.
# Словарь для хранения DataFrame по типу данных
dfs = {'latency': [], 'qps': []}
# Итерация по всем CSV файлам в текущей директории
for file_path in glob('*.csv'):
# Определение названия сервиса и типа данных
service = file_path.split(' ')[0] # Первое слово в имени файла
if 'latency' in file_path:
data_type = 'latency'
elif 'QPS' in file_path:
data_type = 'qps'
else:
continue # Пропустить файлы, которые не соответствуют шаблону
# Чтение CSV файла
df = pd.read_csv(file_path)
df['Service'] = service # Добавление колонки с названием сервиса
df = df.rename(columns={'IsError': f'IsError_{data_type}'}) # Переименование колонки IsError для уникальности
dfs[data_type].append(df) # Добавление DataFrame в список по типу данных
Шаг 3: Объединение DataFrame
После того как вы прочитали все CSV файлы из директории, необходимо объединить их в один общий набор данных. Для этого мы сначала объединим DataFrame по каждому типу метрик, а затем сделаем внутреннее соединение (inner join) по времени и имени сервиса.
# Объединение всех DataFrame по латентности и QPS
latency_df = pd.concat(dfs['latency'])
qps_df = pd.concat(dfs['qps'])
# Приведение форматов времени колонки 'Time' к одному виду для объединения
latency_df['Time'] = pd.to_datetime(latency_df['Time'])
qps_df['Time'] = pd.to_datetime(qps_df['Time'])
# Объединение на основе 'Service' и 'Time'
combined_df = pd.merge(qps_df, latency_df, on=['Time', 'Service'], how='inner')
# Обработка ошибок: создадим единую колонку, которая будет содержать информацию об ошибках
combined_df['IsError'] = combined_df['IsError_qps'] | combined_df['IsError_latency']
Шаг 4: Завершение и вывод данных
На финальном этапе можно удалить колонки с отдельными статусами ошибок, если они не нужны, и вывести итоговый DataFrame или сохранить его в файл.
# Удаление отдельных колонок IsError
combined_df = combined_df.drop(columns=['IsError_qps', 'IsError_latency'])
# Вывод итогового DataFrame
print(combined_df)
# (Опционально) Сохранение результата в новый CSV файл
combined_df.to_csv('combined_metrics.csv', index=False)
Заключение
Следуя этим шагам, вы сможете эффективно собрать и объединить метрики из разных CSV файлов в один DataFrame, что значительно упростит дальнейшие анализы и обучение моделей. Этот подход легко адаптируется под различные условия, включая расширение численности сервисов или изменение структуры данных.