{"id":1775,"date":"2023-03-26T22:20:05","date_gmt":"2023-03-26T14:20:05","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=1775"},"modified":"2023-04-23T21:18:50","modified_gmt":"2023-04-23T13:18:50","slug":"grafana-show-nginx-access-log-charts","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/03\/26\/grafana-show-nginx-access-log-charts\/","title":{"rendered":"Grafana\u5c55\u793a\u7cbe\u7f8e\u7684Nginx\u8bbf\u95ee\u65e5\u5fd7\u56fe\u8868"},"content":{"rendered":"<h2>ELK 7.10 \u642d\u5efa<\/h2>\n<p>ELK 7.10 \u642d\u5efa\u8bf7\u53c2\u8003\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.appblog.cn\/2021\/05\/05\/\u5bb9\u5668\u90e8\u7f72ELK7.10\uff0c\u9002\u7528\u4e8e\u751f\u4ea7\/\" title=\"\u5bb9\u5668\u90e8\u7f72ELK7.10\uff0c\u9002\u7528\u4e8e\u751f\u4ea7\">\u5bb9\u5668\u90e8\u7f72ELK7.10\uff0c\u9002\u7528\u4e8e\u751f\u4ea7<\/a><\/p>\n<h2>Grafana\u5c55\u793aNginx\u56fe\u8868<\/h2>\n<p><!-- more --><\/p>\n<p>\u6ce8\u610f\uff1a\u8bf7\u786e\u4fdd nginx \u4f7f\u7528\u8be5\u5b57\u6bb5\uff0cNginx <code>Key\u540d\u79f0<\/code>\u5982\u679c\u6709\u4fee\u6539\uff0c<code>Logstash<\/code>\u548c<code>Grafana\u6a21\u677f<\/code>\u9700\u8981\u6839\u636e\u81ea\u5df1Nginx\u5b57\u6bb5\u6765\u4fee\u6539<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.yezhou.me\/AppBlog\/images\/\u8fd0\u7ef4\/Grafana\u5c55\u793aNginx\u8bbf\u95ee\u65e5\u5fd7\u56fe\u8868_01.png\" alt=\"\" \/><br \/>\n<img decoding=\"async\" src=\"http:\/\/www.yezhou.me\/AppBlog\/images\/\u8fd0\u7ef4\/Grafana\u5c55\u793aNginx\u8bbf\u95ee\u65e5\u5fd7\u56fe\u8868_02.png\" alt=\"\" \/><br \/>\n<img decoding=\"async\" src=\"http:\/\/www.yezhou.me\/AppBlog\/images\/\u8fd0\u7ef4\/Grafana\u5c55\u793aNginx\u8bbf\u95ee\u65e5\u5fd7\u56fe\u8868_03.png\" alt=\"\" \/><\/p>\n<h2>Nginx \u65e5\u5fd7\u5b57\u6bb5\u914d\u7f6e<\/h2>\n<p>\u6ce8\u610f\uff1a\u8bf7\u786e\u4fdd nginx \u4f7f\u7528\u8be5\u5b57\u6bb5\uff0cNginx Key\u540d\u79f0\u5982\u679c\u6709\u4fee\u6539\uff0cLogstash \u548c Grafana\u6a21\u677f \u9700\u8981\u6839\u636e\u81ea\u5df1Nginx\u5b57\u6bb5\u6765\u4fee\u6539<\/p>\n<pre><code>log_format aka_logs\n    &#039;{&quot;@timestamp&quot;:&quot;$time_iso8601&quot;,&#039;\n    &#039;&quot;host&quot;:&quot;$hostname&quot;,&#039;\n    &#039;&quot;server_ip&quot;:&quot;$server_addr&quot;,&#039;\n    &#039;&quot;client_ip&quot;:&quot;$remote_addr&quot;,&#039;\n    &#039;&quot;xff&quot;:&quot;$http_x_forwarded_for&quot;,&#039;\n    &#039;&quot;domain&quot;:&quot;$host&quot;,&#039;\n    &#039;&quot;url&quot;:&quot;$uri&quot;,&#039;\n    &#039;&quot;referer&quot;:&quot;$http_referer&quot;,&#039;\n    &#039;&quot;args&quot;:&quot;$args&quot;,&#039;\n    &#039;&quot;upstreamtime&quot;:&quot;$upstream_response_time&quot;,&#039;\n    &#039;&quot;responsetime&quot;:&quot;$request_time&quot;,&#039;\n    &#039;&quot;request_method&quot;:&quot;$request_method&quot;,&#039;\n    &#039;&quot;status&quot;:&quot;$status&quot;,&#039;\n    &#039;&quot;size&quot;:&quot;$body_bytes_sent&quot;,&#039;\n    &#039;&quot;request_body&quot;:&quot;$request_body&quot;,&#039;\n    &#039;&quot;request_length&quot;:&quot;$request_length&quot;,&#039;\n    &#039;&quot;protocol&quot;:&quot;$server_protocol&quot;,&#039;\n    &#039;&quot;upstreamhost&quot;:&quot;$upstream_addr&quot;,&#039;\n    &#039;&quot;file_dir&quot;:&quot;$request_filename&quot;,&#039;\n    &#039;&quot;http_user_agent&quot;:&quot;$http_user_agent&quot;&#039;\n  &#039;}&#039;;<\/code><\/pre>\n<h2>Filebeat \u914d\u7f6e<\/h2>\n<blockquote>\n<p>Filebeat Version 7.10<\/p>\n<\/blockquote>\n<pre><code class=\"language-yml\">#=========================== Filebeat inputs =============================\nfilebeat.inputs:                   # inputs\u4e3a\u590d\u6570\uff0c\u8868\u540dtype\u53ef\u4ee5\u6709\u591a\u4e2a\n- type: log                        # \u8f93\u5165\u7c7b\u578b\n  access:\n  enabled: true                    # \u542f\u7528\u8fd9\u4e2atype\u914d\u7f6e\n  # \u65e5\u5fd7\u662fjson\u5f00\u542f\u8fd9\u4e2a\n  json.keys_under_root: true       # \u9ed8\u8ba4\u8fd9\u4e2a\u503c\u662fFALSE\u7684\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u7684json\u65e5\u5fd7\u89e3\u6790\u540e\u4f1a\u88ab\u653e\u5728json\u952e\u4e0a\u3002\u8bbe\u4e3aTRUE\uff0c\u6240\u6709\u7684keys\u5c31\u4f1a\u88ab\u653e\u5230\u6839\u8282\u70b9\n  json.overwrite_keys: true        # \u662f\u5426\u8981\u8986\u76d6\u539f\u6709\u7684key\uff0c\u8fd9\u662f\u5173\u952e\u914d\u7f6e\uff0c\u5c06keys_under_root\u8bbe\u4e3aTRUE\u540e\uff0c\u518d\u5c06overwrite_keys\u4e5f\u8bbe\u4e3aTRUE\uff0c\u5c31\u80fd\u628afilebeat\u9ed8\u8ba4\u7684key\u503c\u7ed9\u8986\u76d6\n  max_bytes: 20480                 # \u5355\u6761\u65e5\u5fd7\u7684\u5927\u5c0f\u9650\u5236,\u5efa\u8bae\u9650\u5236(\u9ed8\u8ba4\u4e3a10M,queue.mem.events * max_bytes \u5c06\u662f\u5360\u6709\u5185\u5b58\u7684\u4e00\u90e8\u5206)\n  paths:\n    - \/var\/log\/nginx\/access.log    # \u76d1\u63a7nginx \u7684access\u65e5\u5fd7\n\n  fields:                          # \u989d\u5916\u7684\u5b57\u6bb5\n    source: nginx-access           # \u81ea\u5b9a\u4e49source\u5b57\u6bb5\uff0c\u7528\u4e8ees\u5efa\u8bae\u7d22\u5f15\uff08\u5b57\u6bb5\u540d\u5c0f\u5199\uff0c\u6211\u8bb0\u5f97\u5927\u5199\u597d\u50cf\u4e0d\u884c\uff09\n\n# \u81ea\u5b9a\u4e49es\u7684\u7d22\u5f15\u9700\u8981\u628ailm\u8bbe\u7f6e\u4e3afalse\nsetup.ilm.enabled: false\n\n#-------------------------- Kafka output ------------------------------\noutput.kafka:            # \u8f93\u51fa\u5230kafka\n  enabled: true          # \u8be5output\u914d\u7f6e\u662f\u5426\u542f\u7528\n  hosts: [&quot;host1:9092&quot;, &quot;host2:9092&quot;, &quot;host3:9092&quot;]  # kafka\u8282\u70b9\u5217\u8868\n  topic: &quot;elk-%{[fields.source]}&quot;   # kafka\u4f1a\u521b\u5efa\u8be5topic\uff0c\u7136\u540elogstash(\u53ef\u4ee5\u8fc7\u6ee4\u4fee\u6539)\u4f1a\u4f20\u7ed9es\u4f5c\u4e3a\u7d22\u5f15\u540d\u79f0\n  partition.hash:\n    reachable_only: true # \u662f\u5426\u53ea\u53d1\u5f80\u53ef\u8fbe\u5206\u533a\n  compression: gzip      # \u538b\u7f29\n  max_message_bytes: 1000000  # Event\u6700\u5927\u5b57\u8282\u6570\u3002\u9ed8\u8ba41000000\u3002\u5e94\u5c0f\u4e8e\u7b49\u4e8ekafka broker message.max.bytes\u503c\n  required_acks: 1  # kafka ack\u7b49\u7ea7\n  worker: 1  # kafka output\u7684\u6700\u5927\u5e76\u53d1\u6570\n  bulk_max_size: 2048    # \u5355\u6b21\u53d1\u5f80kafka\u7684\u6700\u5927\u4e8b\u4ef6\u6570\nlogging.to_files: true   # \u8f93\u51fa\u6240\u6709\u65e5\u5fd7\u5230file\uff0c\u9ed8\u8ba4true\uff0c \u8fbe\u5230\u65e5\u5fd7\u6587\u4ef6\u5927\u5c0f\u9650\u5236\u65f6\uff0c\u65e5\u5fd7\u6587\u4ef6\u4f1a\u81ea\u52a8\u9650\u5236\u66ff\u6362\uff0c\u8be6\u7ec6\u914d\u7f6e\uff1ahttps:\/\/www.cnblogs.com\/qinwengang\/p\/10982424.html\nclose_older: 30m         # \u5982\u679c\u4e00\u4e2a\u6587\u4ef6\u5728\u67d0\u4e2a\u65f6\u95f4\u6bb5\u5185\u6ca1\u6709\u53d1\u751f\u8fc7\u66f4\u65b0\uff0c\u5219\u5173\u95ed\u76d1\u63a7\u7684\u6587\u4ef6handle\u3002\u9ed8\u8ba41h\nforce_close_files: false # \u8fd9\u4e2a\u9009\u9879\u5173\u95ed\u4e00\u4e2a\u6587\u4ef6,\u5f53\u6587\u4ef6\u540d\u79f0\u7684\u53d8\u5316\u3002\u53ea\u5728window\u5efa\u8bae\u4e3atrue\n\n# \u6ca1\u6709\u65b0\u65e5\u5fd7\u91c7\u96c6\u540e\u591a\u957f\u65f6\u95f4\u5173\u95ed\u6587\u4ef6\u53e5\u67c4\uff0c\u9ed8\u8ba45\u5206\u949f\uff0c\u8bbe\u7f6e\u62101\u5206\u949f\uff0c\u52a0\u5feb\u6587\u4ef6\u53e5\u67c4\u5173\u95ed\nclose_inactive: 1m\n\n# \u4f20\u8f93\u4e863h\u540e\u6ca1\u6709\u4f20\u8f93\u5b8c\u6210\u7684\u8bdd\u5c31\u5f3a\u884c\u5173\u95ed\u6587\u4ef6\u53e5\u67c4\uff0c\u8fd9\u4e2a\u914d\u7f6e\u9879\u662f\u89e3\u51b3\u4ee5\u4e0a\u6848\u4f8b\u95ee\u9898\u7684key point\nclose_timeout: 3h\n\n# \u8fd9\u4e2a\u914d\u7f6e\u9879\u4e5f\u5e94\u8be5\u914d\u7f6e\u4e0a\uff0c\u9ed8\u8ba4\u503c\u662f0\u8868\u793a\u4e0d\u6e05\u7406\uff0c\u4e0d\u6e05\u7406\u7684\u610f\u601d\u662f\u91c7\u96c6\u8fc7\u7684\u6587\u4ef6\u63cf\u8ff0\u5728registry\u6587\u4ef6\u91cc\u6c38\u4e0d\u6e05\u7406\uff0c\u5728\u8fd0\u884c\u4e00\u6bb5\u65f6\u95f4\u540e\uff0cregistry\u4f1a\u53d8\u5927\uff0c\u53ef\u80fd\u4f1a\u5e26\u6765\u95ee\u9898\nclean_inactive: 72h\n\n# \u8bbe\u7f6e\u4e86clean_inactive\u540e\u5c31\u9700\u8981\u8bbe\u7f6eignore_older\uff0c\u4e14\u8981\u4fdd\u8bc1ignore_older &lt; clean_inactive\nignore_older: 70h\n\n# \u9650\u5236 CPU\u548c\u5185\u5b58\u8d44\u6e90\nmax_procs: 1 # \u9650\u5236\u4e00\u4e2aCPU\u6838\u5fc3,\u907f\u514d\u8fc7\u591a\u62a2\u5360\u4e1a\u52a1\u8d44\u6e90\nqueue.mem.events: 256 # \u5b58\u50a8\u4e8e\u5185\u5b58\u961f\u5217\u7684\u4e8b\u4ef6\u6570\uff0c\u6392\u961f\u53d1\u9001 (\u9ed8\u8ba44096)\nqueue.mem.flush.min_events: 128 # \u5c0f\u4e8e queue.mem.events ,\u589e\u52a0\u6b64\u503c\u53ef\u63d0\u9ad8\u541e\u5410\u91cf (\u9ed8\u8ba4\u503c2048)<\/code><\/pre>\n<h2>Logstash \u914d\u7f6e<\/h2>\n<blockquote>\n<p>Logstash Version 7.10<\/p>\n<\/blockquote>\n<pre><code class=\"language-bash\">$ vim 01-input.conf\n\ninput {                                        # \u8f93\u5165\u7ec4\u4ef6\n    kafka {                                    # \u4ecekafka\u6d88\u8d39\u6570\u636e\n        bootstrap_servers =&gt; [&quot;host1:9092,host2:9092,host3:9092&quot;]\n        #topics =&gt; &quot;%{[@metadata][topic]}&quot;     # \u4f7f\u7528kafka\u4f20\u8fc7\u6765\u7684topic\n        topics_pattern =&gt; &quot;elk-.*&quot;             # \u4f7f\u7528\u6b63\u5219\u5339\u914dtopic\n        codec =&gt; &quot;json&quot;                        # \u6570\u636e\u683c\u5f0f\n        consumer_threads =&gt; 3                  # \u6d88\u8d39\u7ebf\u7a0b\u6570\u91cf\n        decorate_events =&gt; true                # \u53ef\u5411\u4e8b\u4ef6\u6dfb\u52a0Kafka\u5143\u6570\u636e\uff0c\u6bd4\u5982\u4e3b\u9898\u3001\u6d88\u606f\u5927\u5c0f\u7684\u9009\u9879\uff0c\u8fd9\u5c06\u5411logstash\u4e8b\u4ef6\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u540d\u4e3akafka\u7684\u5b57\u6bb5\n        auto_offset_reset =&gt; &quot;latest&quot;          # \u81ea\u52a8\u91cd\u7f6e\u504f\u79fb\u91cf\u5230\u6700\u65b0\u7684\u504f\u79fb\u91cf\n        group_id =&gt; &quot;logstash-groups1&quot;         # \u6d88\u8d39\u7ec4ID\uff0c\u591a\u4e2a\u6709\u76f8\u540cgroup_id\u7684logstash\u5b9e\u4f8b\u4e3a\u4e00\u4e2a\u6d88\u8d39\u7ec4\n        client_id =&gt; &quot;logstash1&quot;               # \u5ba2\u6237\u7aefID\n        fetch_max_wait_ms =&gt; &quot;1000&quot;            # \u6307\u5f53\u6ca1\u6709\u8db3\u591f\u7684\u6570\u636e\u7acb\u5373\u6ee1\u8db3fetch_min_bytes\u65f6\uff0c\u670d\u52a1\u5668\u5728\u56de\u7b54fetch\u8bf7\u6c42\u4e4b\u524d\u5c06\u963b\u585e\u7684\u6700\u957f\u65f6\u95f4\n  }\n}\n\n$ vim 02-output.conf\n\noutput {                                       # \u8f93\u51fa\u7ec4\u4ef6\n    elasticsearch {\n        # Logstash\u8f93\u51fa\u5230es\n        hosts =&gt; [&quot;host1:9200&quot;, &quot;host2:9200&quot;, &quot;host3:9200&quot;]\n        index =&gt; &quot;%{[fields][source]}-%{+YYYY-MM-dd}&quot;      # \u76f4\u63a5\u5728\u65e5\u5fd7\u4e2d\u5339\u914d\uff0c\u7d22\u5f15\u4f1a\u53bb\u6389elk\n        user =&gt; &quot;elastic&quot;\n        password =&gt; &quot;xxxxxx&quot;\n    }\n    #stdout {\n    #    codec =&gt; rubydebug\n    #}\n}\n\n$ vim 03-filter.conf\n\nfilter {\n   # \u56e0\u4e3aNginx\u524d\u7aef\u6709\u8d1f\u8f7d\u5747\u8861\uff0c$remote_addr \u5b57\u6bb5\u4e0d\u662f\u7528\u6237\u771f\u5b9eip\u5730\u5740\n   # \u672c\u4f8b\u83b7\u53d6 $http_x_forwarded_for \u5b57\u6bb5\uff0c$http_x_forwarded_for \u5b57\u6bb5\u7b2c\u4e00\u4e2aip\u5730\u5740\u5c31\u662f\u7528\u6237\u771f\u5b9eip\u5730\u5740\n   # \u518dnginx\u5b57\u6bb5\u57fa\u7840\u4e0a\u6dfb\u52a0 real_remote_addr \u5b57\u6bb5\uff0c\u7528\u4e8e\u5b58\u50a8\u7528\u6237\u771f\u5b9eip\u5730\u5740\n   if ([fields][source] =~ &quot;nginx-access&quot;) {\n     if &quot;,&quot; in [xff] {\n        mutate {\n          split =&gt; [&quot;xff&quot;, &quot;,&quot;]\n          add_field =&gt; { &quot;real_remote_addr&quot; =&gt; &quot;%{[xff][0]}&quot; }\n        }\n     } else if ([xff] == &quot;-&quot;) {\n        mutate {\n          add_field =&gt; { &quot;real_remote_addr&quot; =&gt; &quot;-&quot; }\n        }\n     } else {\n        mutate {\n          add_field =&gt; { &quot;real_remote_addr&quot; =&gt; &quot;%{xff}&quot; }\n        }\n     }\n\n     geoip {\n       target =&gt; &quot;geoip&quot;\n       source =&gt; &quot;real_remote_addr&quot;\n       database =&gt; &quot;\/usr\/share\/logstash\/data\/GeoLite2-City\/GeoLite2-City.mmdb&quot;\n       add_field =&gt; [ &quot;[geoip][coordinates]&quot;, &quot;%{[geoip][longitude]}&quot; ]\n       add_field =&gt; [ &quot;[geoip][coordinates]&quot;, &quot;%{[geoip][latitude]}&quot; ]\n       # \u53bb\u6389\u663e\u793a geoip \u663e\u793a\u7684\u591a\u4f59\u4fe1\u606f\n       remove_field =&gt; [&quot;[geoip][latitude]&quot;, &quot;[geoip][longitude]&quot;, &quot;[geoip][country_code]&quot;, &quot;[geoip][country_code2]&quot;, &quot;[geoip][country_code3]&quot;, &quot;[geoip][timezone]&quot;, &quot;[geoip][continent_code]&quot;, &quot;[geoip][region_code]&quot;]\n     }\n\n     mutate {\n       convert =&gt; {\n         &quot;[size]&quot; =&gt; &quot;integer&quot;\n         &quot;[status]&quot; =&gt; &quot;integer&quot;\n         &quot;[responsetime]&quot; =&gt; &quot;float&quot;\n         &quot;[upstreamtime]&quot; =&gt; &quot;float&quot;\n         &quot;[geoip][coordinates]&quot; =&gt; &quot;float&quot;\n       }\n     }\n\n     # \u6839\u636ehttp_user_agent\u6765\u81ea\u52a8\u5904\u7406\u533a\u5206\u7528\u6237\u5ba2\u6237\u7aef\u7cfb\u7edf\u4e0e\u7248\u672c\n     useragent {\n       source =&gt; &quot;http_user_agent&quot;\n       target =&gt; &quot;ua&quot;\n       # \u8fc7\u6ee4useragent\u6ca1\u7528\u7684\u5b57\u6bb5\n       remove_field =&gt; [ &quot;[ua][minor]&quot;,&quot;[ua][major]&quot;,&quot;[ua][build]&quot;,&quot;[ua][patch]&quot;,&quot;[ua][os_minor]&quot;,&quot;[ua][os_major]&quot; ]\n     }\n   }\n}<\/code><\/pre>\n<h2>Grafana Nginx \u56fe\u8868<\/h2>\n<p>\u6ce8\u610f\uff1a\u5982\u679c<code>Logstash<\/code>\u914d\u7f6e\u6309\u7167\u672c\u6587\u6765\u914d\uff0c\u9700\u8981 Grafana \u56fe\u8868\u4e2d<code>client_ip<\/code>\u5b57\u6bb5\u66ff\u6362\u4e3a<code>real_remote_addr<\/code>\u5b57\u6bb5\u3002<\/p>\n<p>Grafana Nginx \u56fe\u8868\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/grafana.com\/grafana\/dashboards\/11190\">https:\/\/grafana.com\/grafana\/dashboards\/11190<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>ELK 7.10 \u642d\u5efa ELK 7.10 \u642d\u5efa\u8bf7\u53c2\u8003\uff1a\u5bb9\u5668\u90e8\u7f72ELK7.10\uff0c\u9002\u7528\u4e8e\u751f\u4ea7 Grafana\u5c55\u793aN [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[332,386],"tags":[385,25],"class_list":["post-1775","post","type-post","status-publish","format-standard","hentry","category-nginx","category-monitor","tag-grafana","tag-nginx"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1775"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1775\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}