Facter自定义Facts完整教程:用Facter.add编写自己的系统信息采集代码(7大实用技巧)

📅 发布时间:2026/8/24 10:49:17
Facter自定义Facts完整教程:用Facter.add编写自己的系统信息采集代码(7大实用技巧) Facter自定义Facts完整教程用Facter.add编写自己的系统信息采集代码7大实用技巧【免费下载链接】facterCollect and display system facts项目地址: https://gitcode.com/gh_mirrors/fa/facterFacter 是一款跨平台的系统信息采集工具用于收集 Linux、macOS、Windows、Solaris、AIX 等系统的硬件、网络与操作系统信息。Facter 自定义 Facts允许你通过Facter.add编写 Ruby 代码块采集 Facter 没有内置的任何系统属性。本文带你从零基础快速上手 Facter.add掌握 confine、has_weight、外部 Facts 等核心用法。一、为什么需要 Facter 自定义 FactsFacter 内置了数百个核心 facts例如Fact 名称含义os操作系统结构化信息发行版、版本ipaddress主网络接口 IPmemory内存总量processorsCPU 数量与型号kernel内核名称但你的业务往往需要 Facter 没覆盖的信息比如公司内网代理配置、定制硬件序列号、自研 Agent 版本号。这时就有两条路Facter 自定义 FactsCustom Facts写 Ruby 代码调用Facter.add定义灵活度最高外部 FactsExternal Facts把keyvalue写进文本/JSON/YAML 文件或可执行脚本完全不用写 Ruby适合值已知、只需透传的场景。项目仓库中就自带了示例可直接参考 my_custom_fact.rb 与 my_external_fact.txt。二、Facter.add 最小骨架3 行代码采集第一个 Fact一个自定义 Fact 的标准结构是Facter.add setcodeFacter.add(:proxy_env) do setcode do Facter::Core::Execution.execute(env | grep HTTP_PROXY, on_fail: nil) end end运行后查看结果facter --custom-dir ./custom_facts proxy_env关键要点Facter.add(:name)接收一个符号或字符串作为 fact 名名称会被自动转小写源码见 fact.rbsetcode do ... end块内的代码只在 fact 被真正查询时才执行惰性求值因此可以写代价较高的系统调用而不拖慢整体采集Facter::Core::Execution.execute是官方推荐的方式执行 shell 命令on_fail: nil表示命令失败时返回 nil 而不抛异常实现位于 execution.rb。技巧 1命令执行类采集优先用Facter::Core::Execution.execute而不是裸调system它统一了 Windows/POSIX 差异与错误处理。三、用 confine 按操作系统条件采集不是所有命令在每台机器上都有。confine声明仅当条件满足时才执行本 resolutionFacter.add(:cpu_model) do confine { Facter.value(:kernel) Linux } setcode do Facter.value(:processors).fetch(:isa, unknown) end end条件不满足时该 fact 直接无值不会报命令不存在的错误可以叠加多个confine全部满足才执行常用条件Facter.value(:os)、Facter.value(:kernel)判断系统Facter::Core::Execution.which(lscpu)判断命令是否存在。条件与求值逻辑可参考 confine.rb。技巧 2把判断系统写在 confine、把采集数据写在 setcode采集代码才能安全地只写一个平台的实现。四、has_weight 权重多个采集逻辑谁说了算同一个 fact 可以定义多个setcode多次调用Facter.addFacter 会按权重从高到低逐个尝试取第一个非空结果。权重比较逻辑见 resolution.rb# 低权重兜底方案读文件 Facter.add(:disk_serial) do confine { Facter.value(:os)[:family] RedHat } setcode { File.read(/etc/disk_serial) rescue nil } end # 高权重方案调用硬件命令 Facter.add(:disk_serial) do has_weight(20) setcode do Facter::Core::Execution.execute(smartctl -i /dev/sda, on_fail: nil).match(/Serial Number: (\S)/).captures.first end end权重规则权重效果默认0 及以下若结果为空核心 fact 同名时优先返回核心值1 ~ 9999覆盖同名外部 facts10000 及以上覆盖外部 facts多个自定义方案之间按数值比大小技巧 3写覆盖型采集逻辑想替换内置 fact 的值时记得加has_weight(10_000)仓库示例 my_custom_os_fact.rb 就是这样覆盖os相关值的。五、复用已有 FactFacter.value 一站式取值自定义 fact 块内部可以直接读其他 fact避免重复解析系统Facter.add(:env_summary) do setcode do os#{Facter.value(:os)[:name]}, kernel#{Facter.value(:kernel)}, ip#{Facter.value(:ipaddress)} end endFacter.value支持传入字符串或符号结构化 fact如os返回的是 Hash可直接链式取字段。技巧 4先查facter os --yaml看结构再决定用Facter.value(:os)[:release][:full]这样的精确路径比重新执行uname快得多。六、不想写 Ruby外部 Facts 三步搞定外部 facts 把keyvalue放进指定目录的文件即可仓库示例 my_external_fact.txt 的内容仅一行my_external_fact123支持 4 种形式详见 Extensibility.md文件形式说明fact.txtkeyvalue文本行fact.json/fact.yamlJSON / YAML 键值对支持嵌套结构化可执行文件stdout 输出keyvalue行加载方式facter --external-dir ./external_facts my_external_fact优先级同权重下外部 facts 高于自定义 facts自定义 fact 权重 ≥ 10000 时可反压外部 facts。技巧 5值是环境里就有的配置文件、环境变量→ 用外部 facts值需要现场采集计算 → 用 Facter.add。七、自定义 Facts 放哪里三种加载位置Facter 会按以下位置加载 Ruby 自定义 facts见 Extensibility.mdRuby 加载路径LOAD_PATH中任意facter/子目录环境变量FACTERLIB指定的目录多目录用平台 PATH 分隔符分隔命令行--custom-dir指定的目录。FACTERLIB./custom_facts facter proxy_env facter --custom-dir ./custom_facts proxy_env技巧 6在 Puppet 生产环境中把自定义 facts 放进模块的facts.d/随模块分发无需依赖 FACTERLIB。八、调试与常见坑清单看不到 fact加--debug查看加载了哪些文件与 resolution--trace打印完整调用栈fact 名冲突自定义 fact 与核心 fact 同名且权重低值会被核心值兜底覆盖——这是设计行为而非 bug见 fact.rb 中的resolve_valuesetcode 抛异常异常被捕获并记录到日志fact 返回空可用facter --debug定位超时保护resolution 支持timeout选项默认上限见 resolvable.rb慢命令不会拖死整个采集别用绝对路径命令用Facter::Core::Execution.which(cmd)判断命令存在兼容不同发行版命令位置差异。技巧 7新写 fact 时先用facter name单查验证再放进批量目录避免一个坏文件拖慢全部采集。总结本文带你用Facter.add完成了从最小骨架到生产级用法的全流程setcode惰性采集、confine平台隔离、has_weight权重仲裁、Facter.value复用、外部 facts 免代码透传。核心 API 一览API作用源码位置Facter.add定义/追加 fact resolutionfacter.rbFacter::Util::Factfact 对象与取值仲裁fact.rbFacter::Util::Resolutionsetcode/权重/求值resolution.rbFacter::Core::Execution跨平台命令执行execution.rb配合仓库自带示例 custom_facts/ 目录与 spec/ 下的单元测试你可以快速建立起自己的系统信息采集体系。【免费下载链接】facterCollect and display system facts项目地址: https://gitcode.com/gh_mirrors/fa/facter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考