nginx配置自定義變量實現(xiàn)日志動態(tài)分發(fā)

Nginx是一個異步框架的 Web服務(wù)器,也可以用作反向代理,負載平衡器 和 HTTP緩存。下載地址:www.nginx.org。

  • 當(dāng)我們實際用的時候需要先在配置文件中配置反向代理及負載均衡和日志格式和文件地址。我nginx安裝地址為/soft/nginx,nginx編譯安裝好之后會有多份nginx.conf文件,一份為/soft/nginx/nginx.conf;另一份為/soft/nginx/conf/nginx.conf。如果服務(wù)器中存在多個nginx.conf文件,我們并不知道實際上調(diào)用的是哪個配置文件,因此我們必須找到實際調(diào)用的配置文件才能進行修改。

查看nginx實際調(diào)用的配置文件

  1. 查看nginx路徑
[centos@bogon nginx]$ ps -aux|grep nginx
root      22591  0.0  0.0  25008  1656 ?        Ss   Nov07   0:00 nginx: master process /soft/nginx/sbin/nginx
centos    23716  0.0  0.1  25376  1916 ?        S    19:54   0:00 nginx: worker process
centos    23824  0.0  0.0 112708   968 pts/1    S+   22:06   0:00 grep --color=auto nginx

nginx的路徑為:/soft/nginx/sbin/nginx

  1. 查看nginx配置文件路徑
    使用nginx的 -t 參數(shù)進行配置檢查,即可知道實際調(diào)用的配置文件路徑及是否調(diào)用有效。
[centos@bogon nginx]$ sudo /soft/nginx/sbin/nginx -t
nginx: the configuration file /soft/nginx/nginx.conf syntax is ok
nginx: configuration file /soft/nginx/nginx.conf test is successful

可知,nginx的配置文件路徑為:/soft/nginx/nginx.conf 且調(diào)用有效。

修改nginx.conf 進行個性化配置,以達到日志動態(tài)分發(fā)

我的需求:根據(jù)請求url里面?zhèn)€別關(guān)鍵字不同將請求日志記錄到不同日志文件中。
先看看菜鳥教程關(guān)于nginx.conf參數(shù)的講解:http://www.runoob.com/w3cnote/nginx-install-and-config.html

  1. 訪問日志參數(shù)
    Nginx訪問日志主要有兩個參數(shù)控制
  • log_format ----用來定義記錄日志的格式(可以定義多種日志格式,取不同名字即可)
  • access_log -----用來指定日至文件的路徑及使用的何種日志格式記錄日志
    log_format的默認(rèn)值:
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

access_log的默認(rèn)值:

access_log  logs/access.log  main;

log_format語法格式及參數(shù)語法說明如下:

 log_format    <NAME>    <Strin---g>;
    關(guān)鍵字         格式標(biāo)簽   日志格式
    關(guān)鍵字:其中關(guān)鍵字error_log不能改變
    格式標(biāo)簽:格式標(biāo)簽是給一套日志格式設(shè)置一個獨特的名字
    日志格式:給日志設(shè)置格式
log_format格式變量:
    $remote_addr  #記錄訪問網(wǎng)站的客戶端地址
    $remote_user  #遠程客戶端用戶名
    $time_local  #記錄訪問時間與時區(qū)
    $request  #用戶的http請求起始行信息
    $status  #http狀態(tài)碼,記錄請求返回的狀態(tài)碼,例如:200、301、404等
    $body_bytes_sent  #服務(wù)器發(fā)送給客戶端的響應(yīng)body字節(jié)數(shù)\
    $http_referer  #記錄此次請求是從哪個連接訪問過來的,可以根據(jù)該參數(shù)進行防盜鏈設(shè)置。
    $http_user_agent  #記錄客戶端訪問信息,例如:瀏覽器、手機客戶端等
    $http_x_forwarded_for  #當(dāng)前端有代理服務(wù)器時,設(shè)置web節(jié)點記錄客戶端地址的配置,此參數(shù)生效的前提是代理服務(wù)器也要進行相關(guān)的x_forwarded_for設(shè)置

access_log語法格式及參數(shù)語法說明如下:

 access_log    <FILE>    <NAME>;
    關(guān)鍵字         日志文件   格式標(biāo)簽
    關(guān)鍵字:其中關(guān)鍵字error_log不能改變
    日志文件:可以指定任意存放日志的目錄
    格式標(biāo)簽:給日志文件套用指定的日志格式
其他語法:
    access_log    off;  #關(guān)閉access_log,即不記錄訪問日志
    access_log path [format [buffer=size [flush=time]] [if=condition]];
    access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
    access_log syslog:server=address[,parameter=value] [format [if=condition]];
    說明:
    buffer=size  #為存放訪問日志的緩沖區(qū)大小
    flush=time  #為緩沖區(qū)的日志刷到磁盤的時間
    gzip[=level]  #表示壓縮級別
    [if = condition]  #表示其他條件
  1. Nginx內(nèi)置變量以及日志格式變量參數(shù)詳解
$args                    #請求中的參數(shù)值
$query_string            #同 $args
$arg_NAME                #GET請求中NAME的值
$is_args                 #如果請求中有參數(shù),值為"?",否則為空字符串
$uri                     #請求中的當(dāng)前URI(不帶請求參數(shù),參數(shù)位于$args),可以不同于瀏覽器傳遞的$request_uri的值,它可以通過內(nèi)部重定向,或者使用index指令進行修改,$uri不包含主機名,如"/foo/bar.html"。
$document_uri            #同 $uri
$document_root           #當(dāng)前請求的文檔根目錄或別名
$host                    #優(yōu)先級:HTTP請求行的主機名>"HOST"請求頭字段>符合請求的服務(wù)器名.請求中的主機頭字段,如果請求中的主機頭不可用,則為服務(wù)器處理請求的服務(wù)器名稱
$hostname                #主機名
$https                   #如果開啟了SSL安全模式,值為"on",否則為空字符串。
$binary_remote_addr      #客戶端地址的二進制形式,固定長度為4個字節(jié)
$body_bytes_sent         #傳輸給客戶端的字節(jié)數(shù),響應(yīng)頭不計算在內(nèi);這個變量和Apache的mod_log_config模塊中的"%B"參數(shù)保持兼容
$bytes_sent              #傳輸給客戶端的字節(jié)數(shù)
$connection              #TCP連接的序列號
$connection_requests     #TCP連接當(dāng)前的請求數(shù)量
$content_length          #"Content-Length" 請求頭字段
$content_type            #"Content-Type" 請求頭字段
$cookie_name             #cookie名稱
$limit_rate              #用于設(shè)置響應(yīng)的速度限制
$msec                    #當(dāng)前的Unix時間戳
$nginx_version           #nginx版本
$pid                     #工作進程的PID
$pipe                    #如果請求來自管道通信,值為"p",否則為"."
$proxy_protocol_addr     #獲取代理訪問服務(wù)器的客戶端地址,如果是直接訪問,該值為空字符串
$realpath_root           #當(dāng)前請求的文檔根目錄或別名的真實路徑,會將所有符號連接轉(zhuǎn)換為真實路徑
$remote_addr             #客戶端地址
$remote_port             #客戶端端口
$remote_user             #用于HTTP基礎(chǔ)認(rèn)證服務(wù)的用戶名
$request                 #代表客戶端的請求地址
$request_body            #客戶端的請求主體:此變量可在location中使用,將請求主體通過proxy_pass,fastcgi_pass,uwsgi_pass和scgi_pass傳遞給下一級的代理服務(wù)器
$request_body_file       #將客戶端請求主體保存在臨時文件中。文件處理結(jié)束后,此文件需刪除。如果需要之一開啟此功能,需要設(shè)置client_body_in_file_only。如果將次文件傳 遞給后端的代理服務(wù)器,需要禁用request body,即設(shè)置proxy_pass_request_body off,fastcgi_pass_request_body off,uwsgi_pass_request_body off,or scgi_pass_request_body off
$request_completion      #如果請求成功,值為"OK",如果請求未完成或者請求不是一個范圍請求的最后一部分,則為空
$request_filename        #當(dāng)前連接請求的文件路徑,由root或alias指令與URI請求生成
$request_length          #請求的長度 (包括請求的地址,http請求頭和請求主體)
$request_method          #HTTP請求方法,通常為"GET"或"POST"
$request_time            #處理客戶端請求使用的時間,單位為秒,精度毫秒; 從讀入客戶端的第一個字節(jié)開始,直到把最后一個字符發(fā)送給客戶端后進行日志寫入為止。
$request_uri             #這個變量等于包含一些客戶端請求參數(shù)的原始URI,它無法修改,請查看$uri更改或重寫URI,不包含主機名,例如:"/cnphp/test.php?arg=freemouse"
$scheme                  #請求使用的Web協(xié)議,"http" 或 "https"
$server_addr             #服務(wù)器端地址,需要注意的是:為了避免訪問linux系統(tǒng)內(nèi)核,應(yīng)將ip地址提前設(shè)置在配置文件中
$server_name             #服務(wù)器名
$server_port             #服務(wù)器端口
$server_protocol         #服務(wù)器的HTTP版本,通常為 "HTTP/1.0" 或 "HTTP/1.1"
$status                  #HTTP響應(yīng)代碼
$time_iso8601            #服務(wù)器時間的ISO 8610格式
$time_local              #服務(wù)器時間(LOG Format 格式)
$cookie_NAME             #客戶端請求Header頭中的cookie變量,前綴"$cookie_"加上cookie名稱的變量,該變量的值即為cookie名稱的值
$http_NAME               #匹配任意請求頭字段;變量名中的后半部分NAME可以替換成任意請求頭字段,如在配置文件中需要獲取http請求頭:"Accept-Language",$http_accept_language即可
$http_cookie
$http_host               #請求地址,即瀏覽器中你輸入的地址(IP或域名)
$http_referer            #url跳轉(zhuǎn)來源,用來記錄從那個頁面鏈接訪問過來的
$http_user_agent         #用戶終端瀏覽器等信息
$http_x_forwarded_for
$sent_http_NAME          #可以設(shè)置任意http響應(yīng)頭字段;變量名中的后半部分NAME可以替換成任意響應(yīng)頭字段,如需要設(shè)置響應(yīng)頭Content-length,$sent_http_content_length即可
$sent_http_cache_control
$sent_http_connection
$sent_http_content_type
$sent_http_keep_alive
$sent_http_last_modified
$sent_http_location
$sent_http_transfer_encoding

當(dāng)日志文件中記錄的值為"-"時,表示為空.

  1. nginx.conf 自定義變量使用詳解
    在使用Nginx作為網(wǎng)站的web服務(wù)器的時候,為了達到某些效果或者是為了優(yōu)化Nginx服務(wù)器的效率,經(jīng)常要修改Nginx的配置文件Nginx.conf。
    在 Nginx 配置中,自定義變量只能存放一種類型的值,因為也只存在一種類型的值,那就是字符串。
    比如我們的 nginx.conf 文件中有下面這一行配置
set $a "hello world";  

set 配置指令為對 $a 賦值。特別地,我們把字符串 hello world 賦給了它。
同樣的,如果我們要根據(jù)自定義變量達到一些個性化的需求,可以在變量賦值之后做一些判斷賦值定義等操作。這時候可能需要if語句判斷,比如:

if ( $host ~* www\.(.*) )
  {
    set  $host_without_www $1;
  }

但是要注意:if語句只有在server,location代碼塊中才能使用。
在這里我們了解一下NginxRewrite 規(guī)則相關(guān)指令:

1.break指令
    使用環(huán)境:server,location,if;
    該指令的作用是完成當(dāng)前的規(guī)則集,不再處理rewrite指令。

  2.if指令
    使用環(huán)境:server,location
    該指令用于檢查一個條件是否符合,如果條件符合,則執(zhí)行大括號內(nèi)的語句。If指令不支持嵌套,不支持多個條件&&和||處理。

3.return指令
  語法:return code ;
  使用環(huán)境:server,location,if;
  該指令用于結(jié)束規(guī)則的執(zhí)行并返回狀態(tài)碼給客戶端。
  示例:如果訪問的URL以".sh"或".bash"結(jié)尾,則返回403狀態(tài)碼
  location ~ .*\.(sh|bash)?$
  {
    return 403;
  }

4.rewrite 指令
  語法:rewriteregex replacement flag
  使用環(huán)境:server,location,if
  該指令根據(jù)表達式來重定向URI,或者修改字符串。指令根據(jù)配置文件中的順序來執(zhí)行。注意重寫表達式只對相對路徑有效。如果你想配對主機名,你應(yīng)該使用if語句,示例如下:
  if ( $host ~* www\.(.*) )
  {
    set  $host_without_www $1;
    rewrite  ^(.*)$   http://$host_without_www$1 permanent;
  }

5.Set指令
  語法:setvariable value ; 默認(rèn)值:none; 使用環(huán)境:server,location,if;
  該指令用于定義一個變量,并給變量賦值。變量的值可以為文本、變量以及文本變量的聯(lián)合。
  示例:set $varname "hello world";

6.Uninitialized_variable_warn指令
  語法:uninitialized_variable_warnon|off
  使用環(huán)境:http,server,location,if
  該指令用于開啟和關(guān)閉未初始化變量的警告信息,默認(rèn)值為開啟。

下面都是一些Nginx的Rewrite規(guī)則編寫實例

 1.當(dāng)訪問的文件和目錄不存在時,重定向到某個php文件
    if ( !-e $request_filename )
    {
      rewrite ^/(.*)$ index.php last;
    }

  2.目錄對換 /123456/xxxx ====> /xxxx?id=123456
    rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;

  3.如果客戶端使用的是IE瀏覽器,則重定向到/ie目錄下
    if( $http_user_agent ~ MSIE)
    {
      rewrite ^(.*)$ /ie/$1 break;
    }

  4.禁止訪問多個目錄
    location ~ ^/(cron|templates)/
    {
      deny all;
      break;
    }


  5.禁止訪問以/data開頭的文件
    location ~ ^/data
    {
      deny all;
    }


  6.禁止訪問以.sh,.flv,.mp3為文件后綴名的文件
    location ~ .*\.(sh|flv|mp3)$
    {
      return 403;
    }


  7.設(shè)置某些類型文件的瀏覽器緩存時間
    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
      expires 30d;
    }
    location ~ .*\.(js|css)$
    {
      expires 1h;
    }


8.給favicon.ico和robots.txt設(shè)置過期時間;
  這里為favicon.ico為99天,robots.txt為7天并不記錄404錯誤日志
   location ~(favicon.ico)
  {
    log_not_found off;
    expires 99d;
    break;
  }
  location ~(robots.txt)
  {
    log_not_found off;
    expires 7d;
    break;
  }

9.設(shè)定某個文件的過期時間;這里為600秒,并不記錄訪問日志
  location ^~ /html/scripts/loadhead_1.js
  {
    access_log off;
    root /opt/lampp/htdocs/web;
    expires 600;
    break;
  }


10.文件反盜鏈并設(shè)置過期時間
  這里的return412 為自定義的http狀態(tài)碼,默認(rèn)為403,方便找出正確的盜鏈的請求
  “rewrite ^/ http://img.linuxidc.net/leech.gif;” 顯示一張防盜鏈圖片
  “access_log off;” 不記錄訪問日志,減輕壓力
  “expires 3d”  所有文件3天的瀏覽器緩存
  location ~*^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$
  {
    valid_referers none blocked *.linuxidc.com*.linuxidc.net localhost 208.97.167.194;
    if ($invalid_referer)
    {
      rewrite ^/ http://img.linuxidc.net/leech.gif;
      return 412;
      break;
    }
    access_log off;
    root /opt/lampp/htdocs/web;
    expires 3d;
    break;
  }


11.只允許固定ip訪問網(wǎng)站,并加上密碼
  root /opt/htdocs/www;
  allow 208.97.167.194;
  allow 222.33.1.2;
  allow 231.152.49.4;
  deny all;
  auth_basic “C1G_ADMIN”;
  auth_basic_user_file htpasswd;


12將多級目錄下的文件轉(zhuǎn)成一個文件,增強seo效果
  /job-123-456-789.html 指向/job/123/456/789.html
  rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;


13.文件和目錄不存在的時候重定向:
  if (!-e $request_filename)

   {
    proxy_pass http://127.0.0.1;
  }


14.將根目錄下某個文件夾指向2級目錄
  如/shanghaijob/ 指向 /area/shanghai/
  如果你將last改成permanent,那么瀏覽器地址欄顯是/location/shanghai/
  rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last;
  上面例子有個問題是訪問/shanghai時將不會匹配
  rewrite ^/([0-9a-z]+)job$ /area/$1/ last;
  rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last;
  這樣/shanghai 也可以訪問了,但頁面中的相對鏈接無法使用,
  如./list_1.html真實地址是/area/shanghia/list_1.html會變成/list_1.html,導(dǎo)至無法訪問。
  那我加上自動跳轉(zhuǎn)也是不行咯
  (-d $request_filename)它有個條件是必需為真實目錄,而我的rewrite不是的,所以沒有效果
  if (-d $request_filename)
  {
    rewrite ^/(.*)([^/])$ http://$host/$1$2/permanent;
  }
  知道原因后就好辦了,讓我手動跳轉(zhuǎn)吧
  rewrite ^/([0-9a-z]+)job$ /$1job/permanent;
  rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last;


15.域名跳轉(zhuǎn)
  server
  {
    listen 80;
    server_name jump.linuxidc.com;
    index index.html index.htm index.php;
    root /opt/lampp/htdocs/www;
    rewrite ^/ http://www.linuxidc.com/;
    access_log off;
  }


16.多域名轉(zhuǎn)向
  server_name www.linuxidc.com www.linuxidc.net;
  index index.html index.htm index.php;
  root /opt/lampp/htdocs;
  if ($host ~ "linuxidc\.net") {
    rewrite ^(.*) http://www.linuxidc.com$1permanent;
  }
  1. nginx正則表達式匹配
    正則匹配:
1、~ 區(qū)分大小寫匹配
2、~* 不區(qū)分大小寫匹配
3、!~和!~*分別為區(qū)分大小寫不匹配及不區(qū)分大小寫不匹配
4、^ 以什么開頭的匹配
5、$ 以什么結(jié)尾的匹配
6、.*:   .匹配任意字符,*匹配數(shù)量0到正無窮;
7、\. 斜杠用來轉(zhuǎn)義,\.匹配 .    特殊使用方法,記住記性了;
8、(值1|值2|值3|值4):或匹配模式,例:(jpg|gif|png|bmp)匹配jpg或gif或png或bmp

文件及目錄匹配:

     -f和!-f用來判斷是否存在文件
     -d和!-d用來判斷是否存在目錄
     -e和!-e用來判斷是否存在文件或目錄
     -x和!-x用來判斷文件是否可執(zhí)行

使用excemple:

location = /
#匹配任何查詢,因為所有請求都已 / 開頭。但是正則表達式規(guī)則和長的塊規(guī)則將被優(yōu)先和查詢匹配
location ^~ /images/ {
# 匹配任何已/images/開頭的任何查詢并且停止搜索。任何正則表達式將不會被測試。
location ~* .(gif|jpg|jpeg)$ {
# 匹配任何已.gif、.jpg 或 .jpeg 結(jié)尾的請求

博客標(biāo)題解決方案:

  1. 先觀察請求url
    http://www.kouyy1.com/args?arg1=yiche&arg2=click
  2. 需求:要根據(jù)arg2=后面的參數(shù)值動態(tài)分發(fā)日志
    解決思路:?后面的一長串都屬于nginx.conf內(nèi)置變量里的args,可以根據(jù)正則匹配args后面的內(nèi)容。
log_format  main  '$remote_addr  $remote_user [$time_local] "$request" '
                '$request_method $request_uri  $args  $uri' 
                           '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';     
server {
        listen       80;
        server_name  www.kouyy1.com;
    
        location / {
           proxy_pass        http://192.168.70.34:8080;  
                   proxy_set_header   Host             $host;  
                   proxy_set_header   X-Real-IP        $remote_addr;  
                   proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;  
           
           set  $log_name  "access";
           
           if ($args ~* (.*)arg2=click(.*)){
           set $log_name "click";
          }
           if ($args ~* (.*)arg2=view(.*)){
           set $log_name "view";
          }
           if ($args ~* (.*)arg2=look(.*)){
           set $log_name "look";
          }
           if ($args ~* (.*)arg2=content(.*)){
           set $log_name "content";
          }
           access_log  logs/$log_name.log  main;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
  1. 配置文件重寫之后重啟Nginx
    發(fā)出請求:
    http://www.kouyy1.com/args?arg1=yiche&arg2=click
    http://www.kouyy1.com/args?arg1=yiche&arg2=look
    http://www.kouyy1.com/args?arg1=yiche&arg2=content
    http://www.kouyy1.com/args?arg1=yiche&arg2=view
    http://www.kouyy1.com/args?arg1=yiche&arg2=hello
[centos@bogon logs]$ ll
total 124
-rw-r--r--. 1 centos centos 63768 Nov  8 19:56 access.log
-rw-r--r--. 1 centos centos  2779 Nov  7 19:15 analysis_log.py
-rw-r--r--. 1 centos centos   275 Nov  8 19:54 click.log
-rw-r--r--. 1 centos centos   281 Nov  8 19:54 content.log
-rw-r--r--. 1 centos centos 27446 Nov  8 22:08 error.log
-rw-r--r--. 1 centos centos   544 Nov  8 19:55 look.log
-rw-r--r--. 1 root   root       6 Nov  7 22:45 nginx.pid
-rw-r--r--. 1 centos centos   272 Nov  8 19:55 view.log

可以看出實現(xiàn)了日志動態(tài)分發(fā)。

參考文章

  1. https://www.cnblogs.com/czlun/articles/7010591.html
  2. https://blog.csdn.net/czlun/article/details/73251723
  3. https://www.cnblogs.com/wajika/p/6426270.html
  4. https://yq.aliyun.com/ziliao/46471?spm=a2c4e.11155472.blogcont.29.48c6323ckLnKSx
  5. https://www.cnblogs.com/xuey/p/7631690.html
  6. https://blog.csdn.net/scdxmoe/article/details/52094350
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容