配置Nginx日志url encode问题
文章目录
- 配置Nginx日志url encode问题
- 方法1-lua
- 方法2-set-misc-nginx-module
配置Nginx日志url encode问题
问题描述:
当自定义日志输出格式,需要输出http请求中url参数时,如果参数中包含中文,是会进行url encode的,所以输出都是编码后的字符串,比如我配置的:
log_format test_log escape=json '{ "timestamp": "$msec", ''"request": "$request",''"name": "$arg_name",''"uuid": "$http_uuid",''"remoteAddr": "$remote_addr" }';
请求 http://192.168.108.130:80/lua?name=我是中文
arg_name输出时就会是这样子:
{ “timestamp”: “1740829638.783”, “request”: “GET /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87”,
“uuid”: “-”,“remoteAddr”: “192.168.108.1” }
所以目的是需要把它url decode再输出
方法1-lua
首先需要安装Lua,具体可以网上找教程文章看下,这里只提及简要流程
安装lua所需模块包括:
- lua-nginx-module
- ngx_devel_kit
./configure --prefix=/usr/local/nginx \--pid-path=/var/run/nginx/nginx.pid \--lock-path=/var/lock/nginx.lock \--error-log-path=/var/log/nginx/error.log \--http-log-path=/var/log/nginx/access.log \--with-http_gzip_static_module \--http-client-body-temp-path=/var/temp/nginx/client \--http-proxy-temp-path=/var/temp/nginx/proxy \--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \--http-scgi-temp-path=/var/temp/nginx/scgi \--with-http_stub_status_module \--with-http_ssl_module \--with-file-aio \--with-http_realip_module \--with-openssl=/usr/local/software/openssl-1.1.1w \--add-module=/usr/local/software/lua-nginx-module-0.10.27rc1 \--add-module=/usr/local/software/ngx_devel_kit-0.3.3
然后 make(注意,如果无需替换原nginx目录的内容,则只需要make,不需要make install,然后编译后的objs目录里,把nginx可执行文件copy过去即可,可以先把原来nginx可执行文件备份下)
另外需要本地先安装luajit,比如我安装的 luajit2-2.1-20240626
另外有可能会报错 resty 相关的错误,网上文章有提到用 lua_load_resty_core off; 解决,但是我实际测试无效,故按照错误提示又下载了相关的包:
- lua-resty-core
- lua-resty-lrucache
nginx.conf 中添加配置:lua_package_path “/usr/local/software/lua-resty-core-0.1.29/lib/?.lua;”;
安装完成之后,可以测试下lua:
location /lua {default_type 'text/plain';content_by_lua 'ngx.say("hello, lua")';
}
之后加上我们的url解析配置:
set $decoded_arg_name '';
location /lua {default_type 'text/plain';content_by_lua 'ngx.say("hello, lua")';access_by_lua_block {local args = ngx.req.get_uri_args()if args.name thenlocal decoded_name = ngx.unescape_uri(args.name)ngx.var.decoded_arg_name = decoded_namengx.log(ngx.ERR, "Decoded name: ", decoded_name) # 打印日志调试用end}
}
完整nginx配置代码如下:
#user nobody;
worker_processes 1;#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';log_format test_log escape=json '{ "timestamp": "$msec", ''"request": "$request",''"name": "$decoded_arg_name",''"uuid": "$http_uuid",''"remoteAddr": "$remote_addr" }';#access_log logs/access.log main;access_log logs/test_access.log test_log;sendfile on;#tcp_nopush on;lua_load_resty_core off;lua_package_path "/usr/local/software/lua-resty-core-0.1.29/lib/?.lua;";#keepalive_timeout 0;keepalive_timeout 65;#gzip on;server {listen 80;server_name localhost;set $decoded_arg_name '';#charset koi8-r;charset utf-8;#access_log logs/host.access.log main;location / {root html;index index.html index.htm;} location /lua {default_type 'text/plain';content_by_lua 'ngx.say("hello, lua")';access_by_lua_block {local args = ngx.req.get_uri_args()if args.name thenlocal decoded_name = ngx.unescape_uri(args.name)ngx.var.decoded_arg_name = decoded_namengx.log(ngx.ERR, "Decoded name: ", decoded_name)end} }#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}}
}
但加上上面这一部还不够,lua的输出日志,如果是非ascii码,会输出为十六进制字符串:像是:
{ “timestamp”: “1740835690.677”, “request”: “POST /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “\xE6\x88\x91\xE6\x98\xAF\xE4\xB8\xAD\xE6\x96\x87”,“uuid”: “testuuid”,“remoteAddr”: “192.168.108.1” }
对于这个问题,偏新版的nginx可以通过加上 escape=json解决:
log_format test_log escape=json '{ "timestamp": "$msec", ''"request": "$request",''"name": "$decoded_arg_name",''"uuid": "$http_uuid",''"remoteAddr": "$remote_addr" }';
至此打印的日志则是中文了:
{ “timestamp”: “1740834963.209”, “request”: “POST /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “我是中文”,“uuid”: “testuuid”,“remoteAddr”: “192.168.108.1” }
方法2-set-misc-nginx-module
在nginx中添加此模块,下载模块包 set-misc-nginx-module-0.33 解压后,configure命令如下:
./configure --prefix=/usr/local/nginx \--pid-path=/var/run/nginx/nginx.pid \--lock-path=/var/lock/nginx.lock \--error-log-path=/var/log/nginx/error.log \--http-log-path=/var/log/nginx/access.log \--with-http_gzip_static_module \--http-client-body-temp-path=/var/temp/nginx/client \--http-proxy-temp-path=/var/temp/nginx/proxy \--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \--http-scgi-temp-path=/var/temp/nginx/scgi \--with-http_stub_status_module \--with-http_ssl_module \--with-file-aio \--with-http_realip_module \--with-openssl=/usr/local/software/openssl-1.1.1w \--add-module=/usr/local/software/lua-nginx-module-0.10.27rc1 \--add-module=/usr/local/software/ngx_devel_kit-0.3.3 \--add-module=/usr/local/software/set-misc-nginx-module-0.33
以上添加模块的lua相关的两个模块,可能可以不用加,但我测试的时候没有去掉,这里可以看大家需求
然后 make(注意,如果无需替换原nginx目录的内容,则只需要make,不需要make install,然后编译后的objs里,把nginx可执行文件copy过去即可,可以先把原来nginx可执行文件备份)
更改 nginx.conf
set $decoded_arg_name '';
set_unescape_uri $decoded_arg_name $arg_name;
再同样加上 escape=json
其他什么的都不用配置了,实现效果是一样的。
相关文章:
配置Nginx日志url encode问题
文章目录 配置Nginx日志url encode问题方法1-lua方法2-set-misc-nginx-module 配置Nginx日志url encode问题 问题描述: 当自定义日志输出格式,需要输出http请求中url参数时,如果参数中包含中文,是会进行url encode的,…...
JAVA SE 包装类和泛型
文章目录 📕1. 包装类✏️1.1 基本数据类型和对应的包装类✏️1.2 装箱和拆箱✏️1.3 自动装箱和自动拆箱 📕2. 泛型✏️2.1 泛型的语法✏️2.2 泛型类的使用✏️2.3 裸类型(Raw Type)✏️2.4 擦除机制✏️2.5 泛型的上界✏️2.6 泛型方法✏️2.7 通配符…...
基于Linux系统的物联网智能终端
背景 产品研发和项目研发有什么区别?一个令人发指的问题,刚开始工作时项目开发居多,认为项目开发和产品开发区别不大,待后来随着自身能力的提升,逐步感到要开发一个好产品还是比较难的,我认为项目开发的目的…...
从零开始开发纯血鸿蒙应用之语音朗读
从零开始开发纯血鸿蒙应用 〇、前言一、API 选型1、基本情况2、认识TextToSpeechEngine 二、功能集成实践1、改造右上角菜单2、实现语音播报功能2.1、语音引擎的获取和关闭2.2、设置待播报文本2.3、speak 目标文本2.4、设置语音回调 三、总结 〇、前言 中华汉字洋洋洒洒何其多…...
物联网小范围高精度GPS使用
在园区内实现小范围高精度GPS(全球定位系统)定位,通常需要结合多种技术来弥补传统GPS在精度和覆盖范围上的不足。以下是实现小范围高精度GPS定位的解决方案,包括技术选择、系统设计和应用场景。 一、技术选择 在园区内实现高精度…...
一次有趣的前后端跨越排查
进行前后端代码联调的时候,使用axios调用后端请求,因为都是本地进行联调,所以没有考虑跨域的问题,写了一个get的请求接口,请求后端时,突然跳出下面的问题: 错误的信息一看很像就是跨域的问题&…...
大语言模型(LLM)如何赋能时间序列分析?
引言 近年来,大语言模型(LLM)在文本生成、推理和跨模态任务中展现了惊人能力。与此同时,时间序列分析作为工业、金融、物联网等领域的核心技术,长期依赖传统统计模型(如ARIMA)或深度学习模型&a…...
Kubernetes (K8S) 核心原理深度剖析:从架构设计到运行机制
Kubernetes(K8S)作为容器编排领域的“操作系统”,其设计和实现原理是开发者进阶的必修课。本文将从架构设计、核心组件协作、关键机制实现三个维度,结合源码逻辑与实战场景,分享 K8S 的底层运行原理。 一、Kubernetes 架构设计 1. 声明式 API 与控制器模式 K8S 的核心设…...
Excel 豆知识 - XLOOKUP 为啥会出 #N/A 错误
XLOOKUP有的时候会出 #VALUE! 这个错误。 因为这个XLOOUP有个参数叫 找不到时的返回值,那么为啥还会返回 #VALUE! 呢? 可能还有别的原因,但是主要原因应该就是 检索范围 和 返回范围 不同。 比如这里检索范围在 B列,是 4-21&…...
【深度学习】Hopfield网络:模拟联想记忆
Hopfield网络是一种经典的循环神经网络,由物理学家John Hopfield在1982年提出。它的核心功能是模拟联想记忆,类似于人类大脑通过部分信息回忆完整记忆的能力。以下是通俗易懂的解释: 1. 核心思想 想象你看到一张模糊的老照片,虽然…...
Python可视化大框架的研究与应用
## 摘要 随着数据科学和人工智能的快速发展,数据可视化成为了数据分析中不可或缺的一部分。Python作为一种功能强大且易于学习的编程语言,提供了多种可视化工具和库。本文旨在探讨Python可视化的主要框架,分析其特点、应用场景以及未来发展趋…...
Java 泛型(Generics)详解与使用
一、什么是 Java 泛型? 泛型(Generics)是 Java 1.5 引入的一项重要特性,主要用于 类型参数化,允许在类、接口和方法定义时使用 类型参数(Type Parameter),从而提高代码的复用性、类…...
七、Three.jsPBR材质与纹理贴图
1、PBR材质金属度和粗糙度 1、金属度metalness 金属度属性.metalness表示材质像金属的程度, 非金属材料,如木材或石材,使用0.0,金属使用1.0。 threejs的PBR材质,.metalness默认是0.5,0.0到1.0之间的值可用于生锈的金属外观 new THREE.MeshStandardMaterial({met…...
2024 ChatGPT大模型技术场景与商业应用视频精讲合集(45课).zip
2024ChatGPT大模型技术场景与商业应用视频精讲合集,共十三章,45课。 01. 第一章 ChatGPT:通用人工智能的典范 1.1 ChatGPT概述 .mp4 1.2 通用能力 .mp4 1.3 通用人工智能风口 .mp4 02. 第二章 大模型:ChatGPT的核心支撑 2.1 底层…...
Pytest之parametrize参数化
文章目录 1.前言2.单参数3.多参数4.字典形式5.parametrize 结合 ids 参数 1.前言 在 pytest 中,parametrize 是一个非常实用的装饰器,它允许你对测试函数进行参数化,即使用不同的参数组合多次运行同一个测试函数,从而更高效地进行…...
Python面试(八股)
1. 可变对象和不可变对象 (1). 不可变对象( Immutable Objects ) 不可变对象指的是那些一旦创建后其内容就不能被修改的对象。如果尝试修改不可变对象的内容,将会创建一个新的对象而不是修改原来的对象。常见的不可变类型包括: …...
2024年第十五届蓝桥杯大赛软件赛省赛Python大学A组真题解析《更新中》
文章目录 试题A: 拼正方形(本题总分:5 分)解析答案试题B: 召唤数学精灵(本题总分:5 分)解析答案试题C: 数字诗意解析答案试题D:回文数组试题A: 拼正方形(本题总分:5 分) 【问题描述】 小蓝正在玩拼图游戏,他有7385137888721 个2 2 的方块和10470245 个1 1 的方块,他需…...
湖仓一体概述
湖仓一体之前,数据分析经历了数据库、数据仓库和数据湖分析三个时代。 首先是数据库,它是一个最基础的概念,主要负责联机事务处理,也提供基本的数据分析能力。 随着数据量的增长,出现了数据仓库,它存储的是…...
【行政区划获取】
行政区划获取 获取2023年的行政区划,并以 编码: 省市区 格式保存为字典方便后续调用 注:网址可能会更新,根据最新的来 # 获取并保存行政区划代码 import requests from lxml import etree import jsondef fetch_html(url):""&quo…...
【深入剖析:机器学习、深度学习与人工智能的关系】
深入剖析:机器学习、深度学习与人工智能的关系 在当今数字化时代,人工智能(AI)、机器学习(ML)和深度学习(DL)这些术语频繁出现在各种科技报道和讨论中,它们相互关联又各…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
