fix(inputs.upsd): Enforce string type for vendor and product IDs#18626
fix(inputs.upsd): Enforce string type for vendor and product IDs#18626majiayu000 wants to merge 3 commits intoinfluxdata:masterfrom
Conversation
The go.nut library auto-detects numeric-looking values and converts them to integers, stripping leading zeros (e.g. "0764" becomes 764). This causes type conflicts in InfluxDB when different UPS vendors report non-numeric IDs for the same fields. Convert ups.vendorid, ups.productid, driver.parameter.vendorid, and driver.parameter.productid to strings before writing, following the same pattern used for ups.firmware. Signed-off-by: majiayu000 <1835304752@qq.com>
Signed-off-by: majiayu000 <1835304752@qq.com>
srebhan
left a comment
There was a problem hiding this comment.
Thanks for your contribution @majiayu000!
|
Hi @majiayu000, thanks for this fix. After discussion with @srebhan, we'd like to land this behind a config option so users can migrate gracefully rather than getting a silent type change on upgrade. Here's the plan: This PR (step 1): Add a config option (e.g. Future PRs (for our tracking, not this one):
One small thing worth knowing: because go.nut parses Let me know if you have questions on the option naming or wording of the warning. |
Per maintainer feedback, introduce the fix behind an opt-in config
option so users get a migration path rather than a silent type change
on upgrade. This is step 1 of a 3-step migration:
Step 1 (this commit): Add `stringify_ids` bool, default false to
preserve the legacy numeric behavior. Emit a warning in Init()
when the option is unset noting the default will flip in a
future release.
Step 2 (future): flip the default to true, deprecate the option.
Step 3 (future): remove the option.
When `stringify_ids = true`, ups.vendorid, ups.productid,
driver.parameter.vendorid and driver.parameter.productid are forced
to string before the ForceFloat conversion, so the numeric-looking
values that go.nut auto-casts to int64 (e.g. "0764" -> 764) and the
non-numeric values ("ABCD") are all emitted with the same field type.
Note: because go.nut parses "0764" into int64(764) before Telegraf
sees it, the emitted string is "764"; leading zeros are not
recoverable at this layer. Documented in the plugin README.
Revert CyberPowerSystems_CP900EPFCLCD_full/expected.out to the
pre-PR integer form so the default-off behavior is covered, and
add a CyberPowerSystems_CP900EPFCLCD_full_stringify_ids testcase
that exercises the opt-in path.
Signed-off-by: majiayu000 <1835304752@qq.com>
|
Thanks @skartikey, updated the PR to follow the 3-step migration plan. Pushed as 8f42f14. Changes in this push:
Happy to adjust the warning wording or the option name if you'd prefer something else. Also let me know if you'd rather have |
|
Download PR build artifacts for linux_amd64.tar.gz, darwin_arm64.tar.gz, and windows_amd64.zip. 🥳 This pull request decreases the Telegraf binary size by -1.05 % for linux amd64 (new size: 300.7 MB, nightly size 303.9 MB) 📦 Click here to get additional PR build artifactsArtifact URLs |
Summary
The go.nut library auto-detects numeric-looking values using a regex and converts them to int64. This means a vendorid like "0764" becomes int64(764), but a non-numeric vendorid like "ABCD" stays a string. When both types of UPS devices report to the same InfluxDB bucket, you get type conflicts on the vendorid/productid fields.
This adds a
stringFieldSetthat forcesups.vendorid,ups.productid,driver.parameter.vendorid, anddriver.parameter.productidto always be emitted as strings, following the sameinternal.ToStringpattern already used forups.firmware. The string check runs before theForceFloatconversion so these fields aren't accidentally cast to float.Also adds a test case with non-numeric vendor/product IDs to confirm type consistency.
Checklist
Related issues
resolves #18308