INT 21h

Hi, I am Vladimir Smagin, sysadmin. Telegram Email

Python: анализ логов nginx в специальном формате

№ 8580 В разделах: Администрирование Программирование от December 24th, 2017,

Один из проектов, который я веду вырос довольно геморройным и требовательным к производительности. Программа должна прочитать специально разогретый и смазанный лог нгинкса, извлечь всю необходимую мне информацию и отправить полученные данные в zabbix чтобы было видно здоровье фермы. В эту же программу вкорячил и вывод полной статистики по логу, а не только по конкретным кодам + добавил с какого времени начинать и заканчивать обработку. Больше всего боли приносят конвертации даты и времени при чтении лога. 6 секунд без указания времени против 40 секунд с точкой отсчета.

Исходный код

Пример обрабатываемого лога:

"172.31.30.163","23/Dec/2017:15:38:08 +0000","200","GET /grabit/script.php HTTP/1.1";
"172.31.30.163","23/Dec/2017:15:38:08 +0000","200","GET /grabit/script.php HTTP/1.1";
"172.31.30.163","23/Dec/2017:15:38:08 +0000","200","GET /grabit/script-min.js HTTP/1.1";
"172.31.30.163","23/Dec/2017:15:38:08 +0000","302","GET /grabit/pixel.php HTTP/1.1";
"172.31.30.163","23/Dec/2017:15:38:08 +0000","200","GET /grabit/script.php HTTP/1.1";
"172.31.9.241","23/Dec/2017:15:38:08 +0000","200","GET /grabit/script.php HTTP/1.1";
"172.31.9.241","23/Dec/2017:15:38:08 +0000","200","GET /grabit/script-min.js HTTP/1.1";

Пример вывода:

$ python ./nginx-analyzer.py -h
usage: nginx-analyzer.py [-h] --log logfile [--code HTTP_CODE] [--time]
                         [--totime] [--summ]

Get statistics from nginx special format log file

optional arguments:
  -h, --help        show this help message and exit
  --log logfile     Of course, you need to parse something
  --code HTTP_CODE  Show only response code
  --time            Start counting from timestamp DD-MM-YYYY HH:MM:SS
  --totime          Stop counting from timestamp DD-MM-YYYY HH:MM:SS
  --summ            Display fancy summary

$ time python ./nginx-analyzer.py --log nginx/http.access.log --summ --time "23-12-2017 15:37:00"

HTTP codes  | Type   | Count 
------------+---------------+-----------
 All |               | 3,593,692 
 20x | Success       | 3,188,176 
 30x | Redirection   | 395,021 
 40x | Client errors | 86 
 500 | Server errors | 5,855 
 502 | Server errors | 56 
 50x | Server errors | 5,911

real 0m39,535s
user 0m39,398s
sys 0m0,136s

$ time python ./nginx-analyzer.py --log nginx/http.access.log --code 404

83

real 0m5,790s
user 0m5,702s
sys 0m0,088s

Нет комментариев »

Python: красивые таблицы в консольном выводе

№ 8577 В разделах: Администрирование Программирование от December 24th, 2017,

На днях понадобилось красиво вывести статистику по логам nginx и тут пришел на помощь python с его горой всевозможных библиотечек и прочих рюшечек. Я использовал библиотеку terminaltables. Установить ее в отдельное окружение или в систему это на ваше усмотрение, ну а я предпочитаю котлеты отдельно, мухи отдельно.

Просто оставляю вам пример, который вы легко адаптируете под себя.

import csv
from terminaltables import AsciiTable

successCounter = 0
redirectCounter = 0
clientErrorCounter = 0
serverErrorCounter = 0
serverErrorCounter500 = 0
serverErrorCounter502 = 0

pathPrefix = './' #local
# pathPrefix = '/var/log/' #server


with open(pathPrefix+'nginx/http.access.log') as nginxLogFile:
    logStringsIterable = csv.reader(nginxLogFile, delimiter=",", quotechar='"', lineterminator=";")
    for logString in logStringsIterable:
        # custom nginx log file:
        # log_format compression '"$remote_addr","$time_local","$status","$request";';
        # Position  |   Description
        # 0         |   IP address
        # 1         |   Time stamp
        # 2         |   Response code
        # 3         |   Request [type url protocol]
        if '20' in logString[2]: successCounter += 1
        if '30' in logString[2]: redirectCounter += 1
        if '40' in logString[2]: clientErrorCounter += 1
        if '500' in logString[2]: serverErrorCounter500 += 1
        if '502' in logString[2]: serverErrorCounter502 += 1
        if '50' in logString[2]: serverErrorCounter += 1

# summary

tableData = [
    ['HTTP codes', 'Type', 'Count'],
    ['20x', 'Success', "{:,}".format(successCounter)],
    ['30x', 'Redirection', "{:,}".format(redirectCounter)],
    ['40x', 'Client errors', "{:,}".format(clientErrorCounter)],
    ['500', 'Server errors', "{:,}".format(serverErrorCounter500)],
    ['502', 'Server errors', "{:,}".format(serverErrorCounter502)],
    ['50x', 'Server errors', "{:,}".format(serverErrorCounter)]
]

resultTable = AsciiTable(tableData)
resultTable.inner_heading_row_border = True
resultTable.outer_border = False
resultTable.inner_row_border = False

print(resultTable.table)

Нет комментариев »

Взаимодействие с MQTT из Python

№ 8455 В разделах: Программирование Электроника от September 8th, 2017,

Так уж случилось, что я стал крутым пацаном и начал делать интернет вещей 😀 В общем, для начала необходимо установить модуль paho-mqtt. А еще лучше сначала сделать виртуальное окружение и уже потом туда установить всё нужное.

sudo apt install python3-venv
cd /opt && pyvenv mymqtt
source mymqtt/bin/activate
pip install wheel
pip install paho-mqtt

Ну вот вроде и всё. Теперь можно приступать к работе 🙂 Открываем документацию и читаем. На этом запись можно заканчивать, но я всё-таки покажу вам пару примеров. Я люблю разносить все в разные файлы поэтому некоторые вещи будут работать через библиотеки в поддиректориях.

Итак, я создал директорию с проектом, где есть поддиректория libs и именно в нее я положу свою библиотечку для работы с mqtt.

import sys 
sys.path.append("..")

import paho.mqtt.subscribe as subscribe
import paho.mqtt.publish as publish
import config

def pub(topic, msg, retained=False):
    print("Connecting {}".format(config.mqtt_cred["hostname"]))
    publish.single(topic,msg,hostname=config.mqtt_cred["hostname"],
        port=config.mqtt_cred["port"],auth=config.mqtt_cred["auth"],retain=retained)

def sub(callback_function, topic, wait=False):
    subscribe.callback(callback_function, topic, hostname=config.mqtt_cred["hostname"],
        port=config.mqtt_cred["port"],auth=config.mqtt_cred["auth"])

Сразу же заметна вторая строка. Прикол в том, что у меня на уровне выше лежит конфигурационный файл и я просто добавил в PYTHON_PATH его местоположение. В функции sub я сделал передачу callback функции через параметры, а сама функция описана в файле основной программы. Конечно, я мог ее написать прямо тут, но тогда бы я считал это говнокодом 🙂

Теперь можно поугарать в файле основной программы

from libs import libmqtt

def any_message_received(client, userdata, message):
    '''Callback function on_message, catch any message and process it'''
    topic=message.topic
    value = message.payload.decode("utf-8")
    print(topic, value)
libmqtt.sub(any_message_received, "#")

any_message_received и есть та самая callback функция. На нее я возложил парсинг всего, что приходит из шины. Муторно, но зато делает то, что мне нужно 🙂

А теперь вишенка! Конфиг

'''Config module'''

mqtt_cred={
    "hostname": "myserver",
    "port": 5883,
    "auth": {"username":"mymqtt","password":"longlongpen1s"}
    }

Нет комментариев »

Комментарии

  • 21h: нене ) без меня )
  • Серегй: Не совсем грабить)) если грабить можно и без рации, есть...
  • 21h: магазин грабить собрались? ) не, тут я не помощник ;)
  • Серегй: А что бы мне поймать чужую волну, что мне для этого нужно...
  • 21h: слушать никто не запрещает. нет закона, который запрещает...
  • Серегй: Я хотел узнать могу ли я просто прийти с данной рацией baofeng...
  • 21h: У меня есть только эти 2. По другим ничего не знаю. В интернете...

© Vladimir Smagin, 2005-2017. Копирование материалов без разрешения запрещено.
Яндекс.Метрика