Awesome Open Source
Awesome Open Source

docker-elk-tutorial

docker-elk-tutorial📝

簡介

docker-elk ❓ 這是什麼❓ 他可以吃嗎😕

重點在 ELK ,他是由三個東西所組成的。

Elasticsearch ( E )

img

Logstash ( L )

img

Kibana ( K )

img

基本上,整個工作流程是這樣

img

步驟一

Logstash 蒐集從 docker or 其他地方的 log 資訊,這個步驟主要是因為我們可以透過 logstash.conf 過濾

以及解析我們需要的資訊。

步驟二

Logstash 將處理完後的 log 資訊轉發到 Elasticsearch 進行 index。

步驟三

最後使用者可以透過 Kibana 分析以及視覺化所要的資料。

以上就是整個工作的流程,那他有什麼用呢 😕

像是分散式系統好了,之前介紹的 docker swawm,每個容器的 log都進去一個一個看一定會累死,

所以這時候就可以統一把 log 送到 docker-elk 中,方便統一管理以及分析。

使用者的 log 非常重要,如果可以從 log 中分析出使用者愛好以及習慣,就可以推薦他類似的東西或

進行改善,當然,有一點很重要,就是這些 log 必須 處理 過,你可能會和我說可以用 AI( AI 正夯 😑 )

但這不是這次的重點☺️

由於這篇文章我會採用 Docker 建立 docker-elk,所以建議對 Docker 要有一定的認識,如果你不了解

Docker ,可參考我之前的 Docker 教學文章

透過這篇文章,你將會學會

docker ELK 環境建立

我們直接使用 docker-elk 這邊的 docker-compose.yml 即可,但因為我擔心版本會

更新( 導致怪問題 ),所以我放一份到我自己的目錄下,建議閱讀一下 docker-elk

中的 README.md,先到 docker-elk 目錄底下

cd docker-elk

直接執行以下指令

docker-compose up

第一次會比較慢,因為要 pull image 而且還要初始化 😴

這時候可以起來運動一下拉拉筋 ☺️

也可以用 docker ps 確認 docker-elk 都有正常運行

img

docker-compose.yml 如果沒有特別修改,默認的 port 可參考下方

5000: Logstash TCP input
9200: Elasticsearch HTTP
9300: Elasticsearch TCP transport
5601: Kibana

以上是預設的,這邊我多加上一個 UDP 的 port

12201: Logstash UDP input

那要如何加,首先,在 docker-elk/docker-compose.yml 中加上 12201:12201/udp

  logstash:
    build:
      context: logstash/
    volumes:
      - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
      - ./logstash/pipeline:/usr/share/logstash/pipeline:ro
    ports:
      - "5000:5000"
      - "12201:12201/udp"
    environment:
      LS_JAVA_OPTS: "-Xmx256m -Xms256m"
    networks:
      - elk
    depends_on:
      - elasticsearch

接著在 docker-elk/logstash/pipeline/logstash.conf 底下加上 udp

input {
    tcp {
        port => 5000
    }
    udp {
        port => 12201
    }
}

## Add your filters / logstash plugins configuration here

output {
    elasticsearch {
        hosts => "elasticsearch:9200"
    }
}

logstash.conf 可以設定的真的非常多,像是 filters ,大家可以自行去摸索,這邊先不介紹😏

確認啟動成功後,我們可以先來看看 Elasticsearch,瀏覽 http://localhost:9200/

img

接著再來看看 Kibana( 有時候你會發現無法瀏覽,這是因為還在初始化 )

等待初始化完畢後,可以瀏覽 http://localhost:5601/,你應該會看到

img

我們需要先設定 index pattern,MAC 或 Linux 用戶直接使用以下指令

curl -XPOST -D- "http://localhost:5601/api/saved_objects/index-pattern" \
    -H "Content-Type: application/json" \
    -H "kbn-version: 6.1.0" \
    -d "{'attributes':{'title':'logstash-*','timeFieldName':'@timestamp'}}"

如果你是 Windows 用戶,請用其他方法,雖然 Windows 也有 curl,但我裝上去執行指令,

他都會報錯說 josn格式錯誤,所以我直接改用 Postman

img

如果一切順利,你應該會看到 response

img

接著重新整理 http://localhost:5601/,你應該會看到 index pattern 建立成功

img

接著我們可以嘗試送送看 log , 如果你是 MAC 或 Linux 用戶,你可以使用以下指令

nc localhost 5000 < README.md

上面這段指令其實只是將 README.md 往 logstash ( http://localhost:5000/ ) 送資料,

可以透過 Kibana 觀看結果,會發現有一堆 README.md 的文字

img

如果你是 Windows 用戶,請跳過這段 😆

直接用 python 來測試吧😏

透過 python 送 log 到 ELK

剛剛簡單的介紹 ELK,現在讓我們透過 python 送 log 到 ELK 吧 😆

建議大家可以先了解一下 python 中的 logging

也可以參考這個簡單的範例 logging_tutorial.py

要使用 python 發送 log 到 ELK,請先執行下列指令

python-logstash

pip install python-logstash

接著執行以下程式碼 python-logging/demo_logging.py

import logging
import logstash
import sys

host = 'localhost'

test_logger = logging.getLogger('python-logstash-logger')
test_logger.setLevel(logging.INFO)

# UDP
# test_logger.addHandler(logstash.LogstashHandler(host, 12201, version=1))

# TCP
test_logger.addHandler(logstash.TCPLogstashHandler(host, 5000, version=1))

test_logger.error('python-logstash: test logstash error message.')
test_logger.info('python-logstash: test logstash info message.')
test_logger.warning('python-logstash: test logstash warning message.')

# add extra field to logstash message
extra = {
    'test_string': 'python version: ' + repr(sys.version_info),
    'test_boolean': True,
    'test_dict': {'a': 1, 'b': 'c'},
    'test_float': 1.23,
    'test_integer': 123,
    'test_list': [1, 2, '3'],
}
test_logger.info('python-logstash: test extra fields', extra=extra)
print('done,please see kibana')

接著可以到 Kibana 觀看

img

log 訊息的確是我們剛剛送出去的

img

如果你要測試 UDP 的部份,就把 TCP 註解,UDP 打開( 取消註解 ),

這樣以後我們就可以將我們需要記錄的 log 資料通通都送到 ELK 中管理 👍

logging for Django + ELK

剛剛介紹了如何透過 python 送 log 到 ELK 中,現在要教大家如何在 Django 中設定 logging 😏

如果不了解什麼是 Django,可參考我之前寫的 Django 基本教學 - 從無到有 Django-Beginners-Guide 📝

一樣請記得安裝 python-logstash 😊

pip install python-logstash

我們就依照 這篇 的範例繼續介紹,

先將 django-tutorial/django-tutorial/settings.py 加入下方程式碼

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'logstash': {
            'level': 'WARNING',
            'class': 'logstash.TCPLogstashHandler',
            'host': 'localhost',
            'port': 5000,  # Default value: 5000
            'version': 1,
            'message_type': 'django_logstash',  # 'type' field in logstash message. Default value: 'logstash'.
            'fqdn': False,  # Fully qualified domain name. Default value: false.
            'tags': ['django.request'],  # list of tags. Default: None.
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': True,
        },
        'django.request': {
            'handlers': ['logstash'],
            'level': 'WARNING',
            'propagate': True,
        },
    }
}

詳細的 django logging 可參考官網 https://docs.djangoproject.com/en/2.0/topics/logging/

這邊要稍微提一下 django.request

django.request
Log messages related to the handling of requests.
5XX responses are raised as ERROR messages;
4XX responses are raised as WARNING messages.

接著到 django-tutorial/musics/views.py中修改程式碼

from django.shortcuts import render

from musics.models import Music
from django.http import Http404

# Create your views here.
def hello_view(request):
    musics = Music.objects.all()
    # raise Exception('error !!!!')
    # raise Http404("sorry 404")
    return render(request, 'hello_django.html', {
        'data': "Hello Django ",
        'musics': musics,
})

以上註解的兩個地方,可以自行玩玩看,然後到 Kibana 中觀看,

如果不太理解,可參考影片的說明 Youtube Tutorial PART 4 - logging for Django + ELK

raise Exception('error !!!!') 這行等於是 5XX responses,也就是 ERROR messages,

raise Http404("sorry 404") 這行等於是 ˋXX responses,也就是 WARNING messages。

docker logging + ELK

既然都講到這裡了,一定要來說一下如何將 docker 的 log 送到 ELK 中,

先來個 tcp 的簡單範例

docker run --log-driver=syslog --log-opt syslog-address=tcp://0.0.0.0:5000 --log-opt syslog-facility=daemon alpine echo hello world tcp

img

到 Kibana 觀看

img

再來個 udp 的簡單範例

docker run --log-driver=gelf --log-opt gelf-address=udp://0.0.0.0:12201 alpine echo hello world udp

img

這邊我覺得奇怪的是,如果用 gelf 送出去的 log 都會變成亂碼,

如果有人知道原因再請解答😅

img

docker logging 詳細可參考 https://docs.docker.com/engine/admin/logging/overview/

那如果我希望寫在 docker-compose 中呢?

請看 docker-logging/docker-compose.yml

version: '3.3'
services:

    db:
      # container_name: 'postgres'
      image: postgres
      environment:
        POSTGRES_PASSWORD: password123
      ports:
        - "5432:5432"
        # (HOST:CONTAINER)
      volumes:
        - pgdata:/var/lib/postgresql/data/

    web:
      # build: ./api
      # command: python manage.py runserver 0.0.0.0:8000
      image: twtrubiks/my_django
      restart: always
      volumes:
        - api_data:/docker_api
        # (HOST:CONTAINER)
      ports:
        - "8000:8000"
        # (HOST:CONTAINER)
      depends_on:
        - db

      logging:
        driver: syslog
        options:
            syslog-address: tcp://0.0.0.0:5000
            tag: web-container-tcp

      # logging:
      #   driver: gelf
      #   options:
      #     gelf-address: udp://0.0.0.0:12201
      #     tag: web-container-udp

volumes:
    api_data:
    pgdata:

以上這個範例是從 Docker 基本教學 - 從無到有 Docker-Beginners-Guide修改過來的,

一樣執行 docker-compose up

img

接著到 Kibana 中可以看到 log 資訊

img

後記:

這篇文章主要是帶大家對 ELK 有一些基本的觀念,因為 ELK 可以玩的東西真的非常的多,

坑很大,像是前面所說的 logstash.conf 中可以設定的參數,像是 filters 之類的.......

又或是 Kibana 如何呈現精美的圖表,甚至將 docker-elk 佈署到 Swarm 中,都可以玩玩

看,所以大家有興趣可以再自行深入研究😄

我本來是想要透過 Django 結合 Haystack 做個全文檢索的範例,但因為 Haystack 對於

ElasticSearch 的版本只支援到 2.X ( ElasticSearch 都出到 6.X 了 ),最後就沒有將這範例

寫出來了😅

elasticsearch-py 這個 library 也可以看看,我用 6.x 版本測試,還是有一點問題,問題

如果解決再分享給各位😆

執行環境

  • Python 3.6.2

Reference

Donation

文章都是我自己研究內化後原創,如果有幫助到您,也想鼓勵我的話,歡迎請我喝一杯咖啡😆

alt tag

贊助者付款

License

MIT license



Alternative Project Comparisons
Related Awesome Lists
Top Programming Languages
Top Projects

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Python (837,714
Docker (98,179
Django (35,427
Tutorial (23,657
Logging (15,926
Youtube (13,402
Elasticsearch (11,392
Kibana (3,047
Logstash (2,849
Elk (1,795
Docker Logging (3