ค้นหาเว็บไซต์

วิธีกำหนดค่าการเข้าถึงแบบกำหนดเองและรูปแบบบันทึกข้อผิดพลาดใน Nginx


เซิร์ฟเวอร์ Nginx HTTP มีระบบบันทึกข้อมูลที่ยอดเยี่ยมซึ่งสามารถปรับแต่งได้สูง ในบทความนี้ เราจะอธิบายวิธีกำหนดค่ารูปแบบของคุณสำหรับการเข้าถึงและบันทึกข้อผิดพลาดสำหรับ Nginx ใน Linux

จุดมุ่งหมายของคู่มือนี้คือเพื่อช่วยให้คุณเข้าใจวิธีการสร้างบันทึก เพื่อกำหนดค่ารูปแบบบันทึกที่กำหนดเองเพื่อวัตถุประสงค์ในการแก้ไขจุดบกพร่อง การแก้ไขปัญหา หรือการวิเคราะห์สิ่งที่เกิดขึ้นภายในเว็บเซิร์ฟเวอร์ของคุณตลอดจนเว็บแอปพลิเคชัน (เช่น คำขอติดตาม)

อ่านเพิ่มเติม: 4 เครื่องมือตรวจสอบและจัดการบันทึกโอเพ่นซอร์สที่ดีสำหรับ Linux

บทความนี้ประกอบด้วยสามส่วนซึ่งจะให้ความกระจ่างแก่คุณเกี่ยวกับการกำหนดค่า บันทึกการเข้าถึง/ข้อผิดพลาด และวิธีการเปิดใช้งานการบันทึกแบบมีเงื่อนไขใน Nginx

การกำหนดค่าบันทึกการเข้าถึงใน Nginx

ภายใต้ Nginx คำขอของไคลเอ็นต์ทั้งหมดไปยังเซิร์ฟเวอร์จะถูกบันทึกใหม่ใน บันทึกการเข้าถึง ในรูปแบบที่ระบุโดยใช้โมดูล ngx_http_log_module

ไฟล์บันทึกเริ่มต้นคือ log/access.log (โดยปกติคือ /var/log/nginx/access_log บนระบบ Linux) และรูปแบบเริ่มต้นสำหรับการบันทึกโดยปกติจะเป็นแบบรวมหรือแบบหลัก รูปแบบ (ซึ่งอาจแตกต่างกันไปในแต่ละ distro)

คำสั่ง access_log (ใช้ได้กับ http, เซิร์ฟเวอร์, ตำแหน่ง, หากอยู่ในตำแหน่งและขีดจำกัดยกเว้นบริบท) ใช้เพื่อตั้งค่าไฟล์บันทึกและคำสั่ง log_format (ใช้ได้ภายใต้ http บริบทเท่านั้น) ใช้เพื่อตั้งค่ารูปแบบบันทึก รูปแบบบันทึกอธิบายโดยตัวแปรทั่วไป และตัวแปรที่สร้างขึ้นในเวลาที่มีการเขียนบันทึกเท่านั้น

ไวยากรณ์สำหรับการกำหนดค่ารูปแบบบันทึกคือ:

log_format format_name 'set_of_variables_to_define_format';

และไวยากรณ์สำหรับการกำหนดค่าบันทึกการเข้าถึงคือ:

access_log /path/to/log_file format_name;		#simplest form 
OR
access_log /path/to/log_file [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

ต่อไปนี้เป็นข้อความที่ตัดตอนมาจากไฟล์การกำหนดค่า Nginx เริ่มต้น /etc/nginx/nginx.conf บน CentOS 7

http {
	#main log format 
	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 /var/log/nginx/access.log;
}

รูปแบบบันทึกนี้ให้ผลรายการบันทึกต่อไปนี้

127.0.0.1 - dbmanager [20/Nov/2017:18:52:17 +0000] "GET / HTTP/1.1" 401 188 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"

ต่อไปนี้เป็นรูปแบบการบันทึกที่มีประโยชน์อีกรูปแบบหนึ่งที่เราใช้ในการติดตามคำขอไปยังเว็บแอปพลิเคชันของเราโดยใช้ตัวแปรเริ่มต้นบางตัว ที่สำคัญที่สุดคือมีรหัสคำขอและบันทึกรายละเอียดตำแหน่งไคลเอนต์ (ประเทศ รหัสประเทศ ภูมิภาค และเมือง)

log_format  custom '$remote_addr - $remote_user [$time_local] '
                         	     '"$request" $status $body_bytes_sent '
                      		     '"$http_referer" "$http_user_agent" '
                     		     '"$http_x_forwarded_for" $request_id '
                   		     '$geoip_country_name $geoip_country_code '
                  		     '$geoip_region_name $geoip_city ';

คุณสามารถใช้มันเช่นนี้:

access_log  /var/log/nginx/access.log custom;

สิ่งนี้จะสร้างรายการบันทึกซึ่งปรากฏเช่นนี้

153.78.107.192 - - [21/Nov/2017:08:45:45 +0000] "POST /ngx_pagespeed_beacon?url=https%3A%2F%2Fwww.example.com%2Fads%2Ffresh-oranges-1509260795 HTTP/2.0" 204 0 "https://www.suasell.com/ads/fresh-oranges-1509260795" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0" "-" a02b2dea9cf06344a25611c1d7ad72db Uganda UG Kampala Kampala 

คุณสามารถระบุบันทึกได้หลายรายการโดยใช้คำสั่ง access_log ในระดับเดียวกัน ในที่นี้เราใช้ไฟล์บันทึกมากกว่าหนึ่งไฟล์ในบริบท http

http{
	##default log format
	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                	      '$status $body_bytes_sent "$http_referer" '
                                         '"$http_user_agent" "$http_x_forwarded_for"';
      
	##request tracing using custom format
	log_format custom '$remote_addr - $remote_user [$time_local] '
                                           '"$request" $status $body_bytes_sent '
                                           '"$http_referer" "$http_user_agent" '
                                           '"$http_x_forwarded_for" $request_id '
                                           '$geoip_country_name $geoip_country_code '
                                          '$geoip_region_name $geoip_city ';

	##this uses the default log format
	access_log /var/log/nginx/access.log;

	##this uses the our custom log format
	access_log /var/log/nginx/custom_log custom;
}

ต่อไปนี้คือตัวอย่างการกำหนดค่าการบันทึกขั้นสูง ซึ่งมีประโยชน์สำหรับรูปแบบบันทึกที่มีตัวแปรที่เกี่ยวข้องกับการบีบอัด และสำหรับการสร้างไฟล์บันทึกที่ถูกบีบอัด:

access_log /var/log/nginx/custom_log custom buffer 32k;
access_log /path/to/log.gz compression  gzip  flush=5m;

การกำหนดค่าบันทึกข้อผิดพลาดใน Nginx

ในกรณีที่ Nginx พบข้อผิดพลาด ระบบจะบันทึกข้อมูลที่เกี่ยวข้องกับข้อผิดพลาดดังกล่าวในบันทึกข้อผิดพลาด ปัญหาเหล่านี้อยู่ภายใต้ระดับความรุนแรงที่แตกต่างกัน: แก้ไขข้อบกพร่อง, ข้อมูล, ประกาศ, เตือน, ข้อผิดพลาด (นี่คือระดับเริ่มต้นและใช้งานได้ทั่วโลก), คริติคอล, การแจ้งเตือน หรือ อุบัติใหม่

ไฟล์บันทึกเริ่มต้นคือ log/error.log แต่โดยปกติจะอยู่ใน /var/log/nginx/ บน Linux คำสั่ง error_log ใช้เพื่อระบุไฟล์บันทึก และสามารถใช้ได้ในบริบทหลัก, http, เมล, สตรีม, เซิร์ฟเวอร์, ตำแหน่งที่ตั้ง (ตามลำดับ)

คุณควรทราบด้วยว่า:

  • การกำหนดค่าในบริบทหลักจะสืบทอดตามระดับที่ต่ำกว่าตามลำดับด้านบนเสมอ
  • และการกำหนดค่าในระดับที่ต่ำกว่าจะแทนที่การกำหนดค่าที่สืบทอดมาจากระดับที่สูงกว่า

คุณสามารถกำหนดค่าการบันทึกข้อผิดพลาดได้โดยใช้ไวยากรณ์ต่อไปนี้:

error_log /path/to/log_file log_level;

ตัวอย่างเช่น:

error_log /var/log/nginx/error_log warn; 

วิธีนี้จะสั่งให้ Nginx บันทึกข้อความทั้งหมดประเภท คำเตือน และระดับการบันทึกที่รุนแรงยิ่งขึ้น คริติคอล, การแจ้งเตือน และ อุบัติใหม่ ข้อความ

ในตัวอย่างถัดไป ข้อความระดับ วิกฤติ, การแจ้งเตือน และ ฉุกเฉิน จะถูกบันทึก

error_log /var/www/example1.com/log/error_log crit;

พิจารณาการกำหนดค่าด้านล่างนี้ เราได้กำหนดการบันทึกข้อผิดพลาดในระดับต่างๆ (ในบริบทของ http และเซิร์ฟเวอร์) ในกรณีที่เกิดข้อผิดพลาด ข้อความจะถูกเขียนลงในบันทึกข้อผิดพลาดเพียงรายการเดียว ซึ่งเป็นรายการที่อยู่ใกล้กับระดับที่เกิดข้อผิดพลาดมากที่สุด

http {
	log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';
	
	error_log  /var/log/nginx/error_log  crit;

    	server {
		listen 80;
		server_name example1.com;

		#this logs errors messages for example1.com only
      		error_log  /var/log/nginx/example1.error_log  warn;
            	…...
	}

     	server {
		listen 80;
		server_name  example2.com;

		#this logs errors messages for example2.com only
        		error_log  /var/log/nginx/example1.error_log;
        		…….
    	}
}

หากคุณใช้คำสั่ง error_log มากกว่าหนึ่งคำสั่งเช่นเดียวกับในการกำหนดค่าด้านล่าง (ระดับเดียวกัน) ข้อความจะถูกเขียนลงในบันทึกที่ระบุทั้งหมด

server {
		listen 80;
		server_name example1.com;

      		error_log  /var/www/example1.com/log/error_log  warn;
		error_log  /var/log/nginx/example1.error_log  crit;
            	…...
	}

การกำหนดค่าการบันทึกแบบมีเงื่อนไขใน Nginx

ในบางกรณี เราอาจต้องการให้ Nginx ทำการบันทึกข้อความแบบมีเงื่อนไข ไม่ใช่ทุกข้อความที่จะต้องถูกบันทึกโดย Nginx ดังนั้นเราจึงสามารถเพิกเฉยต่อรายการบันทึกที่ไม่มีนัยสำคัญหรือสำคัญน้อยกว่าจากบันทึกการเข้าถึงของเราสำหรับบางกรณีได้

เราสามารถใช้โมดูล ngx_http_map_module ซึ่งสร้างตัวแปรที่มีค่าขึ้นอยู่กับค่าของตัวแปรอื่นๆ พารามิเตอร์ภายในบล็อกแผนที่ (ซึ่งควรมีอยู่ในเนื้อหา http เท่านั้น) ระบุการจับคู่ระหว่างแหล่งที่มาและค่าผลลัพธ์

สำหรับการตั้งค่าประเภทนี้ คำขอจะไม่ถูกบันทึกหากเงื่อนไขประเมินเป็น “0 ” หรือสตริงว่าง ตัวอย่างนี้ไม่รวมคำขอที่มีรหัสสถานะ HTTP 2xx และ 3xx

http{
	map $status $condition {
		~^[23] 0;
    		default 1;
	}
	server{
		access_log  /path/to/access.log  custom if=$condition;
	}
}

นี่เป็นอีกตัวอย่างที่เป็นประโยชน์สำหรับการดีบักเว็บแอปพลิเคชันในขั้นตอนการพัฒนา การดำเนินการนี้จะละเว้นข้อความทั้งหมดและบันทึกเฉพาะข้อมูลการแก้ไขข้อบกพร่องเท่านั้น

 
http{
	map $info  $debuggable { 
    		default     0; 
    		debug       1; 
	} 
	server{
		……..
		access_log /var/log/nginx/testapp_debug_access_log  debug if=$debuggable; 
		#logs other requests 
		access_log  /var/log/nginx/testapp_access.log  main; 
		…….
	}
}

คุณสามารถค้นหาข้อมูลเพิ่มเติม รวมถึงการบันทึกไปยัง syslog ที่นี่

นั่นคือทั้งหมดที่สำหรับตอนนี้! ในคู่มือนี้ เราได้อธิบายวิธีกำหนดค่ารูปแบบการบันทึกแบบกำหนดเองสำหรับการเข้าถึงและบันทึกข้อผิดพลาดใน Nginx ใช้แบบฟอร์มคำติชมด้านล่างเพื่อถามคำถามหรือแบ่งปันความคิดเห็นเกี่ยวกับบทความนี้