рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдЪрд░рдг рдХреЛ рдкрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рд▓реЙрдЧрд┐рдВрдЧ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЙрдЪрд┐рдд рд▓реЙрдЧрд┐рдВрдЧ рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рддреА рд╣реИ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреА рд╣реИред рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЪрд░рдг рдореЗрдВ, рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓реЙрдЧрд┐рдВрдЧ рдХрд░рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓ рдерд╛ рдЬрдм рддрдХ рдХрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдирд╣реАрдВ рдмрдврд╝реА рдФрд░ рд▓реЙрдЧ рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬ рдореЗрдВ рд╕рдордп рд▓рдЧрдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реБрдЖред
рд╕рдорд╛рдзрд╛рди рд▓реЙрдЧ рдФрд░ рдЦреЛрдЬ рдХреЗ рдПрдХрддреНрд░реАрдХрд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдХреЗрдВрджреНрд░реАрдХреГрдд рд▓реЙрдЧ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдмрдирд╛рдирд╛ рдерд╛ред рдЪреБрдирд╛рд╡ ELK рд╕реНрдЯреИрдХ рдкрд░ рдЧрд┐рд░ рдЧрдпрд╛ред ELK рддреАрди рдУрдкрдирд╕реЛрд░реНрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдХрд╛ рдПрдХ рд╕рдВрдпреЛрдЬрди рд╣реИ: рдЗрд▓рд╛рд╕реНрдЯрд┐рдХрд╕рд░реНрдЪ, рд▓реЙрдЧрд╕реНрдЯреИрд╢ рдФрд░ рдХрд┐рдмрд╛рдирд╛ред ELK рд╕реНрдЯреЛрд░ рд▓реЙрдЧреНрд╕ рдмрдирд╛рддрд╛ рд╣реИ, рдЧреНрд░рд╛рдлрд╝ рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд╕рд╛рде рдкреВрд░реНрдг-рдкрд╛рда рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд╣реИред рд▓реЗрдЦ рдореЗрдВ Django рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдЧ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП ELK рд╕реНрдЯреИрдХ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
ELK рд╕реНрдерд╛рдкрдирд╛
рдбреЙрдХрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдбреЙрдХ-рдПрд▓реНрдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдИрдПрд▓рдХреЗ рд╕реНрдЯреИрдХ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред Logstash рд╕реЗрдЯрд┐рдВрдЧ рдмрджрд▓реЗрдВ, nginx рд▓реЙрдЧ рдХреЗ рдорд┐рд▓рд╛рди рдХреЗ рд▓рд┐рдП GROK рдкреИрдЯрд░реНрди рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рд╕реЗрдХреНрд╢рди рдХреЛ рдмрджрд▓реЗрдВ рддрд╛рдХрд┐ Django рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдЧ рдФрд░ nginx рд▓реЙрдЧ рдЕрд▓рдЧ-рдЕрд▓рдЧ ElasticSearch рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрдВред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, logstash.conf рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
input { beats { port => 5000 host => "0.0.0.0" } } filter { if [type] == "nginx" { grok { match => { "message" => "%{IPORHOST:remote_ip} - %{DATA:user_name} \[%{HTTPDATE:access_time}\] \"%{WORD:http_method} %{DATA:url} HTTP/%{NUMBER:http_version}\" %{NUMBER:response_code} %{NUMBER:body_sent_bytes} \"%{DATA:referrer}\" \"%{DATA:agent}\"" } } } } output { if [type] == "nginx" { elasticsearch { hosts => "elasticsearch:9200" index => "nginx-%{+YYYY.MM.dd}" } } else if [type] == "django" { elasticsearch { hosts => "elasticsearch:9200" index => "django-%{+YYYY.MM.dd}" } } else { elasticsearch { hosts => "elasticsearch:9200" index => "unknown_messages" } } }
рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╕реНрдЯреИрдХ рдЪрд▓рд╛рдПрдБ:
docker-compose up
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╕реНрдЯреИрдХ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рдкрд░ рд╕реБрдирддрд╛ рд╣реИ:
- 5000: рд▓реЙрдЧрд╕реНрдЯреИрд╢ рдЯреАрд╕реАрдкреА рдЗрдирдкреБрдЯред
- 9200: рдПрд▓рд┐рд╕реНрдЯрд┐рдХреНрд╕ рдЦреЛрдЬ HTTP
- 9300: рдЗрд▓рд╛рд╕реНрдЯрд┐рд╕рд░реНрдЪ рдЯреАрд╕реАрдкреА рдкрд░рд┐рд╡рд╣рди
- 5601: рдХрд┐рдмрд╛рдирд╛
рд▓реЙрдЧрд┐рдВрдЧ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░
рдПрдХ Django рдЖрд╡реЗрджрди рдХреА рд▓реЙрдЧрд┐рдВрдЧ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЖрд░реЗрдЦ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╕реЗрд╡рд╛рдПрдБ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: nginx, django рдЕрдиреБрдкреНрд░рдпреЛрдЧ, рдЕрдЬрд╡рд╛рдЗрди рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ред рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ ELK рд╕реНрдЯреИрдХ рдореЗрдВ рд▓реЙрдЧ рднреЗрдЬрддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдХреЛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
рд▓реЗрдЦрди рдирдЧреНрдиреЗрдХреНрд╕ рд▓реЙрдЧреНрд╕ рдХреЛ рдИрдПрд▓рдХреЗ
рдирдЧреАрдирдХреНрд╕ рд▓реЙрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдлрд╝рд╛рдЗрд▓рдмреАрдЯ рд╕реЗрд╡рд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдлрд╛рдЗрд▓рдмреАрдЯ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдкрдирд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдПрдХ Ubuntu рд╕рд░реНрд╡рд░ рдкрд░ рдлрд╝рд╛рдЗрд▓рдмреАрдЯ рд╕реЗрд╡рд╛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдЙрджрд╛рд╣рд░рдг:
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.4.0-amd64.deb sudo dpkg -i filebeat-6.4.0-amd64.deb
рдлрд╛рдЗрд▓рдмреАрдЯ рдлрд╛рдЗрд▓ рд╕реЗ рд▓реЙрдЧ рдкрдврд╝реЗрдЧрд╛ рдФрд░ рд▓реЙрдЧрд╕реНрдЯреИрд╢ рдХреЛ рднреЗрдЬреЗрдЧрд╛ред рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЙрджрд╛рд╣рд░рдг:
filebeat.inputs: - type: log enabled: true paths: - /var/log/nginx/access.log fields: type: nginx fields_under_root: true scan_frequency: 5s output.logstash: hosts: ["logstash:5000"]
рд╣рдо рдЕрдкрдиреА рдлрд╝рд╛рдЗрд▓рдмреАрдЯ рд╕реЗрд╡рд╛ рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХрд┐рдмрд╛рдирд╛ рдореЗрдВ рд▓реЙрдЧ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВред
ELK рдореЗрдВ Django рд▓реЙрдЧреНрд╕ рд▓рд┐рдЦрдирд╛
Django рдХреЗ рд▓рд┐рдП Logstash рд╕реЗрд╡рд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡реИрдХрд▓реНрдкрд┐рдХ Python-logstash рдкреИрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВред
pip install python-logstash
рдЪрд▓рд┐рдП Django рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд▓реЙрдЧ рдХреЛ рд▓реЙрдЧрд╕реНрдЯреИрд╢ рд╕реЗрд╡рд╛ рдореЗрдВ рднреЗрдЬрд╛ рдЬрд╛рдПред
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'simple': { 'format': 'velname)s %(message)s' }, }, 'handlers': { 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'logstash': { 'level': 'INFO', 'class': 'logstash.TCPLogstashHandler', 'host': 'logstash', 'port': 5000, 'version': 1, 'message_type': 'django', # 'type' logstash . 'fqdn': False, 'tags': ['django'], # . }, }, 'loggers': { 'django.request': { 'handlers': ['logstash'], 'level': 'INFO', 'propagate': True, }, ... } }
рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрд╡реЗрджрди рд▓реЙрдЧрд╕реНрдЯреИрд╢ рдореЗрдВ рд▓реЙрдЧ рднреЗрдЬ рджреЗрдЧрд╛ред рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг:
import logging logger = logging.getLogger(__name__) def test_view(request, arg1, arg): ... if is_error:
рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд▓рд┐рдП рдХрд┐рдмрдирд╛ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред рдЕрдкрдиреА рд╕реНрд╡рдпрдВ рдХреА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ:



рд╕рд┐рд╕реНрдЯрдо рд╕реЗрд╡рд╛ рд▓реЙрдЧ рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдЙрдирдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рдиреЗ, рдЧреНрд░рд╛рдлрд╝ рдФрд░ рд╡рд┐рдЬрд╝реБрдЕрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдмрдирд╛рдиреЗ, рдЖрдкрдХреЛ рдЬрд▓реНрджреА рд╕реЗ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рдареАрдХ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред