1.原技术路线解析

在nging配置中将日志信息交给syslog处理,rsyslog配置中将数据传递给了514端口解析,然后将解析好的数据传入elasticsearch中。

nginx配置

    server {
listen 80;
listen [::]:80;
server_name test.86dev.wrddns.com; # 以下两行将日志写入syslog
access_log syslog:server=unix:/dev/log,facility=local5,tag=web_1,severity=info main;
error_log syslog:server=unix:/dev/log,facility=local5,tag=web_1,severity=error warn; # ....其他配置
}

/etc/rsyslog.conf

# 配置文件,存放解析规则xxx.conf和ruleBase文件xx.rb
$IncludeConfig /etc/rsyslog.d/*.conf # 配置将日志放到哪个端口解析
local5.* @10.3.19.86:514

在实际应用过程中有一些问题,不能和php上面的一些配置进行配合记录,解析规则不好配置,有些内容解析不好,所以探索使用新的技术路线。

2.新技术路线

尝试使用新技术路线,通过swoole起一个服务,然后监听9502端口,rsyslog将日志推向该端口,对日志进行解析后推入elasticsearch,此时可以获取到php端的一些配置。以下是大体思路

2.1 选择swoole的server类型。

这里不再赘述swoole的安装,首要考虑的问题是原推向514的协议类型。

先查看端口的协议类型

# root @ WENGINE in ~ [9:48:51]
$ netstat -antup | grep 514
udp 0 0 0.0.0.0:514 0.0.0.0:* 23560/rsyslogd
udp 0 0 :::514 :::* 23560/rsyslogd

可以看到是udp协议,所以选用swoole的 upd服务

结合laravel的commands来编写服务端

<?php

namespace App\Console\Swoole;

use Illuminate\Console\Command;
use swoole_websocket_server;
use swoole_server;
use swoole_process;
use swoole_sock_udp;
use UAParser\Parser;
use GeoIp2\Database\Reader;
use Wrd\Framework\Models\SysConfig;
use Elasticsearch\ClientBuilder; class SwooleServer extends Command
{ protected $signature = 'swoole-server start
{cmd=start : can use start}
{--daemon : set to run in daemonize mode}
'; protected $description = 'swoole server control'; public $access_buffer = []; public function __construct()
{
parent::__construct();
} public function handle()
{
$command = $this->argument('cmd');
$option = $this->option('daemon');
switch ($command) {
case 'start':
$this->initWs($option);
break;
default:
$this->info('请按照下面格式输入命令:php artisan swoole-server {start}');
break;
} } public function initWs($daemonize = false)
{
if ($daemonize) {
$this->info('Starting Websocket server in daemon mode...');
} else {
$this->info('Starting Websocket server in interactive mode...');
} $server = new swoole_server('0.0.0.0', 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);
$server->set([
'daemonize' => $daemonize,
'log_file' => '/var/www/html/storage/logs/websocket.log',
'worker_num' => 1,
'task_worker_num' => 1,
]); $server->on('Packet', function($serv, $data, $clientInfo)
{
$serv->task($data);
}); $server->on('Task', function ($serv, $task_id, $from_id, $data) { //通过正则表达式提取出需要的信息,不同的日志格式需要不同的正则,这里只写一种情况
$rule = '/\<\d*\>.*\d{2}\:\d{2}\:\d{2}\s[^\s]*\s[^\s]*\s(\w*\_\d*)\:\s\[Customize-format\]/'; preg_match($rule, $data, $matches); if (empty($matches)) {
$this->writeLog($data); //记录下无法解析的日志,更正正则
return false;
} $vhost = $matches[1];
$ip = $matches[2];
//...更多参数 $ua = $matches[12];
//解析UA,这里使用的解析库https://github.com/ua-parser/uap-php
$parser = Parser::create();
$parser_ua = $parser->parse($ua);
$browser = $parser_ua->ua->family;
$os = $parser_ua->os->family;
$device = $parser_ua->device->family; //解析IP,这里使用的解析库https://github.com/maxmind/GeoIP2-php
$reader = new Reader(public_path().'/geoip2/GeoLite2-City.mmdb'); try{
$record = $reader->city($ip);
$country = $record->country->isoCode;
$continent = $record->continent->names['zh-CN'];
$subdivisions = $record->mostSpecificSubdivision->names['zh-CN'];
$city = $record->city->names['zh-CN'];
$geoip = array(
'location' => array($record->location->longitude, $record->location->latitude)
); } catch (\Exception $e) {
//如果ip没有被收录(项目有很多内网ip),则拿数据库中的提前配置项,进行解析
} $res = array(
'vhost' => $vhost,
'ip' => $ip,
// ...其它项
'token' => $token,
'browser' => $browser,
'os' => $os,
'device' => $device,
'continent' => $continent,
'country' => $country,
'subdivisions' => $subdivisions,
'city' => $city,
'geoip' => $geoip,
); $this->access_buffer[] = $res; //每隔一段时间,写入到elasticsearch
if (count($this->access_buffer) > 0 && time() - strtotime($this->access_buffer[0]['@timestamp']) > 10) {
$insert_data = $this->access_buffer;
$this->access_buffer = []; $this->insertElasticsearch('access', $insert_data);
} //return 数据 给 Finish
return "Task {$task_id}'s result";
}); $server->on('Finish', function ($serv,$task_id, $data) {
echo "Task {$task_id} finish\n";
}); $server->start(); } public function insertElasticsearch($type='access', $data){
foreach($data as $item){
$params['body'][] = [
'index' => [
'_index' => $type.'-'.date('Y.m.d', time()),
'_type' => 'events',
]
];
$params['body'][] = $item;
} extract(\Config::get('app.elastic', [
'host' => '127.0.0.1',
'port' => '9200'
])); //往elasticsearch写数据,这里使用的库https://github.com/elastic/elasticsearch-php
$helper = ClientBuilder::create()
->setHosts([$host.":".$port])
->build(); if (!empty($params['body'])) {
$response = $helper->bulk($params);
//var_dump($response);
} } public function writeLog($info){
$alert_message = array(
'error' => '此条信息未能命中日志格式,未写入elasticsearch',
'info' => $info
);
\Log::alert($alert_message);
}

2.2 通过更改nginx的main日志格式简化正则表达式

nginx的配置中的

log_format main [$proxy_add_x_forwarded_for]-[$remote_user]-[$time_local]-[$request]-[$status]-[$bytes_sent]-[$http_host]-[$http_referer]-[$http_user_agent]-[$cookie_wengine_ticket]-[archer-main];

加了特殊符号,并且最后给了一个标识,这样能提高命中准确度

2.3 更改rsyslog的端口

local5.* @10.3.19.86:9502

2.4 其它一些问题

可以通过nc来检测swoole的udp服务是否通

yum install -y nc
# root @ WENGINE in ~ [10:17:07] C:130
$ nc -u 127.0.0.1 9502
ceshi

可以写supervisor的脚本来使swoole服务器一直启动

[program:swooleserver]
directory = /var/www/html
command=php artisan swoole-server
user=apache
autostart=true
startsecs=2
autorestart=true
redirect_stderr=true
stopsignal=INT
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10
stderr_capture_maxbytes=1MB
stderr_events_enabled=false

用swoole实现nginx日志解析的更多相关文章

  1. tomcat及nginx相关,格式化输出,配置及日志解析

    1.https://www.cnblogs.com/jingmoxukong/p/8258837.html?utm_source=gold_browser_extension       Tomcat ...

  2. Logstash使用grok插件解析Nginx日志

    grok表达式的打印复制格式的完整语法是下面这样的: %{PATTERN_NAME:capture_name:data_type}data_type 目前只支持两个值:int 和 float. 在线g ...

  3. Logstash收集nginx日志之使用grok过滤插件解析日志

    grok作为一个logstash的过滤插件,支持根据模式解析文本日志行,拆成字段. nginx日志的配置: log_format main '$remote_addr - $remote_user [ ...

  4. ELK+Redis 解析Nginx日志

    一.ELK简介 Elk是指logstash,elasticsearch,kibana三件套,我们一般使用它们做日志分析. ELK工作原理图: 简单来讲ELK具体的工作流程就是客户端的logstash ...

  5. 使用Hive的正则解析器RegexSerDe分析nginx日志

    1.环境: hadoop-2.6.0 + apache-hive-1.2.0-bin 2.使用Hive分析nginx日志,站点的訪问日志部分内容为: cat /home/hadoop/hivetest ...

  6. [日志分析]Graylog2进阶 通过正则解析Nginx日志

    之前分享的 [日志分析]Graylog2采集Nginx日志 主动方式 这篇文章介绍了Graylog如何通过Graylog Collector Sidecar来采集nginx日志. 由于日志是未经处理的 ...

  7. Goaccess解析nginx日志备忘

    参考 http://nginx.org/en/docs/http/ngx_http_log_module.html?&_ga=1.92028562.949762386.1481787781#l ...

  8. 烂泥:利用awstats分析nginx日志

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 昨天把nginx的日志进行了切割,关于如何切割nginx日志,可以查看<烂泥:切割 ...

  9. nginx日志分析利器GoAccess

    面试的时候一定会被面到的问题是:给出web服务器的访问日志,请写一个脚本来统计访问前10的IP有哪些?访问前10的请求有哪些?当你领略过goaccess之后,你就明白,这些问题,除了考验你的脚本背诵记 ...

随机推荐

  1. Description Resource Path Location Type Java compiler level does not match the version of the installed Java project facet Unknown Faceted Project Problem (Java Version Mismatch)

    project 编译问题,需要三处的jdk版本要保持一致,才能编译通过. 1.在项目上右键properties->project Facets->修改右侧的version  保持一致 2. ...

  2. 02、体验Spark shell下RDD编程

    02.体验Spark shell下RDD编程 1.Spark RDD介绍 RDD是Resilient Distributed Dataset,中文翻译是弹性分布式数据集.该类是Spark是核心类成员之 ...

  3. Unity3D转UE4指南

    坐标: Unity3D X - left, right Y - up, down Z - forwards, backwards Unreal Engine4 X - forwards, backwa ...

  4. 会说话的ABAP report

    report z. INCLUDE ole2incl. DATA: ole   TYPE ole2_object,       voice TYPE ole2_object,       text   ...

  5. InnoDB锁演示

    create table t1( c1 int(10) unsigned not null default '0', c2 int(10) unsigned not null default '0', ...

  6. NutDao配置多数据源

    首先,我必须声明,这是一个非常简单的方法,很多小菜没做出来,是因为把nutz想得太复杂 数据源(或者是数据库连接池),在Nutz.Ioc看来,是一个普通的Bean,没任何特别之处. 再强调一点,除了$ ...

  7. 安装ubuntu-tweak

    第一步:添加tweak源 sudo add-apt-repository ppa:tualatrix/ppa   第二步:更新 sudo apt-get update   第三步:安装ubuntu-t ...

  8. ES6介绍

    1.ES6简介 ECMAScript 6.0,是 JavaScript 语言下一代标准,发布于 2015 年 6 月.它的目标是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业 ...

  9. JT/T 1077-2016《道路运输车辆卫星定位系统车载视频平台技术要求》平台标准符合性检测合同

    合同编号: 道路运输车辆卫星定位系统 平台标准符合性检测合同 委托方(甲方): 受托方(乙方): 交通运输通信信息工程质量检测中心 签订时间: 签订地点: 北京市 委托方(甲方): 委托方(甲方): ...

  10. c#简单加密和对称加密

    转自:https://www.cnblogs.com/zhihai/archive/2012/05/03/2480856.html using System;using System.Collecti ...