惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
The GitHub Blog
The GitHub Blog
Martin Fowler
Martin Fowler
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
有赞技术团队
有赞技术团队
GbyAI
GbyAI
F
Fortinet All Blogs
The Cloudflare Blog
爱范儿
爱范儿
IT之家
IT之家
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
博客园 - 【当耐特】
博客园_首页
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
量子位
C
Cisco Blogs
Latest news
Latest news
Hugging Face - Blog
Hugging Face - Blog
S
Securelist
Stack Overflow Blog
Stack Overflow Blog
K
Kaspersky official blog
Spread Privacy
Spread Privacy
B
Blog
L
Lohrmann on Cybersecurity
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
P
Privacy International News Feed
T
Tor Project blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
小众软件
小众软件
P
Proofpoint News Feed
T
Tailwind CSS Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Recorded Future
Recorded Future
S
Secure Thoughts
人人都是产品经理
人人都是产品经理
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
Last Week in AI
Last Week in AI
W
WeLiveSecurity
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
宝玉的分享
宝玉的分享
D
Docker
Blog — PlanetScale
Blog — PlanetScale
雷峰网
雷峰网

Posts on WKLKEN THINKING

apisix 中的 lrucache apisix 中的服务发现机制 apisix 中的负载均衡 apisix etcd机制 聊聊框架 关于 k8s 的 zero downtime deployment 一些建议 apisix 遇到的一些问题 关于在除夕前一天换了一个洗衣机的故事 Django DRF 性能优化 DRF 的一些实践 Part1: Serializer DRF继承关系图 Better Code: 关于接口的灵活性 新的仓库: wklken/naming 缓存使用的一些经验 Better Code: 抽象: 可扩展性与可维护性的抉择 Better Code: 异常时, 该提示用户哪些信息? Better Code: 更好的异常日志打印 Go: some libs Go: go-redis/cache升级的坑 Go: logrus性能提升 Go: gin validation 远程办公的一点总结 Go: 开发过程中的一些bug 项目管理实践: 风险驱动开发 Go: 一种error wrap调用链处理方式 漫谈技术选型 Go: 基于 apitest 做handler层单元测试 Go: go-sql-driver interpolateparams参数优化 [分享]深度工作 你需要更多的思考时间 Django项目重构小结 工作七年小结: 学习,生活及其他 [分享]bash日常: bash-utils 极客时间推广海报 2017总结: 予时光以意义 k8s APIServer源码: api注册详细细节 k8s APIServer源码: api注册主体流程 k8s APIServer源码: 服务启动 k8s APIServer源码: go-restful框架 重构 - 读书笔记(Python示例) 写给新人的沟通建议 vim 杂谈 - 关于快速编辑 vim 杂谈 - 关于移动 读书笔记-重构: 章11 处理概括关系 读书笔记-重构: 章10 简化函数调用 读书笔记-重构: 章9 简化表达式 读书笔记-重构: 章8 重新组织数据 读书笔记-重构: 章7 在对象之间搬移特性 读书笔记-重构: 章6 重新组织函数 Python 代码规范小结 [分享]关于vim ElasticSearch集群部署文档 Logstash+ElasticSearch处理mysql慢查询日志 [分享]关于代码调试DE那些事 Logstash+ElasticSearch+Kibana- 实现相对通用的数据收集分析 ELK维护的一些点(二) [分享]Python源码剖析-数据结构 一些Centos Python生产环境的部署命令 摘录<<6个月学会任何一种外语>> ELK 维护的一些点 也许是一个新的开始 一些vim的个性化配置 读书笔记-调试九法 这段时间的一些想法 Python 源码阅读 - 垃圾回收机制 我为什么要写博客 APUE笔记-第一章 UNIX基础知识 Python源码阅读-闭包的实现 Python源码阅读-内存管理机制(二) Python源码阅读-内存管理机制(一) Python-基础-数据结构小结 '活动'设计的一些trick 一些简单的Python测试题 我的tmux配置及说明【k-tmux】 Review and Restart 工作四周年小结 vim插件: surround & repeat[成对符号编辑] vim插件: gundo[时光机] vim插件: expand-region[区域选中] vim插件: quickrun[快速执行] vim插件: trailing-whitespace[行尾空格处理] vim插件: closetag[成对标签补全] vim插件: ctrlp[文件搜索] vim插件: airline[状态栏增强] vim插件: theme[主题] vim插件: tagbar[大纲式导航] vim插件: nerdcommenter[快速注释] vim插件: rainbow_parentheses[括号高亮] vim插件: syntastic[语法检查] vim插件: delimitmate[符号自动补全] vim插件: matchit[成对标签跳转] vim插件: easy-align[快速对齐] vim插件: multiple-cursors[多光标操作] vim插件: vim-signature[快速标记跳转] vim插件: easymotion[快速跳转] vim插件: vundle[管理插件] Elasticsearch几个问题的解决 分享一份 Vim 简介PPT k-vim 更新9.0版本 关于知识管理工具的思考
Logstash+ElasticSearch+Kibana处理nginx访问日志
2015-04-26 · via Posts on WKLKEN THINKING

ELK似乎是当前最为流行的日志收集-存储-分析的全套解决方案.

去年年初, 公司里已经在用, 当时自己还山寨了一个统计系统(postgresql-echarts, 日志无结构化, json形式存储到postgresql, 构建统一前端配置生成, 调用统一查询接口, 具体细节), 已经过了一年有余.

一年刚好, 发生了很多事, 那套系统不知现在如何了.

在新的公司, 一切都得从0到1, 近期开始关注日志/数据上报/统计, 以及后续的数据挖掘等.


搭建, 测试并上线了一套简单的系统, 初期将所有服务器的nginx日志, 以及搜索日志进行处理.

elk

下面主要介绍对nginx日志进行处理的过程, 不是针对elk的介绍, 所有涉及ip的地方都改成127.0.0.1了, 根据自己环境进行修改

1. nginx日志 -> logstash shipper -> redis

centos使用yum安装nginx后, 默认/etc/nginx/nginx.conf中的日志格式定义为:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

然后在具体server配置中使用

access_log /data/logs/nginx/{PROJECT_NAME}_access.log main;

此时, 我们需要做的是, 将access log通过logstash shipper读取, 转json, 发送到redis, 由后续的logstash indexer进行处理

步骤

1.在日志所在机器部署logstash

2.在logstash安装目录下的patterns中加入一个文件nginx

内容(与上面的log_format相对应)

NGUSERNAME [a-zA-Z\.\@\-\+_%]+
NGUSER %{NGUSERNAME}
NGINXACCESS %{IPORHOST:clientip} - %{NOTSPACE:remote_user} \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NOTSPACE:http_x_forwarded_for}

3.增加一个logstash配置文件: logstash-project-access-log.conf

注意, input的file, filter的grok, output的redis-key

    input {
    file {
        path => [ "/data/logs/nginx/xxxx_access.log" ]
        start_position => "beginning"
    }
    }

    filter {
    mutate { replace => { "type" => "nginx_access" } }
    grok {
        match => { "message" => "%{NGINXACCESS}" }
    }
    date {
        match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
    }
    geoip {
        source => "clientip"
    }
    }


    output {
    redis { host => "127.0.0.1" data_type => "list" key => "logstash:xxxx:access_log" }
    }

4.使用supervisor启动shipper.

    [program:logstash_xxxx_shipper]
    command=/var/shell/logstash/bin/logstash -f /var/shell/logstash/configs/nginx-xxxx-shipper.conf
    numprocs=1
    autostart=true
    autorestart=true
    log_stdout=true
    log_stderr=true
    logfile=/data/logs/logstash/logstash_xxxx_access.log

2. redis -> logstash indexer -> elasticsearch

注意, input的redis为上一步redis配置, key要对应, output的elasticsearch配置, index指定了最终es中存储对应的index, 加日期, 方便对日志进行定期删除

input {
redis {
    host => "127.0.0.1"
    port => "6379"
    key => "logstash:xxxx:access_log"
    data_type => "list"
    codec  => "json"
    type => "logstash-arthas-access"
    tags => ["arthas"]
}
}

output {
elasticsearch {
    host => "127.0.0.1"
    index => "logstash-arthas-access-%{+YYYY.MM.dd}"
}
}

3. elasticsearch -> kibana

剩下的其实没什么了, 启动kibana后, 配置好指向的es, 就可以在kibana中查看到实时的日志数据

demo环境截图

kibana-nginx

kibana中, 支持各种统计, 着实让人惊艳了一把.

除了基本的nginx日志, 还需要在各类url入口, 加入平台, 渠道等信息, 这样通过nginx访问日志, 可以统计到更多的信息

当然, 如果需要一些更为精确/特殊的统计, 需要自行进行数据上报的工作.


后续

  1. 更多的类型的日志聚合, 包括各类访问日志, 统计上报日志等, 日志落地成文件, 永久留存, 转入es中, 只留存三个月
  2. 如何对各类数据进行拆分/汇总
  3. ELK整体部署/运维/扩容等, 包括数据清理
  4. 基于ES日志的业务自定义统计后台(kibana无法满足一些具体业务的统计需求)
  5. 为什么不使用logstash forwarder, 因为目前日志组成等较为简单, 简单处理 , 后续需要用到时再考虑

其他

1. 关于logformat和对应grok的配置

groklogstash的一个插件, 文档

Grok is currently the best way in logstash to parse crappy unstructured log data into something structured and queryable

所以, 我们在处理nginx日志时, 需要根据具体logformat定义对应的grok表达式

除了上面例子中用的那套, 另一份

logformat

  log_format logstash '$http_host '
                      '$remote_addr [$time_local] '
                      '"$request" $status $body_bytes_sent '
                      '"$http_referer" "$http_user_agent" '
                      '$request_time '
                      '$upstream_response_time';

patterns/nginx

NGUSERNAME [a-zA-Z\.\@\-\+_%]+
NGUSER %{NGUSERNAME}
NGINXACCESS %{IPORHOST:http_host} %{IPORHOST:clientip} \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NUMBER:request_time:float} %{NUMBER:upstream_time:float}

如果想自行定义, 可以使用 grokdebug, 将要解析的日志和配置的正则放入, 可以查看最终得到的结构化数据

初期只安装了一个 kopf, web界面查看

3. supervisor

建议使用supervisorelk进行管理,(ps. 不要用yum自带的, 版本太旧好多坑, 浪费1小时……使用pip install安装最新版本即可)

配置示例elk.conf

[program:elasticsearch]
command=/var/shell/elk/elasticsearch/bin/elasticsearch
numprocs=1
autostart=true
autorestart=true

[program:kibana]
command=/var/shell/elk/kibana/bin/kibana
numprocs=1
autostart=true
autorestart=true

[program:logstash_arthas]
command=/var/shell/elk/logstash/bin/logstash -f /var/shell/elk/logstash/config/xxxx_access.conf
numprocs=1
autostart=true
autorestart=true
log_stdout=true
log_stderr=true
logfile=/data/logs/elk/logstash/logstash_arthas_access.log

4. logstash坑

start_position => "beginning"

logstash, 会记录一份文件读到的位置, 在$HOME/.sincedb_xxxxx 如果要让logstash重新读取文件, 删除之即可, 重启shipper.

但是你可能发现es中重复记录了, 这是因为, 在output中, 没有定义存储到es时使用的document_id, es全部当成新纪录存入, 导致数据重复