ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

访问 Gumroad 部署环境的日志(Logs):Nomad 环境下的生产与预发布日志查看指南

访问 Gumroad 部署环境的日志(Logs):Nomad 环境下的生产与预发布日志查看指南 访问 Gumroad 部署环境的日志LogsNomad 环境下的生产与预发布日志查看指南【免费下载链接】gumroadSee what sticks项目地址: https://gitcode.com/GitHub_Trending/gumr/gumroad导读docs/logs.md是 Gumroad 项目中关于访问部署环境运行日志的最小操作指南它明确了在生产production与预发布staging两种 Nomad 部署环境中如何通过logs.sh脚本一键拉取日志。本文以此文档为骨架结合仓库中的 Rails 日志配置config/application.rb、config/environments/production.rb、config/initializers/lograge.rb、日志脱敏工具lib/utilities/log_redactor.rb以及部署文档docs/deploying.md、docs/production_environment.md完整还原这两条命令的使用场景、底层日志链路与可验证依据帮助开发者在线上排查问题时快速上手。一、原文档速览两条命令两个环境docs/logs.md的正文非常精炼核心内容如下生产环境production进入nomad/production目录后执行./logs.sh预发布环境staging进入nomad/staging目录后执行./logs.sh。cd nomad/production ./logs.sh cd nomad/staging ./logs.sh两条命令形态完全一致区别仅在于所在目录对应了不同的 Nomad 部署集群。这意味着 Gumroad 的日志访问入口与部署集群绑定想看哪套环境的日志就去哪套环境的 Nomad 工作目录执行脚本。需要说明的是nomad/部署目录属于独立的部署仓库部署相关脚本不在本仓库内但本仓库保留了部署与日志体系的若干佐证足以还原该命令背后的完整链路。二、为什么是nomad/HashiCorp Nomad 部署体系docs/logs.md中的命令都以cd nomad/...开头说明 Gumroad 的生产与预发布环境是构建在HashiCorp Nomad作业调度器之上的。从 docs/deploying.md 可以看到 Nomad 在本项目中的具体角色部署时通过cd nomad/production dotenv -f ../.env ./deploy_unattended.sh执行运行database_migration、rpush、sidekiq_worker等 Nomad 作业job部署异常时可以在http://localhost:8080的 Nomad-UI 的Allocations页面杀掉正在运行的容器或使用nomad命令热修复 worker 时会通过dotenv -f ../.env erb sidekiq_worker.nomad.erb sidekiq_worker.nomad渲染 Nomad 作业定义文件再用nomad run提交。也就是说Gumroad 的 web 服务器、Sidekiq worker、RPush 推送服务等都以容器化作业的形式运行在 Nomad 集群中logs.sh正是面向这套体系封装的日志查看脚本其实现细节位于独立的部署仓库本仓库未包含。仓库中还保留了 Nomad 客户端的安装脚本 ci_scripts/install_nomad.sh脚本默认下载并安装NOMAD_VERSION${NOMAD_VERSION:-0.8.3}版本的nomad_${NOMAD_VERSION}_linux_amd64.zip到/usr/local/bin/随后用nomad --version验证安装。这从侧面说明要使用logs.sh本机通常需要具备可用的nomad命令行工具并配置好对应集群的访问凭证。三、日志从哪里来Rails 应用侧的日志出口理解了 Nomad 集群之后还需要知道应用自身是如何产生日志的。Gumroad 在非开发环境下将 Rails 日志直接输出到 STDOUT这是容器化环境的标准做法——容器运行时Docker/Nomad捕获标准输出再由日志采集代理如日志 shipper转发到集中式平台。3.1 生产与预发布日志打到 STDOUTconfig/application.rb 第 121–129 行对日志做了环境分支if Rails.env.development? || Rails.env.test? logger ActiveSupport::Logger.new(log/#{Rails.env}.log, weekly) logger.formatter config.log_formatter else logger Logger.new(STDOUT) config.lograge.enabled true end config.logger ActiveSupport::TaggedLogging.new(logger)开发/测试环境写入log/环境名.log文件并按weekly进行日志轮转生产/预发布环境写入STDOUT同时开启 logrageconfig.lograge.enabled true把 Rails 默认的多行请求日志折叠为单行结构化日志便于采集、解析与检索无论哪种环境最终都会包一层ActiveSupport::TaggedLogging为每条日志追加上下文标签。3.2 环境级配置日志级别与标签config/environments/production.rb 第 50–61 行的配置是生产环境的最终设定# Log to STDOUT by default config.logger ActiveSupport::Logger.new(STDOUT) .tap { |logger| logger.formatter ::Logger::Formatter.new } .then { |logger| ActiveSupport::TaggedLogging.new(logger) } # Prepend all log lines with the following tags. config.log_tags [:request_id] # info includes generic and useful information about system operation, but avoids logging too much # information to avoid inadvertent exposure of personally identifiable information (PII). If you # want to log everything, set the level to debug. config.log_level ENV.fetch(RAILS_LOG_LEVEL, info)要点日志级别通过环境变量RAILS_LOG_LEVEL控制默认info源码注释明确说明info级既包含系统运行的有用信息又避免过度记录个人身份信息 PII需要全量输出时设为debug日志标签config.log_tags [:request_id]每条日志都会带上请求 ID方便在分布式调用中串联一次请求的完整链路生产环境显式使用了::Logger::Formatter作为格式化器保证输出格式稳定、可解析。预发布环境 config/environments/staging.rb 采用相同的 STDOUT :request_id结构但默认日志级别为debug同样可用RAILS_LOG_LEVEL覆盖因此在预发布环境能看到比生产更细粒度的日志。3.3 测试环境的可观测开关config/environments/test.rb 中提供了调试相关的环境变量当RAILS_DISABLE_TEST_LOGtrue时使用空 logger 关闭日志日志级别默认debug。这属于本地开发/CI 场景与部署环境的日志查看无直接关系但有助于理解整个应用的日志配置全貌。四、集中式日志从 Nomad 容器到 Kibanalogs.sh拉取的是 Nomad 容器内的原始输出而 Gumroad 在更长周期上的日志回溯依赖集中式平台。这一点在 docs/deploying.md 的 “Logs” 一节有明确说明All logs generated in the production docker containers (which includes db migration, web servers, Sidekiq) are being pushed tohttps://logs.gumroad.com. Its a Kibana instance connected to Elasticsearch. To view deployment/application logs, please search with the 7-letter SHA of the revision.关键信息覆盖范围生产环境 Docker 容器产生的所有日志——包括db migration、web 服务器Puma、Sidekiq——都会被推送pushed到集中式平台技术栈logs.gumroad.com是一个连接 Elasticsearch 的Kibana实例可在 Kibana Discover 页面对日志进行全文检索与聚合分析检索方法以部署版本的7 位短 SHA作为检索关键词即可定位某次发布前后所有容器的日志。结合 docs/production_environment.md 可知生产环境由多类服务组成Puma web 服务器、Sidekiq worker、RPush 推送服务这些服务的日志都会进入上述集中链路。因此在实际排障时有两套互补手段手段命令 / 入口适用场景实时/单机日志cd nomad/production ./logs.sh或 staging 同理查看某个环境当前容器实例的实时输出集中式检索Kibanalogs.gumroad.com 7 位 SHA跨容器、跨时间范围如发布前后对比的检索与聚合五、日志内容的安全处理LogRedactor 脱敏在将日志输出到 STDOUT 并汇入集中平台之前Gumroad 在业务代码层面对敏感信息做了显式脱敏处理。工具位于 lib/utilities/log_redactor.rbmodule LogRedactor FILTERED [FILTERED] SENSITIVE_KEYS %w[ token stripe_publishable_key authorization paypal-auth-assertion verify_sign ].freeze ...LogRedactor.redact(value)会递归遍历 Hash/Array/OpenStruct 结构凡是键名小写后命中SENSITIVE_KEYS的值一律替换为[FILTERED]从而避免 token、Stripe 公钥、授权头、PayPal 断言等敏感凭据进入日志。仓库中的实际用法示例app/business/payments/charging/implementations/paypal/paypal_rest_api.rb 第 198 行Rails.logger.info Making PayPal request:: #{LogRedactor.redact(request)}app/business/payments/payouts/processor/paypal/paypal_payout_processor.rb 第 351、392、421 行记录 PayPal 批量打款参数与 IPN 事件时均先经LogRedactor.redact处理app/controllers/user/omniauth_callbacks_controller.rb 第 64 行记录 Stripe Connect 回调参数时同样脱敏。因此即便通过logs.sh或 Kibana 检索日志诸如token、authorization等敏感字段在写入日志前也已被过滤这是处理支付相关日志时需要了解的安全边界。六、请求级结构化日志lograge 定制字段生产与预发布环境开启 lograge 后每次请求只输出一行精简日志而 config/initializers/lograge.rb 通过custom_options为这行日志附加了排障所需的关键字段Rails.application.config.lograge.custom_options lambda do |event| params { remote_ip: event.payload[:remote_ip] } headers event.payload[:headers] uuid event.payload[:uuid] ...该 lambda 会收集remote_ip、headers、uuid等通用请求上下文登录接口logins#create的login_identifier/login注册接口signup#create的email、buyer_signup、g-recaptcha-response以及has_auth、has_mobile_token、auth_user_id、auth_token_id、agent_action_*等认证与 Agent 动作字段存在时才加入。最终输出形如{ params params, headers headers, uuid uuid }这些字段与:request_id标签结合可以在 Kibana 中按uuid、remote_ip或auth_user_id快速过滤出单次请求/单个用户的完整日志序列——这与docs/logs.md提供的原始日志入口形成互补先logs.sh看容器实时输出再到 Kibana 按字段做结构化检索。七、实操指南完整的日志排查路径综合原文档与仓库源码一次完整的日志排查可以按以下路径展开1. 定位环境与集群生产cd nomad/production预发布cd nomad/staging2. 查看实时日志cd nomad/production ./logs.sh # 生产环境 cd nomad/staging ./logs.sh # 预发布环境3. 结合日志级别调整输出预发布默认debug生产默认info两者均可通过RAILS_LOG_LEVEL环境变量覆盖见 config/environments/production.rb 与 config/environments/staging.rb每条日志携带request_id标签config.log_tags [:request_id]可作为请求链路串联的锚点。4. 跨时间范围回溯在 Kibanalogs.gumroad.comDiscover 页以部署的7 位短 SHA检索覆盖 db migration、web、Sidekiq 等全部容器依据 docs/deploying.md 的 Logs 一节利用 lograge 定制的uuid、remote_ip、auth_user_id等字段做二次过滤。5. 注意日志脱敏边界敏感键token、stripe_publishable_key、authorization、paypal-auth-assertion、verify_sign在写入日志前已被替换为[FILTERED]见 lib/utilities/log_redactor.rb日志中出现的凭据类字段应为空值或脱敏标记。八、FAQ 与常见注意事项Q1为什么生产环境用 STDOUT 而不是日志文件容器化部署下日志由容器运行时统一捕获输出到 STDOUT 才能被采集转发到 Kibana 等集中平台。源码在 config/application.rb 中对非开发/测试环境统一走Logger.new(STDOUT)。Q2logs.sh脚本在哪里脚本位于独立的 Nomad 部署仓库nomad/production、nomad/staging目录不在当前应用仓库内。本仓库通过 docs/deploying.md 保留了其使用方式与上下文。Q3本地没有 nomad 命令怎么办可参考 ci_scripts/install_nomad.sh 安装 HashiCorp Nomad 客户端默认版本 0.8.3并确保配置好对应集群的访问凭证。Q4日志太多、噪音大生产环境默认info级别已刻意避免记录过多 PII源码注释明确说明需要排障细节时可临时以debug级别运行但需注意敏感信息处理与日志量成本集中检索时优先用 7 位 SHA、request_id、uuid、remote_ip等字段缩小范围。九、小结docs/logs.md用两条命令浓缩了 Gumroad 的日志访问方式进入对应环境的 Nomad 目录执行./logs.sh。围绕这两条命令仓库源码揭示了完整的日志链路产生生产/预发布环境将 Rails 日志输出到 STDOUTconfig/application.rb生产默认info级别并携带request_id标签config/environments/production.rb结构化lograge 开启单行日志并注入uuid、remote_ip、认证字段等排障信息config/initializers/lograge.rb安全支付、回调等场景的敏感字段在写日志前经LogRedactor脱敏lib/utilities/log_redactor.rb汇聚所有容器日志推送至 Kibana Elasticsearch可用 7 位 SHA 检索docs/deploying.md查看实时日志走cd nomad/environment ./logs.sh回溯检索走 Kibana。掌握这两条命令加上背后的配置细节即可在 Gumroad 的生产与预发布环境中快速定位线上问题。【免费下载链接】gumroadSee what sticks项目地址: https://gitcode.com/GitHub_Trending/gumr/gumroad创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进