天马网络 网站建设,网络推广方案下拉管家xiala11,wordpress 定制表单,it服务商需求、日志按照天的单位进行分割存储。
如果你直接百度#xff0c;可能会搜到很多教你用各种脚本或是三方插件来按天分割的#xff0c;这边我用nginx服务本身来分割日志。
方法一
通过使用 $time_iso8601 变量和 map 指令#xff0c;实现了日志文件按天分割的功能。以下是…需求、日志按照天的单位进行分割存储。
如果你直接百度可能会搜到很多教你用各种脚本或是三方插件来按天分割的这边我用nginx服务本身来分割日志。
方法一
通过使用 $time_iso8601 变量和 map 指令实现了日志文件按天分割的功能。以下是详细的说明
1、map指令
map $time_iso8601 $logdate{~^(?ymd\d{4}-\d{2}-\d{2}) $ymd;default date-not-found;
}作用: map 指令将 $time_iso8601 变量映射为 $logdate 变量其中 $time_iso8601 是 Nginx 内置的变量表示请求的时间格式为 ISO 8601例如 2024-08-13T20:35:0608:00。 正则表达式: ~^(?ymd\d{4}-\d{2}-\d{2}) 用于从 $time_iso8601 中提取日期部分例如 2024-08-13。正则表达式中的 (?ymd\d{4}-\d{2}-\d{2}) 捕获年-月-日部分并将其赋值给变量 $ymd。 映射结果: 提取的日期部分被映射为 $logdate 变量这个变量将用于日志文件的命名。
2、日志文件存储
access_log /data/logs/access_api.json_$logdate json;
error_log /data/logs/api-error.log$logdate error;access_log: 配置了访问日志的路径并使用 $logdate 变量生成按天分割的日志文件名。日志文件的完整路径格式为 /data/logs/access_api.json_YYYY-MM-DD其中 YYYY-MM-DD 是日期。 error_log: 错误日志的路径未使用 $logdate因此错误日志不会按天分割。
3、工作流程
每当有请求到达时Nginx 会自动根据请求的时间使用 map 指令提取日期部分生成 $logdate 变量。访问日志会记录在以当前日期命名的日志文件中如 access_api.json_2024-08-06。随着日期的变化$logdate 变量会自动更新新的日志将记录到新的一天的日志文件中。
总结
通过 map 指令结合正则表达式从 $time_iso8601 中提取日期部分并使用该日期生成动态的日志文件名从而实现了日志的按天分割功能。每一天都会生成一个新的日志文件方便日后的日志分析与管理。
这里记得注意启动nginx的用户权限是否 有配置日志路径下的权限记得日志写入权限的验证。
配置文件完整示例
user app;
worker_processes 2;
events {worker_connections 30000;
}
http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;
###日志格式log_format json escapejson {timestamp:$time_iso8601,remote_addr: $remote_addr, referer: $http_referer, request: $request, status: $status, bytes: $body_bytes_sent, agent: $http_user_agent, x_forwarded: $http_x_forwarded_for, up_addr: $upstream_addr,up_host: $upstream_http_host,up_resp_time: $upstream_response_time,request_time: $request_time,request_GlobalId: $http_GlobalId,response_GlobalId: $sent_http_GlobalIdresponse_body: $resp_body,request_body: $request_body };
###日志按天分割map $time_iso8601 $logdate{~^(?ymd\d{4}-\d{2}-\d{2}) $ymd;default date-not-found;}
###charset utf-8 ;gzip on;
# 后端IP地址
upstream api-prod {server 10.66.66.88:8501 max_fails5 fail_timeout30s;server 10.66.66.66:8501 max_fails5 fail_timeout30s;
}server {listen 80 ;listen 7309 ;server_name api.xxxxxx.cn api-test.xxxxx.cn;charset utf-8 ;#日志配置lua_need_request_body on;set $resp_body ;body_filter_by_lua local resp_body string.sub(ngx.arg[1], 1, 1000)ngx.ctx.buffered (ngx.ctx.buffered or ) .. resp_bodyif ngx.arg[2] thenngx.var.resp_body ngx.ctx.bufferedend;location / {proxy_pass http://api-prod;if ($http_user_agent ~* SLBHealthCheck) {access_log off;return 200;}}access_log /data/logs/access_api.json_$logdate json;error_log /data/logs/api-error.log error;
}
}查看是否在日志文件路径下日志文件有按照天的维度来分割观察日志是按照天的维度来分割的配置完成。验证完成
-rw-r--r-- 1 app app 2 Aug 8 14:59 access_api.json_2024-06-05
-rw-r--r-- 1 app app 535976601 Aug 8 23:59 access_api.json_2024-08-08
-rw-r--r-- 1 app app 1236143585 Aug 9 23:59 access_api.json_2024-08-09
-rw-r--r-- 1 app app 499546906 Aug 10 23:59 access_api.json_2024-08-10
-rw-r--r-- 1 app app 313264627 Aug 11 23:59 access_api.json_2024-08-11
-rw-r--r-- 1 app app 675015315 Aug 12 23:59 access_api.json_2024-08-12
-rw-r--r-- 1 app app 469080433 Aug 13 23:59 access_api.json_2024-08-13
-rw-r--r-- 1 app app 174011220 Aug 14 11:47 access_api.json_2024-08-14
-rw-r--r-- 1 app app 2 Aug 8 14:59 api-error.log
[rootiZbp13xxxxxxxxxxw3yfqZ logs]# pwd
/data/logs方法二
通过使用lua脚本来实现。
1、定义一个共享字典 lua_shared_dict logs 10m;
lua_shared_dict logs 10m;: 定义了一个共享字典用于缓存日志文件句柄。这可以避免每次都重新打开日志文件从而提高性能。10m表示分配了10MB的内存用于缓存。
2、Lua脚本实现 log_by_lua_block {local cjson require cjsonlocal log_file_cache ngx.shared.logslocal today os.date(%Y-%m-%d)local log_file log_file_cache:get(today)if not log_file thenlog_file io.open(/data/logs/access_api_ .. today .. .json, a)log_file_cache:set(today, log_file)endlocal log_line cjson.encode({timestamp ngx.var.time_iso8601,remote_addr ngx.var.remote_addr,referer ngx.var.http_referer,request ngx.var.request,status ngx.var.status,bytes ngx.var.body_bytes_sent,agent ngx.var.http_user_agent,x_forwarded ngx.var.http_x_forwarded_for,up_addr ngx.var.upstream_addr,up_host ngx.var.upstream_http_host,up_resp_time ngx.var.upstream_response_time,request_time ngx.var.request_time,request_GlobalId ngx.var.http_GlobalId,response_GlobalId ngx.var.sent_http_GlobalId,response_body ngx.var.resp_body,request_body ngx.var.request_body})log_file:write(log_line .. \n)log_file:flush()}代码解释 local cjson require cjson: 通过 require 加载 Lua 的 cjson 模块用于将 Lua 表转换为 JSON 格式的字符串。这样可以把日志以 JSON 格式写入文件。 local log_file_cache ngx.shared.logs: 从共享字典 logs 中获取缓存的日志文件句柄。这可以避免每次请求都重新打开文件。 local today os.date(%Y-%m-%d): 获取当前日期并将其格式化为 YYYY-MM-DD 的字符串形式这样每天都有一个新的日志文件名。 local log_file log_file_cache:get(today): 尝试从共享字典中获取当前日期对应的日志文件句柄。 if not log_file then: 如果日志文件句柄不存在说明这是当天第一次写日志因此我们需要打开一个新的日志文件。 log_file io.open(/data/logs/access_api_ .. today .. .json, a): 使用 io.open 打开一个新的日志文件文件名包含当前日期。使用 a 模式以追加方式打开文件这样不会覆盖已有的日志内容。 log_file_cache:set(today, log_file): 将新打开的日志文件句柄缓存到共享字典中避免下次重复打开。 local log_line cjson.encode({...}): 将日志信息封装成 Lua 表并使用 cjson.encode 将其转换为 JSON 字符串。 log_file:write(log_line .. \n): 将生成的日志行写入文件并添加换行符。 log_file:flush(): 将缓冲区的内容立即写入文件以确保日志数据实时保存。
总结
权限问题: 需要确保 Nginx 对日志文件目录 /data/logs/ 有写权限。cjson 模块: 需要确认 OpenResty/Nginx 环境中已经安装了 cjson 模块。性能问题: 因为每个请求都涉及 Lua 脚本的执行所以在高流量的生产环境中性能开销需要评估。
配置文件完整示例
user app;
worker_processes 2;events {worker_connections 30000;
}http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;charset utf-8;gzip on;lua_shared_dict logs 10m; # 用于缓存日志文件句柄# 定义日志格式log_format json escapejson {timestamp:$time_iso8601,remote_addr: $remote_addr, referer: $http_referer, request: $request, status: $status, bytes: $body_bytes_sent, agent: $http_user_agent, x_forwarded: $http_x_forwarded_for, up_addr: $upstream_addr,up_host: $upstream_http_host,up_resp_time: $upstream_response_time,request_time: $request_time,request_GlobalId: $http_GlobalId,response_GlobalId: $sent_http_GlobalId,response_body: $resp_body,request_body: $request_body};# 后端IP地址upstream api-prod {server 10.66.66.86:8501 max_fails5 fail_timeout30s;server 10.66.66.88:8501 max_fails5 fail_timeout30s;}server {listen 80;listen 7309;server_name api.xxxxxx.cn api-test.xxxxxx.cn;charset utf-8;lua_need_request_body on;# 获取响应体内容set $resp_body ;body_filter_by_lua local resp_body string.sub(ngx.arg[1], 1, 1000)ngx.ctx.buffered (ngx.ctx.buffered or ) .. resp_bodyif ngx.arg[2] thenngx.var.resp_body ngx.ctx.bufferedend;# 动态生成日志文件路径并写入日志log_by_lua_block {local cjson require cjsonlocal log_file_cache ngx.shared.logslocal today os.date(%Y-%m-%d)local log_file log_file_cache:get(today)-- 仅记录非 SLB 健康检查的日志if not ngx.var.http_user_agent:match(SLBHealthCheck) thenif not log_file thenlog_file io.open(/data/logs/access_api_xxxxxx_ .. today .. .json, a)log_file_cache:set(today, log_file)endlocal log_line cjson.encode({timestamp ngx.var.time_iso8601,remote_addr ngx.var.remote_addr,referer ngx.var.http_referer,request ngx.var.request,status ngx.var.status,bytes ngx.var.body_bytes_sent,agent ngx.var.http_user_agent,x_forwarded ngx.var.http_x_forwarded_for,up_addr ngx.var.upstream_addr,up_host ngx.var.upstream_http_host,up_resp_time ngx.var.upstream_response_time,request_time ngx.var.request_time,request_GlobalId ngx.var.http_GlobalId,response_GlobalId ngx.var.sent_http_GlobalId,response_body ngx.var.resp_body,request_body ngx.var.request_body})log_file:write(log_line .. \n)log_file:flush()end}location / {proxy_pass http://api-prod;}error_log /data/logs/api-error.log error;}
}
查看是否在日志文件路径下日志文件有按照天的维度来分割观察日志是按照天的维度来分割的配置完成。验证完成.这里为了验证服务修改一下时间观察nginx是否会生成新的日志文件
[rootiZbp1axxxxxxxxp8q7ioZ logs]# sudo date 081615302024
Fri Aug 16 15:30:00 CST 2024
[rootiZbp1xxxxxxxxxq7ioZ logs]# ll
-rw-rw-rw- 1 app app 58961 Aug 13 15:30 access_api_2024-08-13.json
-rw-rw-rw- 1 app app 22945650 Aug 14 13:51 access_api_2024-08-14.json
-rw-rw-rw- 1 app app 10418 Aug 16 15:30 access_api_2024-08-16.json