[ВОЛК] исправление нереентерабельности логгирования
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2025-12-21 13:03:16 +03:00
parent 53db795675
commit 8772eaaf3d
+30 -74
View File
@@ -1,6 +1,7 @@
import os import os
import json import json
import time import time
import traceback
from datetime import datetime from datetime import datetime
from urllib.request import urlopen from urllib.request import urlopen
from dotenv import load_dotenv from dotenv import load_dotenv
@@ -36,8 +37,8 @@ def log_message(message, category="VOLK_loader"):
if attempt < 4: # Не последняя попытка if attempt < 4: # Не последняя попытка
time.sleep(0.4) # Задержка 400ms между попытками time.sleep(0.4) # Задержка 400ms между попытками
else: else:
# После 5 неудачных попыток выводим в stdout # После 5 неудачных попыток просто возвращаем False
print(f"Не удалось записать в лог после 5 попыток: {log_entry.strip()}") # Не используем print() чтобы избежать реентерабельных вызовов с gunicorn
return False return False
return False return False
@@ -52,9 +53,7 @@ def load_categories():
# Проверка наличия URL # Проверка наличия URL
if not VOLK_CATEGORY_LIST: if not VOLK_CATEGORY_LIST:
error_msg = "Переменная окружения VOLK_CATEGORY_LIST не установлена" error_msg = "Переменная окружения VOLK_CATEGORY_LIST не установлена"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
return return
# Чтение JSON из URL # Чтение JSON из URL
@@ -66,9 +65,7 @@ def load_categories():
api_version = data.get('api_version') api_version = data.get('api_version')
if api_version != VOLK_API_VERSION: if api_version != VOLK_API_VERSION:
error_msg = f"Несовпадение версии API: получена версия '{api_version}', ожидается '{VOLK_API_VERSION}'. Обработка остановлена." error_msg = f"Несовпадение версии API: получена версия '{api_version}', ожидается '{VOLK_API_VERSION}'. Обработка остановлена."
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
return return
log_message(f"Версия API соответствует: {api_version}") log_message(f"Версия API соответствует: {api_version}")
@@ -76,9 +73,7 @@ def load_categories():
# Проверка наличия блока data # Проверка наличия блока data
if 'data' not in data: if 'data' not in data:
error_msg = "В JSON отсутствует блок 'data'" error_msg = "В JSON отсутствует блок 'data'"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
return return
categories_data = data['data'] categories_data = data['data']
@@ -109,8 +104,7 @@ def load_categories():
for item in categories_data: for item in categories_data:
# Проверка обязательного поля ID # Проверка обязательного поля ID
if 'id' not in item or not item['id']: if 'id' not in item or not item['id']:
# log_message(f"Пропущена запись без id или с пустым id: {item}", "WARNING") log_message(f"Пропущена запись без id или с пустым id: {item}", "WARNING")
log_message(f"Пропущена запись без id или с пустым id: {item}")
continue continue
# Подготовка значений # Подготовка значений
@@ -160,6 +154,7 @@ def load_categories():
desc_url = VOLK_CATEGORY_DESC_PREFIX + category_id desc_url = VOLK_CATEGORY_DESC_PREFIX + category_id
log_message(f"Запрос описания для категории {category_id} из {desc_url}") log_message(f"Запрос описания для категории {category_id} из {desc_url}")
log_message("отладочное сообщение для проверки вывода в лог-файл") log_message("отладочное сообщение для проверки вывода в лог-файл")
with urlopen(desc_url) as response: with urlopen(desc_url) as response:
# Явно указываем кодировку UTF-8 при декодировании # Явно указываем кодировку UTF-8 при декодировании
raw_data = response.read() raw_data = response.read()
@@ -169,8 +164,7 @@ def load_categories():
log_message("data decoded") log_message("data decoded")
except UnicodeDecodeError as e: except UnicodeDecodeError as e:
error_msg = f"Ошибка декодирования ответа для категории {category_id}: {e}. Попытка декодирования как latin-1." error_msg = f"Ошибка декодирования ответа для категории {category_id}: {e}. Попытка декодирования как latin-1."
# log_message(error_msg, "WARNING") log_message(error_msg, "WARNING")
log_message(error_msg)
decoded_data = raw_data.decode('latin-1') decoded_data = raw_data.decode('latin-1')
try: try:
@@ -178,9 +172,7 @@ def load_categories():
log_message("json loaded") log_message("json loaded")
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
error_msg = f"Ошибка парсинга JSON для категории {category_id}: {e}. Первые 500 символов ответа: {decoded_data[:500]}" error_msg = f"Ошибка парсинга JSON для категории {category_id}: {e}. Первые 500 символов ответа: {decoded_data[:500]}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
# Пропускаем эту категорию и продолжаем обработку # Пропускаем эту категорию и продолжаем обработку
continue continue
@@ -188,18 +180,14 @@ def load_categories():
api_version = desc_response.get('api_version') api_version = desc_response.get('api_version')
if api_version != VOLK_API_VERSION: if api_version != VOLK_API_VERSION:
error_msg = f"Несовпадение версии API при загрузке описания категории {category_id}: получена версия '{api_version}', ожидается '{VOLK_API_VERSION}'. Пропуск категории." error_msg = f"Несовпадение версии API при загрузке описания категории {category_id}: получена версия '{api_version}', ожидается '{VOLK_API_VERSION}'. Пропуск категории."
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
# Пропускаем эту категорию и продолжаем обработку # Пропускаем эту категорию и продолжаем обработку
continue continue
# Проверка наличия блока data # Проверка наличия блока data
if 'data' not in desc_response: if 'data' not in desc_response:
error_msg = f"В JSON ответе для категории {category_id} отсутствует блок 'data'. Пропуск категории." error_msg = f"В JSON ответе для категории {category_id} отсутствует блок 'data'. Пропуск категории."
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
# Пропускаем эту категорию и продолжаем обработку # Пропускаем эту категорию и продолжаем обработку
continue continue
@@ -208,9 +196,7 @@ def load_categories():
# Проверка типа desc_data - должен быть словарём # Проверка типа desc_data - должен быть словарём
if not isinstance(desc_data, dict): if not isinstance(desc_data, dict):
error_msg = f"Блок 'data' для категории {category_id} не является словарём (тип: {type(desc_data)}). Пропуск категории." error_msg = f"Блок 'data' для категории {category_id} не является словарём (тип: {type(desc_data)}). Пропуск категории."
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
# Пропускаем эту категорию и продолжаем обработку # Пропускаем эту категорию и продолжаем обработку
continue continue
@@ -235,13 +221,9 @@ def load_categories():
except Exception as e: except Exception as e:
error_msg = f"Ошибка при загрузке описания для категории {category_id}: {type(e).__name__}: {e}" error_msg = f"Ошибка при загрузке описания для категории {category_id}: {type(e).__name__}: {e}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
import traceback
traceback_str = traceback.format_exc() traceback_str = traceback.format_exc()
# log_message(f"Трассировка ошибки для категории {category_id}:\n{traceback_str}", "ERROR") log_message(f"Трассировка ошибки для категории {category_id}:\n{traceback_str}", "ERROR")
log_message(f"Трассировка ошибки для категории {category_id}:\n{traceback_str}")
# Пропускаем эту категорию и продолжаем обработку остальных # Пропускаем эту категорию и продолжаем обработку остальных
continue continue
@@ -251,16 +233,12 @@ def load_categories():
except Error as e: except Error as e:
error_msg = f"Ошибка базы данных: {e}" error_msg = f"Ошибка базы данных: {e}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
if 'connection' in locals() and connection.is_connected(): if 'connection' in locals() and connection.is_connected():
connection.rollback() connection.rollback()
except Exception as e: except Exception as e:
error_msg = f"Общая ошибка: {e}" error_msg = f"Общая ошибка: {e}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
finally: finally:
if 'connection' in locals() and connection.is_connected(): if 'connection' in locals() and connection.is_connected():
cursor.close() cursor.close()
@@ -277,17 +255,13 @@ def load_events_by_category(category_id):
# Проверка наличия URL префикса # Проверка наличия URL префикса
if not VOLK_EVENT_LIST_PREFIX: if not VOLK_EVENT_LIST_PREFIX:
error_msg = "Переменная окружения VOLK_EVENT_LIST_PREFIX не установлена" error_msg = "Переменная окружения VOLK_EVENT_LIST_PREFIX не установлена"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
return return
# Проверка наличия category_id # Проверка наличия category_id
if not category_id: if not category_id:
error_msg = "ID категории не указан" error_msg = "ID категории не указан"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
return return
# Формирование URL для запроса # Формирование URL для запроса
@@ -302,9 +276,7 @@ def load_events_by_category(category_id):
api_version = data.get('api_version') api_version = data.get('api_version')
if api_version != VOLK_API_VERSION: if api_version != VOLK_API_VERSION:
error_msg = f"Несовпадение версии API: получена версия '{api_version}', ожидается '{VOLK_API_VERSION}'. Обработка остановлена." error_msg = f"Несовпадение версии API: получена версия '{api_version}', ожидается '{VOLK_API_VERSION}'. Обработка остановлена."
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
return return
log_message(f"Версия API соответствует: {api_version}") log_message(f"Версия API соответствует: {api_version}")
@@ -312,9 +284,7 @@ def load_events_by_category(category_id):
# Проверка наличия блока data # Проверка наличия блока data
if 'data' not in data: if 'data' not in data:
error_msg = "В JSON отсутствует блок 'data'" error_msg = "В JSON отсутствует блок 'data'"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
return return
events_data = data['data'] events_data = data['data']
@@ -352,14 +322,12 @@ def load_events_by_category(category_id):
for item in events_data: for item in events_data:
# Проверка обязательного поля id # Проверка обязательного поля id
if 'id' not in item or item['id'] is None: if 'id' not in item or item['id'] is None:
# log_message(f"Пропущено событие без id: {item}", "WARNING") log_message(f"Пропущено событие без id: {item}", "WARNING")
log_message(f"Пропущено событие без id: {item}")
continue continue
# Проверка обязательного поля title # Проверка обязательного поля title
if 'title' not in item or not item['title']: if 'title' not in item or not item['title']:
# log_message(f"Пропущено событие без title (id: {item.get('id', 'N/A')}): {item}", "WARNING") log_message(f"Пропущено событие без title (id: {item.get('id', 'N/A')}): {item}", "WARNING")
log_message(f"Пропущено событие без title (id: {item.get('id', 'N/A')}): {item}")
continue continue
# Подготовка значений с маппингом полей # Подготовка значений с маппингом полей
@@ -367,8 +335,7 @@ def load_events_by_category(category_id):
try: try:
id_event = int(item['id']) # Уникальный идентификатор события из JSON id_event = int(item['id']) # Уникальный идентификатор события из JSON
except (ValueError, TypeError): except (ValueError, TypeError):
# log_message(f"Пропущено событие с некорректным id (не число): {item.get('id', 'N/A')}", "WARNING") log_message(f"Пропущено событие с некорректным id (не число): {item.get('id', 'N/A')}", "WARNING")
log_message(f"Пропущено событие с некорректным id (не число): {item.get('id', 'N/A')}")
continue continue
name = item.get('title', '') name = item.get('title', '')
about = item.get('announce', '') or '' about = item.get('announce', '') or ''
@@ -429,16 +396,12 @@ def load_events_by_category(category_id):
except Error as e: except Error as e:
error_msg = f"Ошибка базы данных: {e}" error_msg = f"Ошибка базы данных: {e}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
if 'connection' in locals() and connection.is_connected(): if 'connection' in locals() and connection.is_connected():
connection.rollback() connection.rollback()
except Exception as e: except Exception as e:
error_msg = f"Общая ошибка: {e}" error_msg = f"Общая ошибка: {e}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
finally: finally:
if 'connection' in locals() and connection.is_connected(): if 'connection' in locals() and connection.is_connected():
cursor.close() cursor.close()
@@ -464,8 +427,7 @@ def load_all_events():
categories = cursor.fetchall() categories = cursor.fetchall()
if not categories: if not categories:
# log_message("В базе данных нет категорий для загрузки событий", "WARNING") log_message("В базе данных нет категорий для загрузки событий", "WARNING")
log_message("В базе данных нет категорий для загрузки событий")
cursor.close() cursor.close()
connection.close() connection.close()
return return
@@ -487,9 +449,7 @@ def load_all_events():
processed_count += 1 processed_count += 1
except Exception as e: except Exception as e:
error_msg = f"Ошибка при загрузке событий для категории {category_id}: {e}" error_msg = f"Ошибка при загрузке событий для категории {category_id}: {e}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
# Продолжаем обработку других категорий # Продолжаем обработку других категорий
continue continue
@@ -497,14 +457,10 @@ def load_all_events():
except Error as e: except Error as e:
error_msg = f"Ошибка базы данных при загрузке всех событий: {e}" error_msg = f"Ошибка базы данных при загрузке всех событий: {e}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
except Exception as e: except Exception as e:
error_msg = f"Общая ошибка при загрузке всех событий: {e}" error_msg = f"Общая ошибка при загрузке всех событий: {e}"
# log_message(error_msg, "ERROR") log_message(error_msg, "ERROR")
log_message(error_msg)
print(error_msg)
if __name__ == "__main__": if __name__ == "__main__":
load_categories() load_categories()