Мониторим CPU и память — простые скрипты для Linux и Windows
🤔 Проблема: Сервер тормозит, но вы не знаете, в чём причина.
✅ Решение: Скрипты для мониторинга нагрузки.
Linux (Bash + Python):
Windows (PowerShell):
👉 Добавьте алерты в Telegram — и вы всегда будете в курсе перегрузок!
🌐 @helcode | #bash #python #powershell
🤔 Проблема: Сервер тормозит, но вы не знаете, в чём причина.
✅ Решение: Скрипты для мониторинга нагрузки.
Linux (Bash + Python):
# Загрузка CPU
top -bn1 | grep "Cpu(s)" | awk '{print "CPU: " 100 - $8 "%"}'
python
# Загрузка памяти
import psutil
print(f"RAM: {psutil.virtual_memory().percent}%")
Windows (PowerShell):
powershell
# CPU
Get-CimInstance Win32_Processor | Select LoadPercentage
# Память
Get-CimInstance Win32_OperatingSystem | Select FreePhysicalMemory, TotalVisibleMemorySize
👉 Добавьте алерты в Telegram — и вы всегда будете в курсе перегрузок!
🌐 @helcode | #bash #python #powershell
👍3
Твой Python-скрипт вырос и хочет отдельной команды в терминале. Как ему это организовать? ☕️
Мы все начинаем с простого скрипта
Всё, что нужно, — это
1.
2.
3.
Следующий уровень: после этого можно установить скрипт как пакет через
А какой у вас любимый инструмент для создания CLI? 🤔
🌐 @helcode | #python
Мы все начинаем с простого скрипта
super_script.py. Но потом к нему добавляются аргументы, конфиги, логирование... И вот ты уже не запускаешь скрипт, а выполняешь сложный ритуал: python /path/to/script.py --verbose --output /home/user/data.json. Пора дать ему собственное имя и сделать полноценным CLI-инструментом!Всё, что нужно, — это
argparse из коробки Python. Смотрим, как превратить хаос в элегантную команду:# file: data_processor.py
import argparse
def process_data(input_file, output_file, verbose=False):
# Здесь твоя магия обработки данных
if verbose:
print(f"Обрабатываем {input_file} и сохраняем в {output_file}")
return True
if __name__ == "__main__":
# Создаем парсер
parser = argparse.ArgumentParser(description='Крутой инструмент для обработки данных.')
# Добавляем аргументы
parser.add_argument('input', help='Путь до входного файла')
parser.add_argument('-o', '--output', required=True, help='Путь до выходного файла')
parser.add_argument('-v', '--verbose', action='store_true', help='Вербальный режим')
# Парсим аргументы
args = parser.parse_args()
# Передаем в функцию
process_data(args.input, args.output, args.verbose)
1.
ArgumentParser — это наш главный конструктор команд.2.
add_argument определяет, какие флаги и аргументы мы принимаем. required=True для обязательных, action='store_true' для булевых флагов.3.
parse_args() превращает sys.argv в удобный объект с точками (args.input).Следующий уровень: после этого можно установить скрипт как пакет через
pip install -e . (прописав в setup.py) и твоя команда data_processor будет доступна из любой директории!А какой у вас любимый инструмент для создания CLI? 🤔
P.S. Если твой скрипт после этого начнет требовать зарплату в виде GPU — мы не виноваты.
🌐 @helcode | #python
👍2🤔1
Как заставить старый скрипт работать в 10 раз быстрее
😴 Ваш скрипт работает так медленно, что пока он выполняется, можно выучить новый язык?
👁🗨 Мы все их видели: скрипты, написанные на коленке, которые со временем стали критически важными. Они работают, но отжирают уйму времени и ресурсов. Часто проблема не в сложности задачи, а в неоптимальных подходах.
👉Взгляните на этот кусок кода. Часто проблема в циклах внутри циклов, где можно применить списковые включения или функции из
Было (медленно):
Стало (быстро):
Списковые включения в Python оптимизированы на уровне C и работают значительно быстрее классических
А вы как ускоряли своих "динозавров"? Поделитесь самым крутым оптимизационным хаком в комментариях!
🌐 @helcode | #python
😴 Ваш скрипт работает так медленно, что пока он выполняется, можно выучить новый язык?
👁🗨 Мы все их видели: скрипты, написанные на коленке, которые со временем стали критически важными. Они работают, но отжирают уйму времени и ресурсов. Часто проблема не в сложности задачи, а в неоптимальных подходах.
👉Взгляните на этот кусок кода. Часто проблема в циклах внутри циклов, где можно применить списковые включения или функции из
itertools.Было (медленно):
results = []
for item in huge_list:
if some_condition(item):
for subitem in item.subitems:
if another_condition(subitem):
results.append(process(subitem))
Стало (быстро):
results = [process(subitem) for item in huge_list if some_condition(item) for subitem in item.subitems if another_condition(subitem)]
# Или еще лучше: использовать генератор для экономии памяти!
results_gen = (process(subitem) for item in huge_list ... )
Списковые включения в Python оптимизированы на уровне C и работают значительно быстрее классических
for`-циклов с .append()`. А использование генераторов (`()`) вместо списков (`[]`) позволяет не загружать все данные в память сразу, что еще ускоряет работу с большими объемами данных.А вы как ускоряли своих "динозавров"? Поделитесь самым крутым оптимизационным хаком в комментариях!
Это как в «Форсаже»: иногда не нужен новый двигатель, а нужно просто правильно настроить карбюратор и сбросить лишний вес.
🌐 @helcode | #python
👍3
Как автоматически генерировать сложные пароли для всей команды
Ваш пароль "qwerty123" прекрасен... если вы хотите подарить хакеру новый автомобиль. Давайте генерировать лучше!
Слабые пароли - главная дыра в безопасности. А придумывать и хранить десятки сложных паролей для разных сервисов не может даже человек с памятью как у Шерлока. Доверьте это машине.
Однострочник на Python в помощь всей команде:
Мы используем модуль
А как вы управляете паролями в своей команде?
🌐 @helcode | #python
Ваш пароль "qwerty123" прекрасен... если вы хотите подарить хакеру новый автомобиль. Давайте генерировать лучше!
Слабые пароли - главная дыра в безопасности. А придумывать и хранить десятки сложных паролей для разных сервисов не может даже человек с памятью как у Шерлока. Доверьте это машине.
Однострочник на Python в помощь всей команде:
import secrets
import string
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
password = ''.join(secrets.choice(alphabet) for i in range(16))
print(password) # Пример: 'xT5&!k8@qL9#vR2$'
Мы используем модуль
secrets, который криптографически безопасен (в отличие от random). string.ascii_letters + string.digits - это наш алфавит (буквы и цифры). Добавляем спецсимволы для сложности. Длина 16 символов - отличный старт.А как вы управляете паролями в своей команде?
🌐 @helcode | #python
👍2
Автоматизируйте свои чат-боты: хватит отвечать на одни и те же вопросы!
Ваша команда снова спрашивает, «каой пароль от тестовой БД?».
🤖Пора научить бота делать вашу работу за вас.
В любой команде есть рутинные вопросы, которые отвлекают от работы. «Где документация?», «Как запустить проект?», «Кто дежурный?». Вместо того чтобы в сотый раз копировать один и тот же ответ, можно написать простого бота для Telegram или Slack.
Вот пример на Python с библиотекой
Мы используем
Какой самый частый и раздражающий вопрос вы получаете в чате?
🌐 @helcode | #python
Ваша команда снова спрашивает, «каой пароль от тестовой БД?».
🤖Пора научить бота делать вашу работу за вас.
В любой команде есть рутинные вопросы, которые отвлекают от работы. «Где документация?», «Как запустить проект?», «Кто дежурный?». Вместо того чтобы в сотый раз копировать один и тот же ответ, можно написать простого бота для Telegram или Slack.
Вот пример на Python с библиотекой
python-telegram-bot для обработки частого вопроса.from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
# Бот отвечает на сообщение с ключевым словом
await update.message.reply_text(
"Коллега, привет! Вот частые ответы:\n"
"• Пароль от БД: 'supersecret'\n"
"• Документация: https://wiki.our-company.com/\n"
"• Как запустить: см. файл README.md в корне проекта"
)
if __name__ == '__main__':
app = Application.builder().token("YOUR_TOKEN").build()г
app.add_handler(MessageHandler(filters.TEXT & filters.Regex(r'(?i)(пароль|документация|как запустить)'), help_command))
app.run_polling()
Мы используем
MessageHandler с фильтром filters.Regex(). Он ловит любое текстовое сообщение, в котором есть слова «пароль», «документация» или «как запустить» (регистр неважен благодаря `(?i)`), и автоматически отвечает заготовленным текстом.Какой самый частый и раздражающий вопрос вы получаете в чате?
Это как поставить на частый вопрос автоответчик «я в отпуске», только Вы не в отпуске, а просто пьете кофе, пока бот работает.
🌐 @helcode | #python
👍2
Хватит хардкодить пароли в скриптах! Где и как хранить секреты
API-токены, пароли от БД, ключи шифрования. Они не должны лежать в открытом виде в коде, который вы заливаете на GitHub. Но как тогда скрипт получит к ним доступ? Решение есть.
Используем переменные окружения и файлы.
Способ 1: переменные окружения (просто и достаточно для многих случаев)
Задаем переменную в сессии или в файле
И используем в Python-скрипте:
Способ 2: Файлы с секретами (более безопасно)
Создаем файл, который не будет попадать в git:
Читаем его в коде с помощью библиотеки
Немного теории:
- Переменные окружения — это изолированное пространство памяти процесса. Их не видно в списке запущенных процессов (в отличие от аргументов командной строки).
-
Где вы храните свои секреты?
Признавайтесь, мы не осудим
🌐 @helcode | #bash #python
password = "12345" в коде — это как оставить ключи от квартиры в двери. API-токены, пароли от БД, ключи шифрования. Они не должны лежать в открытом виде в коде, который вы заливаете на GitHub. Но как тогда скрипт получит к ним доступ? Решение есть.
Используем переменные окружения и файлы.
Способ 1: переменные окружения (просто и достаточно для многих случаев)
Задаем переменную в сессии или в файле
~/.bashrc / ~/.zshrc:export DB_PASSWORD="my_super_secret_password_123"
И используем в Python-скрипте:
import os
db_pass = os.environ.get('DB_PASSWORD')
if not db_pass:
raise ValueError("Не задан пароль от БД!")
Способ 2: Файлы с секретами (более безопасно)
Создаем файл, который не будет попадать в git:
# .env file (добавляем в .gitignore!)
DB_HOST=localhost
DB_USER=admin
DB_PASSWORD=secret
Читаем его в коде с помощью библиотеки
python-dotenv:
pip install python-dotenv
from dotenv import load_dotenv
load_dotenv() # Загружает переменные из файла .env в os.environ
db_pass = os.getenv('DB_PASSWORD')
Немного теории:
- Переменные окружения — это изолированное пространство памяти процесса. Их не видно в списке запущенных процессов (в отличие от аргументов командной строки).
-
.env файлы — это удобный способ локальной разработки. На продакшене (сервере) эти же переменные задаются через конфигурацию systemd, Docker или панели управления хостингом.Где вы храните свои секреты?
Признавайтесь, мы не осудим
Хардкодить пароль в коде — это как написать пин-код от карты на ней же шариковой ручкой. Удобно, но недальновидно.
🌐 @helcode | #bash #python
👍3🤣1
multiprocessing или threading? Вопрос на миллион потоков... и процессов!
Ваш скрипт тормозит и вы хотите распараллелить все на свете.
🤔 Но что выбрать? Потоки? Процессы?
Ответ кроется в трех буквах — GIL (Global Interpreter Lock).
☕️ Это такой злой бариста в кофейне Python, который не дает нескольким потокам одновременно молоть зёрна (выполнять Python-код). Но у каждого процесса своя кофейня (и свой GIL)!
Код-пример (CPU-bound):
Код-пример (I/O-bound):
Выбор зависит от типа задачи. Не используйте потоки для вычислений — вы не получите прироста, а только накладные расходы. Не используйте процессы для простых HTTP-запросов — вы создадите слишком много тяжелых процессов.
А вы чаще сталкиваетесь с I/O или CPU-bound задачами? И какой ваш любимый способ паралеллить?
🌐 @helcode | #python
Ваш скрипт тормозит и вы хотите распараллелить все на свете.
🤔 Но что выбрать? Потоки? Процессы?
Ответ кроется в трех буквах — GIL (Global Interpreter Lock).
☕️ Это такой злой бариста в кофейне Python, который не дает нескольким потокам одновременно молоть зёрна (выполнять Python-код). Но у каждого процесса своя кофейня (и свой GIL)!
Код-пример (CPU-bound):
# Много вычислений -> multiprocessing
import multiprocessing
import math
def calculate_factorial(n):
return math.factorial(n)
if __name__ == '__main__':
numbers = [100000, 200000, 300000] * 5 # Тяжелая работа
with multiprocessing.Pool() as pool:
results = pool.map(calculate_factorial, numbers) # 🚀 Запуск на всех ядрах!
Код-пример (I/O-bound):
# Много ожидания -> threading
import threading
import requests
def check_site(url):
response = requests.get(url)
return response.status_code
urls = ['https://google.com', 'https://yandex.ru', ...] * 10
threads = []
for url in urls:
thread = threading.Thread(target=check_site, args=(url,))
thread.start()
threads.append(thread)
for thread in threads:
thread.join() # 🧵 Ждем все потоки
Выбор зависит от типа задачи. Не используйте потоки для вычислений — вы не получите прироста, а только накладные расходы. Не используйте процессы для простых HTTP-запросов — вы создадите слишком много тяжелых процессов.
А вы чаще сталкиваетесь с I/O или CPU-bound задачами? И какой ваш любимый способ паралеллить?
P.S. GIL — это не баг, это фича, которая не дает твоему коду сломать интерпретатор. Но иногда так хочется его пристрелить... (шучу, не шучу).
🌐 @helcode | #python
Ваши логи выглядят как поток сознания писателя-авангардиста? Пора навести порядок!
📖 Читать обычные текстовые логи, где вперемешку идут отладочные сообщения, ошибки и информационные записи, - это как искать иголку в стоге сена. А если нужно автоматически анализировать логи? На помощь приходят структурированные логи в формате JSON.
Используем встроенный модуль
Настройка структурированного логирования:
Вместо неструктурированной строки мы получаем JSON-объект:
✅ Преимущества:
- Легко парсить автоматизированными системами (ELK Stack, Loki, CloudWatch).
- Можно добавлять любые метаданные к каждому событию (
- Упрощен поиск и фильтрация по конкретным полям.
Как вы справляетесь с анализом логов?
🌐 @helcode | #python
📖 Читать обычные текстовые логи, где вперемешку идут отладочные сообщения, ошибки и информационные записи, - это как искать иголку в стоге сена. А если нужно автоматически анализировать логи? На помощь приходят структурированные логи в формате JSON.
Используем встроенный модуль
logging в Python, но с кастомным форматтером.Настройка структурированного логирования:
import logging
import json
from datetime import datetime
class StructuredMessage:
def __init__(self, message, **kwargs):
self.message = message
self.kwargs = kwargs
def __str__(self):
# Создаем словарь с основным сообщением и дополнительными полями
log_data = {
'timestamp': datetime.utcnow().isoformat() + 'Z',
'level': logging.getLevelName(logging.getLogger().getEffectiveLevel()),
'message': self.message,
**self.kwargs # Добавляем все переданные ключевые аргументы
}
return json.dumps(log_data)
# Настраиваем логирование
logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
# Не нужно форматировать, тк наши сообщения уже строки JSON
handler.setFormatter(logging.Formatter('%(message)s'))
logger.addHandler(handler)
logger.setLevel(logging.INFO)
# Использование
logger.info(StructuredMessage("User logged in", user_id=123, ip="192.168.1.1", success=True))
logger.error(StructuredMessage("DB connection failed", attempt=3, timeout=30))
Вместо неструктурированной строки мы получаем JSON-объект:
{"timestamp": "2023-10-26T10:30:15.123456Z", "level": "INFO", "message": "User logged in", "user_id": 123, "ip": "192.168.1.1", "success": true}✅ Преимущества:
- Легко парсить автоматизированными системами (ELK Stack, Loki, CloudWatch).
- Можно добавлять любые метаданные к каждому событию (
user_id, request_id, execution_time).- Упрощен поиск и фильтрация по конкретным полям.
Как вы справляетесь с анализом логов?
Переход на структурированные логи - это как перейти от расшифровки древних свитков к аккуратной Excel-таблице. Информация та же, а работать в разы удобнее.
🌐 @helcode | #python
👍3
Как заставить скрипты общаться друг с другом: не только HTTP
Ваши скрипты живут в вакууме и не общаются? Пора познакомить их друг с другом! 🤝
Часто одна автоматизированная задача должна запускать другую или передавать ей данные. Делать это через запись в файл и постоянный опрос - неэлегантно. Есть более эффективные способы межпроцессного взаимодействия (IPC).
👀 Рассмотрим несколько способов, кроме очевидного HTTP.
Способ 1: очереди сообщений (Message Queues) на примере Redis
Способ 2: Named Pipes (именованные каналы) в Linux/macOS
* Очереди сообщений идеальны для построения распределенных систем. Гарантируют доставку, позволяют балансировать нагрузку между несколькими "воркерами".
* Именованные каналы - очень простой способ одноразовой передачи данных между процессами на одной машине. Работает на уровне файловой системы.
Как ваши скрипты общаются между собой?
🌐 @helcode | #python #bash
Ваши скрипты живут в вакууме и не общаются? Пора познакомить их друг с другом! 🤝
Часто одна автоматизированная задача должна запускать другую или передавать ей данные. Делать это через запись в файл и постоянный опрос - неэлегантно. Есть более эффективные способы межпроцессного взаимодействия (IPC).
👀 Рассмотрим несколько способов, кроме очевидного HTTP.
Способ 1: очереди сообщений (Message Queues) на примере Redis
# Скрипт-отправитель (producer.py)
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
task = {'user_id': 456, 'action': 'generate_report'}
r.lpush('task_queue', json.dumps(task)) # Кладем задачу в очередь
# Скрипт-получатель (consumer.py)
import redis
import json
import time
r = redis.Redis(host='localhost', port=6379, db=0)
while True:
# Блокирующее ожидание задачи из очереди (ждем 30 сек)
_, task_json = r.brpop('task_queue', timeout=30)
if task_json:
task = json.loads(task_json)
print(f"Обрабатываю задачу: {task}")
# ... обработка ...
time.sleep(1)
Способ 2: Named Pipes (именованные каналы) в Linux/macOS
# Создаем канал
mkfifo my_pipe
# Скрипт-читатель (зависнет, пока не появятся данные)
cat my_pipe
# Скрипт-писатель
echo "Hello from another script!" > my_pipe
* Очереди сообщений идеальны для построения распределенных систем. Гарантируют доставку, позволяют балансировать нагрузку между несколькими "воркерами".
* Именованные каналы - очень простой способ одноразовой передачи данных между процессами на одной машине. Работает на уровне файловой системы.
Как ваши скрипты общаются между собой?
Научить скрипты общаться - это как организовать работу отдела: можно кидать записки через стол (файлы), а можно настроить слаженный процесс с задачами и очередями. Второе - эффективнее.
🌐 @helcode | #python #bash
👍4