NGINX 访问日志(按位置)

NGINX 访问日志(按位置)

你好,我有两个平台,其中一个作为子目录运行。我希望能够为每个应用程序提供访问和错误日​​志;但它没有按我的预期工作 :(

以下是我所拥有的:

server {
    listen 80 default;
    listen [::]:80;

    root /var/www/html/app1;
    index index.php;

    server_name localhost;

    access_log /var/log/nginx/app1.access.log;
    error_log /var/log/nginx/app1.error.log;    

    location = /favicon.ico { log_not_found off; access_log off; }
    location = /robots.txt { log_not_found off; access_log off; allow all; }
    location ~ /\.(?!well-known).* {
            deny all;
            access_log off;
            log_not_found off;
    }
    location ~*  \.(woff|jpg|jpeg|png|gif|ico|css|js)$ {
        access_log off;
        log_not_found off;
        expires 365d;
    }

    location / {
        try_files $uri $uri/ /index.php?$is_args$args;
    }   


    location /app2 {

        try_files $uri $uri/ /app2/index.php$is_args$args;

        access_log /var/log/nginx/app2.access.log;
        error_log  /var/log/nginx/app2.error.log;
    }

    # SECURITY : Deny all attempts to access PHP Files in the uploads directory
    location ~* /(?:uploads|files)/.*\.php$ {
            deny all;
    }

    # PHP : pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;    
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # Yoast SEO Sitemaps
    location ~ ([^/]*)sitemap-rewrite-disabled(.*).x(m|s)l$ {
            ## this redirects sitemap.xml to /sitemap_index.xml
        rewrite ^/sitemap.xml$ /sitemap_index.xml permanent;
            ## this makes the XML sitemaps work
            rewrite ^/([a-z]+)?-?sitemap.xsl$ /index.php?xsl=$1 last;
        rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
        rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
            ## The following lines are optional for the premium extensions
        ## News SEO
            rewrite ^/news-sitemap.xml$ /index.php?sitemap=wpseo_news last;
        ## Local SEO
        rewrite ^/locations.kml$ /index.php?sitemap=wpseo_local_kml last;
        rewrite ^/geo-sitemap.xml$ /index.php?sitemap=wpseo_local last;
        ## Video SEO
        rewrite ^/video-sitemap.xsl$ /index.php?xsl=video last;
    }
}

仅有的对 app2 主页的访问会记录在 app2 日志中,而进一步访问网站(如 /app2/help)将出现在 app1 日志中。

例子:

/help == app1.access.log && app1.error.log 确定

/app2 == app2.access.log && app2.error.log 确定

/app2/help == app1.access.log && app1.error.log *(想要出现在 app2 日志中) 不行

答案1

发生这种情况是因为最终处理您的请求的位置是location ~ \.php$,它从服务器上下文继承其日志配置。假设 yoast seo 站点地图属于 app1,您需要一个类似这样的配置:

# Use an upstream to future changes easier
upstream _php {
    server unix:/var/run/php/php7.0-fpm.sock;
}

server {
    listen 80 default;
    listen [::]:80;

    root /var/www/html/app1;
    index index.php;

    server_name localhost;

    access_log /var/log/nginx/app1.access.log;
    error_log /var/log/nginx/app1.error.log;    

    # Put php directives in the server context so they can be inherited by all locations
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    location = /favicon.ico { log_not_found off; access_log off; }
    location = /robots.txt { log_not_found off; access_log off; allow all; }

    # Locations that aren't logged can be left outside and shared
    location ~ /\.(?!well-known) {
        deny all;
        access_log off;
        log_not_found off;
    }

    location ~* \.(woff|jpg|jpeg|png|gif|ico|css|js)$ {
        access_log off;
        log_not_found off;
        expires 365d;
    }

    # Everything that logs to app1 should go in here
    location / {
        try_files $uri $uri/ /index.php?$is_args$args;

        # SECURITY : Deny all attempts to access PHP Files in the uploads directory
        location ~* /(?:uploads|files)/.*\.php$ {
            deny all;
        }

        # PHP : pass the PHP scripts to FastCGI server defined in upstream _php
        location ~ \.php$ {
            fastcgi_pass _php;
        }

        # Yoast SEO Sitemaps
        location ~ ([^/]*)sitemap-rewrite-disabled(.*).x(m|s)l$ {
                ## this redirects sitemap.xml to /sitemap_index.xml
            rewrite ^/sitemap.xml$ /sitemap_index.xml permanent;
                ## this makes the XML sitemaps work
                rewrite ^/([a-z]+)?-?sitemap.xsl$ /index.php?xsl=$1 last;
            rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
            rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
                ## The following lines are optional for the premium extensions
            ## News SEO
                rewrite ^/news-sitemap.xml$ /index.php?sitemap=wpseo_news last;
            ## Local SEO
            rewrite ^/locations.kml$ /index.php?sitemap=wpseo_local_kml last;
            rewrite ^/geo-sitemap.xml$ /index.php?sitemap=wpseo_local last;
            ## Video SEO
            rewrite ^/video-sitemap.xsl$ /index.php?xsl=video last;
        }
    }   

    # Everything that logs to app2 should go in here
    location /app2 {
        try_files $uri $uri/ /app2/index.php$is_args$args;

        access_log /var/log/nginx/app2.access.log;
        error_log  /var/log/nginx/app2.error.log;

        # SECURITY : Deny all attempts to access PHP Files in the uploads directory
        location ~* /(?:uploads|files)/.*\.php$ {
            deny all;
        }

        # PHP : pass the PHP scripts to FastCGI server defined in upstream _php
        location ~ \.php$ {
            fastcgi_pass _php;
        }
    }
}

将 fastcgi 参数移入服务器并使用 php 服务器的上游意味着不需要进行大量重复工作。

答案2

您可以尝试使用“if”进行条件记录。为每个位置设置一个地图,并在日志语句中添加“if”。

map $uri $app1 {
    ~^[app1] 1;
    default 0;
}
map $uri $app2 {
    ~^[app2]  1;
    default 0;
}

access_log /path/to/access-app1.log combined if=$app1;
access_log /path/to/access-app2.log combined if=$app2;

请注意 - 以上声明仅供参考,未经测试,可能需要进行一些语法更改。

答案3

根据NGINX 有关位置的文档

[...] 为了找到与给定请求匹配的位置,nginx 首先检查使用前缀字符串(前缀位置)定义的位置。其中,选择并记住具有最长匹配前缀的位置。然后按照正则表达式在配置文件中出现的顺序检查正则表达式。正则表达式的搜索在第一次匹配时终止,并使用相应的配置。如果没有找到与正则表达式匹配的,则使用先前记住的前缀位置的配置。

因此,如果任何带有location下方或上方正则表达式的块location /app2捕获 URL,它将被发送到默认服务器日志(或者根据您的某些选项,发送到无日志文件)。

像这样的排序工作的优先级

  • (none):如果没有修饰符,则位置将被解释为前缀匹配。这意味着给定的位置将与请求 URI 的开头进行匹配以确定匹配。
  • =:如果使用等号,则当请求 URI 与给定的位置完全匹配时,该块将被视为匹配。
  • ~:如果存在波浪号修饰符,则该位置将被解释为区分大小写的正则表达式匹配。
  • ~*:如果使用波浪号和星号修饰符,则位置块将被解释为不区分大小写的正则表达式匹配。
  • ^~:如果存在插入符号和波浪号修饰符,并且如果此块被选为最佳非正则表达式匹配,则不会进行正则表达式匹配。

为了清楚起见,我删除了一些配置。

也许您可以尝试给予 app2 优先级,使用正则表达式^~,看看会发生什么:

 server {
     listen 80 default;
     listen [::]:80;

     root /var/www/html/app1;
     index index.php;

     server_name localhost;

     access_log /var/log/nginx/app1.access.log;
     error_log /var/log/nginx/app1.error.log;

     location / {
         try_files $uri $uri/ /index.php?$is_args$args;
     }

     location ^~ /app2 {

         try_files $uri $uri/ /app2/index.php$is_args$args;

         access_log /var/log/nginx/app2.access.log;
         error_log  /var/log/nginx/app2.error.log;
     }
 }

这应该确保执行最佳匹配的非正则表达式,并将正则表达式块保留为第二个,并且不需要复制来捕获其他位置,因为它们是继承的。

答案4

=配置看起来正确。如果你不使用或, nginx 将对位置进行最长匹​​配,~因此以 包括 开头的任何内容/app2//app2/helper将匹配第二个位置并优先于location /

我无法使用您发布的相同配置重现您的问题。我猜您没有重新启动 nginx。重新加载可能还不够。

相关内容