
后端网络云原生【免费下载链接】corednsCoreDNS is a DNS server that chains plugins项目地址https://gitcode.com/gh_mirrors/co/coredns点击查看免费下载导读log是 CoreDNS 内置的请求access日志插件负责把进入 CoreDNS 的每一个 DNS 查询及其响应摘要输出到标准输出stdout。本文以 plugin/log/README.md 为主体结合 plugin/log/log.go、plugin/log/setup.go 等源码完整讲解它的语法、响应类别class过滤、全部占位符placeholder、自定义日志格式、JSON 输出模式以及它注入的{/log/class}、{/log/type}元数据帮助你在生产环境中精准、低噪地记录 DNS 访问日志。插件概述与适用场景log插件启用后会将所有查询以及应答的相关部分输出到标准输出。默认输出为 Common Log Format通用日志格式并可通过 Corefile 指令微调输出内容。需要明确两点边界log插件只控制查询日志query loggingCoreDNS 自身的其他日志启动信息、插件加载、错误日志等不受其开关影响无论是否启用本插件都会照常输出。对于繁忙的 DNS 服务器逐条记录查询日志会带来明显的性能开销每条请求都要格式化字符串并写日志文档明确提示这一点生产环境应结合class过滤或按需采样使用。插件在插件链中的位置与机制log注册后作为一个普通 Handler 包裹后续插件见 plugin/log/setup.go 中的AddPlugin在ServeDNS中先匹配规则再通过dnstest.NewRecorder记录下游插件的应答最后按格式输出见 plugin/log/log.go 的Logger.ServeDNS。语法与配置指令无参数形式log不带任何参数时对所有请求以 Common Log Format 输出一条查询日志到 stdout。从源码看plugin/log/setup.go 的logParse此时默认规则为NameScope为.匹配所有区域、Format为DefaultLogFormat、类别为all。带名称与格式的形式log [NAMES...] [FORMAT]NAMES要匹配并记录日志的域名列表支持多个域名同时给出未指定时默认作用域为.。FORMAT日志格式默认是 Common Log Format{common}是 Common Log Format 的快捷写法{combined}则在 Common Log Format 基础上追加查询 opcode{opcode}。解析细节源码logParse中若最后一个参数包含{则被识别为格式串支持{common}、{combined}快捷展开见 plugin/log/setup.go其余参数全部作为域名作用域例如log example.org example.net {host}会生成两条规则各自使用{host}格式。每个名称会通过dns.Fqdn规范化为带尾点的 FQDN。响应类别过滤log [NAMES...] [FORMAT] { class CLASSES... }CLASSES以空格分隔的响应类别列表只记录匹配类别的响应。在 Corefile 中可以写多条class语句它们之间是**或OR**关系源码将多条class参数合并进同一个 mapplugin/log/setup.go 中classes[cls] struct{}{}只要响应的类别命中其中任意一个即输出日志。setup_test.go中log { class denial }、log { class denial error }与两条class语句等价的用例印证了这一行为plugin/log/setup_test.go。响应类别含义类别含义success成功响应denialNXDOMAIN 或 nodata名称存在但类型不存在响应nodata 响应返回码为 NOERRORerrorSERVFAIL、NOTIMP、REFUSED 等即远端服务器不愿解析该请求的情况all默认值。未指定类别时的行为与任何类别混用都会导致所有消息被记录未指定类别时默认是all源码中len(classes) 0时写入response.All。类别判定映射自 plugin/pkg/response/classify.goNoError/Delegation归为successNameError/NoData归为denial其余含OtherError归为error。底层响应类型判定在 plugin/pkg/response/typify.go 的Typify中完成。日志格式与占位符log同时支持请求request与响应response占位符自定义格式可自由组合。支持的占位符如下占位符含义{type}请求的 qtype{name}请求的 qname{class}请求的 qclass{proto}所用协议tcp 或 udp{remote}客户端 IP 地址IPv6 地址会用方括号包裹[::1]{local}服务器 IP 地址IPv6 地址同样用方括号包裹{size}请求大小字节{port}客户端端口{duration}响应耗时{rcode}响应 RCODE{rsize}原始未压缩响应大小客户端实际收到的可能更小{rflags}响应标志每个置位的标志都会显示例如 aa, tc包含 qr 位{bufsize}查询中通告的 EDNS0 buffer 大小{do}查询中 EDNS0 DODNSSEC OK位是否置位{id}查询 ID{opcode}查询 OPCODE{common}默认的 Common Log Format{combined}带查询 opcode 的 Common Log Format{/LABEL}任意元数据标签只要用{/与}包裹即可作为占位符未定义时替换为默认值-详见metadata插件plugin/metadata/README.md占位符的求值逻辑集中在 plugin/pkg/replacer/replacer.go{remote}、{local}对 IPv6 地址自动加方括号appendAddrToRFC3986{rflags}通过appendFlags依次检查 qr/aa/tc/rd/ra/z/ad/cd 标志并逗号拼接{rcode}优先用dns.RcodeToString输出文本如NOERROR未知 RCODE 回退为十进制数字元数据标签{/...}从 context 中按metadata.ValueFunc取值未设置则输出-。格式串会被解析为「字面量 / 标签 / 元数据」三类节点并缓存loadFormatsync.Map复用同一 Replacer 并发安全降低逐请求解析开销。默认 Common Log Format{remote}:{port} - {id} {type} {class} {name} {proto} {size} {do} {bufsize} {rcode} {rflags} {rsize} {duration}该常量定义在 plugin/log/log.go 的CommonLogFormat中CombinedLogFormat CommonLogFormat {opcode}DefaultLogFormat CommonLogFormat。注意格式串中-对应replacer.EmptyValue空值占位符因此日志里出现-表示某个字段不可用。默认文本模式下每条日志通过log.Info输出典型实例如下[INFO] [::1]:50759 - 29008 A IN example.org. udp 41 false 4096 NOERROR qr,rd,ra,ad 68 0.037990251s逐字段解读[::1]:50759为客户端地址与端口29008为查询 ID引号内依次是 qtype、qclass、qname、协议、请求大小、DO 位、EDNS0 buffer 大小随后是 RCODE、置位标志、响应大小与耗时。JSON 输出模式启动 CoreDNS 时使用命令行标志-log-formatjson即可让整个进程以 JSON 格式输出日志这是命令行参数不是 Corefile 指令默认值是-log-formattext见 coremain/run.go 中的 flag 定义以及 plugin/pkg/log/json.go 中IsJSON()的后端判断。log插件的名称匹配与响应类别过滤在两种模式下行为完全一致。每个查询产生一条 JSON 记录包含公共字段time、level、msg、plugin查询记录恒为log以及以下类型化字段字段类型含义client_ipstring客户端地址IPv6 地址不带方括号client_portnumber客户端端口qnamestring小写、完整限定的查询名DNS 展示格式qtype,qclassstring查询类型与类别未知值包含数字形式protocolstringudp或tcp同{proto}id,opcodenumber查询 ID 与 opcoderequest_sizenumber请求字节数同{size}dnssec_okboolean查询的 DNSSEC OK 位bufsizenumber有效响应 buffer 大小同{bufsize}rcodestring 或 null响应 RCODE未记录到 DNS 响应时为 nullresponse_sizenumber记录的响应字节数同{rsize}duration_secondsnumber处理耗时秒与文本模式一致响应大小描述的是记录的、未压缩的消息未必等于真正下发给客户端的字节数。延迟错误如 SERVFAIL使用插件链返回后 CoreDNS 将生成的响应被丢弃的请求rcode: null不会记为成功响应裸Write调用计入大小但无法提供解码后的响应 RCODE。这些字段的实现位于 plugin/log/json.go 的logJSON通过slog.String/slog.Int/slog.Bool输出类型化属性rcode在rr.Msg nil例如被 ACL 丢弃时输出null否则先查dns.RcodeToString未知 RCODE 输出数字字符串。FORMAT仍控制msg字段包括自定义格式与元数据占位符但不会替换 JSON schema 或定义新的顶层字段DNS 字段直接来自请求与响应对象而非解析msg。例如配置log . {name} {rcode}时输出{time:2026-09-15T08:00:00Z,level:INFO,msg:example.org. NOERROR,plugin:log,client_ip:127.0.0.1,client_port:40212,qname:example.org.,qtype:A,qclass:IN,protocol:udp,id:42,opcode:0,request_size:29,dnssec_ok:false,bufsize:512,rcode:NOERROR,response_size:29,duration_seconds:0.001}附加元数据区分 NOERROR denial 与 successlog插件还会向 context 注入以下元数据用于对「NOERROR 的 denial」与 success 消息做更细粒度的区分。映射关系来自 plugin/pkg/response/classify.go 与 plugin/pkg/response/typify.go{/log/class}success、denial{/log/type}NODATA、NXDOMAIN、NOERROR注入逻辑在 plugin/log/log.go 的ServeDNS中先response.Typify(rrw.Msg, ...)得到类型如 NODATA/NXDOMAIN/NOERROR再response.Classify(tpe)得到类别success/denial/error最后通过metadata.SetValueFunc注册两个惰性求值的元数据函数。配合自定义格式使用. { log . {proto} Request: {name} {type} {/log/class} {/log/type} }典型输出形如udp Request: example.org. A denial NXDOMAIN可精确区分「名称不存在的 NXDOMAIN」「名称存在但类型不存在的 NODATA」以及「正常成功的 NOERROR」三类结果。实战示例以下示例均来自 plugin/log/README.md可直接放入 Corefile 使用。将所有请求记录到 stdout. { log whoami }自定义日志格式覆盖所有区域.. { log . {proto} Request: {name} {type} {id} }只记录 example.org及以下子域的 denialNXDOMAIN 与 nodata. { log example.org { class denial } }以 Combined Log Format 记录所有未成功解析的查询. { log . {combined} { class denial error } }记录所有未出现错误的查询. { log . { class denial success } }多条 class 语句的 OR 语义上面的写法可等价改写为. { log . { class denial class success } }测试用例进一步验证了这些行为TestLoggedClassDenial证实class denial下 NXDOMAIN 请求会输出 NXDOMAIN而class error不记录该请求TestLoggedStatus验证默认格式包含A IN example.org. udp 29 false 512等字段TestLoggedSynthesizesDeferredServerFailure则验证下游插件返回错误但未写响应时log会先合成 SERVFAIL 应答再分类记录见 plugin/log/log_test.go。常见问题与注意事项{remote}/{local}与client_ip的差异文本模式的{remote}对 IPv6 加方括号如[::1]JSON 模式的client_ip不带方括号做日志归一时需注意。rsize是未压缩大小{rsize}与response_size描述的是记录的原始消息长度客户端实际收到的报文可能更小例如受 EDNS0 buffer 限制被截断。被丢弃的请求请求被上游插件丢弃未产生响应时文本模式{rcode}显示-JSON 模式rcode为null不会被当作成功响应计数。性能开销文档明确说明繁忙服务器启用查询日志会有性能损耗建议用class过滤仅记录denial/error或将-log-formatjson与结构化采集配合以降低解析成本。配置错误会在启动时暴露class后无参数、非法类别如class abracadabra或块内未知属性如log { unknown }都会导致 Corefile 解析失败logParse会返回错误并中止启动见 plugin/log/setup_test.go 中的对应用例。赞分享后端网络云原生【免费下载链接】corednsCoreDNS is a DNS server that chains plugins项目地址https://gitcode.com/gh_mirrors/co/coredns点击查看免费下载相关推荐Fission日志查询语言高效过滤与分析函数输出Fission日志查询语言高效过滤与分析函数输出 在Kubernetes环境中管理Serverless函数时日志分析是排查问题、优化性能的关键环节。Fiss云原生后端VeleroArkbackup get 命令详解查询备份状态、过滤与格式化输出VeleroArk backup get 命令详解查询备份状态、过滤与格式化输出 导读 velero backup get 历史版本中为 ark bac云原生灾备存储后端INFINI Console日志分析实时日志查询与过滤INFINI Console日志分析实时日志查询与过滤 痛点分布式环境下的日志管理困境 在分布式搜索集群环境中日志管理一直是运维工程师面临的核心挑战。当E后端数据库可观测性告警运维上一篇GetQzonehistory完整教程5分钟学会永久备份QQ空间所有历史记录下一篇提升Android开发效率dagger-intellij-plugin的5个实用技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考