nginx+logstash+mysql 實(shí)時(shí)存儲(chǔ)數(shù)據(jù)

實(shí)現(xiàn)思路:
1.硬件端日志訪(fǎng)問(wèn)nginx附帶json格式日志
2.后通過(guò)logstash實(shí)時(shí)讀取nginx日志存儲(chǔ)于mysql中

1.nginx安裝和配置

1.1 point-record為自定義nginx服務(wù)名

docker run  -p 80:80 --name=point-record -v /opt/point-record/conf.d:/etc/nginx/conf.d -v /opt/point-record/web:/etc/nginx/web -v  /opt/nginx-log/point-record/:/var/log/nginx/ -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime -d nginx

1.2 在/opt/point-record/conf.d創(chuàng)建配置文件point.conf

cd /opt/point-record/conf.d

nano point.conf

point.conf:

log_format json escape=json '{"timestamp":"$time_iso8601",'
                           '"version":"1",'
                           '"client":"$remote_addr",'
                           '"url":"$uri",'
                           '"status":"$status",'
                           '"domain":"$host",'
                           '"host":"$server_addr",'
                           '"size":$body_bytes_sent,'
                           '"responsetime":$request_time,'
                           '"referer":"$http_referer",'
                            #消息體打印
                           '"body":$request_body,'
                           '"ua": "$http_user_agent"'
               '}';
               
               
server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /etc/nginx/web;
        location / {
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_redirect off;
            #必須經(jīng)過(guò)一次轉(zhuǎn)發(fā),否則nginx不會(huì)讀取消息體,打印的request_body為空
            proxy_pass $scheme://127.0.0.1:$server_port/success;
            access_log  /var/log/nginx/access_json.log  json;
           
        }
        location /success {
            return 200;
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

2.logstash安裝與配置

2.1 官網(wǎng)下載 logstash-7.5.1.tar.gz 上傳服務(wù)器并解壓

tar -xzvf logstash-7.5.1.tar.gz -C /usr/local/
                                                                                               
cd /usr/local/

#修改文件夾名稱(chēng) ("logstash7" 是為了區(qū)分版本,可以同時(shí)安裝多個(gè)版本)
mv logstash-7.5.1 logstash7

cd  logstash7

目錄下文件:


image.png
image.png

2.2 logstash原生版本只有input中自帶jdbc插件,這意味著只支持jdbc導(dǎo)入不支持jdbc導(dǎo)出,需要額外安裝網(wǎng)友的自制插件:

2.2.1 logstash配置mysql-connector-java包
MySQL Connector/J是MySQL官方JDBC驅(qū)動(dòng)程序,JDBC(Java Data Base Connectivity,java數(shù)據(jù)庫(kù)連接)是一種用于執(zhí)行SQL語(yǔ)句的Java API,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供統(tǒng)一訪(fǎng)問(wèn)忌傻,它由一組用Java語(yǔ)言編寫(xiě)的類(lèi)和接口組成深纲。
官方下載地址:https://dev.mysql.com/downloads/connector/
下載地址:https://dev.mysql.com/downloads/connector/j/

mkdir -p /usr/local/logstash7/jdbc

cd /usr/local/logstash7/jdbc

# 上傳mysql-connector-java包
rz

tar -xzvf mysql-connector-java-8.0.19.tar.gz

2.2.2 安裝 logstash-output-jdbc插件
更改gem源:
國(guó)外的gem源由于網(wǎng)絡(luò)原因浸卦,從國(guó)內(nèi)訪(fǎng)問(wèn)太慢而且不穩(wěn)定拓型,還經(jīng)常安裝不成功

cd /usr/local/logstash7/

在安裝 目錄下找到Gemfile文件

image.png
image.png

編輯該文件將source改為 https://gems.ruby-china.com
image.png
image.png

修改完成后運(yùn)行安裝命令

/usr/local/logstash7/bin/logstash-plugin install logstash-output-jdbc

運(yùn)行后輸出Installation successful表示成功


image.png
image.png

2.3 配置config文件
在 /usr/local/logstash7/config/目錄下創(chuàng)建nginx.conf文件

input {
        file {
                path => ["/opt/nginx-log/point-record/access_json.log"]
                type => "nginx"
        }
}
filter {
         mutate {
        #先替換掉字符串當(dāng)中的特殊字符在做json轉(zhuǎn)換
        gsub =>["message", "\\n", ""]
        gsub =>["message", "\\r", ""]
        gsub =>["message", "\\t", ""]
        gsub =>["message", "[\\]", ""]
    
        }
          json {
                 source => "message"
          }
    
     mutate {
                gsub =>["timestamp", "T", " "]
                gsub =>["timestamp", "\+08:00", ""]
                
        add_field => {"pass_flag"=>"0"}
                add_field =>{"appId"=>"%{[body][appID]}"}
        add_field =>{"appType"=>"%{[body][appType]}"}
        add_field =>{"appVer"=>"%{[body][appVer]}"}
        add_field =>{"userID"=>"%{[body][userID]}"}
        add_field =>{"sessionID"=>"%{[body][sessionID]}"}
        add_field =>{"deviceID"=>"%{[body][deviceID]}"}
        add_field =>{"deviceType"=>"%{[body][deviceType]}"}
        add_field =>{"OSVer"=>"%{[body][OSVer]}"}
        add_field =>{"lang"=>"%{[body][lang]}"}
        add_field =>{"deviceInfo_devRes"=>"%{[body][deviceInfo][devRes]}"}
        add_field =>{"deviceInfo_auxRes"=>"%{[body][deviceInfo][auxRes]}"}
        add_field =>{"sign"=>"%{[body][sign]}"}
        add_field =>{"ntime"=>"%{[body][ntime]}"}
                    
        add_field =>{"eventId"=>"%{[body][eventId]}"}
        add_field =>{"arg1"=>"%{[body][arg1]}"}
        add_field =>{"arg2"=>"%{[body][arg2]}"}
        add_field =>{"arg3"=>"%{[body][arg3]}"}
        add_field =>{"arg4"=>"%{[body][arg4]}"}
        add_field =>{"arg5"=>"%{[body][arg5]}"}
        add_field =>{"arg6"=>"%{[body][arg6]}"}
        add_field =>{"arg7"=>"%{[body][arg7]}"}
        add_field =>{"arg8"=>"%{[body][arg8]}"}
        add_field =>{"arg9"=>"%{[body][arg9]}"}
        
        add_field =>{"arg10"=>"%{[body][arg10]}"}
    }
    
    
    
    ruby {
        
        code =>"
            salt='XXXXX.com@0723'
            appid = event.get('appId')
            appType =event.get('appType')
            appVer=event.get('appVer')
            userID=event.get('userID')
            sessionID=event.get('sessionID')
            deviceID = event.get('deviceID')    
            target = '' << appType << appid << appVer << userID << salt << sessionID << deviceID
            event.set('md5_value',target)
            require 'digest/md5';
            md5id = Digest::MD5.hexdigest(target)    
            event.set('md5id',md5id)
            if md5id== event.get('sign')
                event.set('pass_flag','1')
        
            end
        "
    }
    mutate {
        remove_field =>["body","@timestamp","message"]
    }
}
output {
    stdout {codec => "rubydebug"}
    
    if [pass_flag] == "1" {
        jdbc {
            driver_jar_path => "/usr/local/logstash7/jdbc/mysql-connector-java-8.0.19/mysql-connector-java-8.0.19.jar"
            driver_class => "com.mysql.jdbc.Driver"
            #數(shù)據(jù)庫(kù)連接
            connection_string => "jdbc:mysql://rm-bp131frjzi5x1h304.mysql.rds.aliyuncs.com:3306/edu-big-class-test?user=root&password=sairobo@mxxz3rzzz"
            #insert語(yǔ)句            
            statement => [ "insert into point_record (`client_ip`,`svrtime`,`app_type`,`app_id`,`app_ver`,`user_id`,`session_id`,`device_id`,`device_type`,`os_ver`,`lang`,`device_dev_res`,`device_aux_res`,`ntime`,`event_id`,`arg1`,`arg2`,`arg3`,`arg4`,`arg5`,`arg6`,`arg7`,`arg8`,`arg9`,`arg10`) value(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
             "client","timestamp","appType","appId","appVer","userID","sessionID","deviceID","deviceType","OSVer","lang","deviceInfo_devRes","deviceInfo_auxRes","ntime","eventId","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9","arg10"]
        }
    }
}

3 啟動(dòng)
前臺(tái)啟動(dòng)命令如下,

/usr/local/logstash7/bin/logstash -f /usr/local/logstash7/config/nginx.conf

結(jié)束: Ctrl+c

后臺(tái)啟動(dòng)

nohup  /usr/local/logstash7/bin/logstash -f /usr/local/logstash7/config/nginx.conf  >/dev/null &

結(jié)束:

jobs -l
image.png
image.png

獲取到pid為28978

kill -9 28978

使用postman模擬測(cè)試

image.png

每次send請(qǐng)求模擬一次硬件端的日志請(qǐng)求

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鞍匾,一起剝皮案震驚了整個(gè)濱河市般贼,隨后出現(xiàn)的幾起案子愧哟,更是在濱河造成了極大的恐慌,老刑警劉巖哼蛆,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕊梧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡腮介,警方通過(guò)查閱死者的電腦和手機(jī)肥矢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)萤厅,“玉大人橄抹,你說(shuō)我怎么就攤上這事√栉叮” “怎么了楼誓?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)名挥。 經(jīng)常有香客問(wèn)我疟羹,道長(zhǎng),這世上最難降的妖魔是什么禀倔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任榄融,我火速辦了婚禮,結(jié)果婚禮上救湖,老公的妹妹穿的比我還像新娘愧杯。我一直安慰自己,他們只是感情好鞋既,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布力九。 她就那樣靜靜地躺著耍铜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跌前。 梳的紋絲不亂的頭發(fā)上棕兼,一...
    開(kāi)封第一講書(shū)人閱讀 52,785評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音抵乓,去河邊找鬼伴挚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛灾炭,可吹牛的內(nèi)容都是我干的茎芋。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼咆贬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼败徊!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起掏缎,我...
    開(kāi)封第一講書(shū)人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤皱蹦,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后眷蜈,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體沪哺,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年酌儒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辜妓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡忌怎,死狀恐怖籍滴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情榴啸,我是刑警寧澤孽惰,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站鸥印,受9級(jí)特大地震影響勋功,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜库说,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一狂鞋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧潜的,春花似錦骚揍、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)纤掸。三九已至,卻和暖如春浑塞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背政己。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工酌壕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人歇由。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓卵牍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親沦泌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子糊昙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容