Prometheus Adapter for HWiNFO (+ Grafana Dashboard)

I've been running prometheus with node_exporter for all of my linux boxes for a while, and just found your exporter for hwInfo64. Thank you so much @Kallex ... you rock!

As a tiny contribution, I added my UPS info to the yaml:

YAML:
    # UPS
    - '(?<Entity_UPS>)(?<MetricName>UPS Load|Input Voltage|Output Voltage|Charge Level|Estimated Runtime|AC Power|Charging|Discharging)'

That results in:

# HELP hwi_ups_ac_power_yesno UPS AC Power Yes/No - UPS
# HELP hwi_ups_charge_level UPS Charge Level % - UPS
# HELP hwi_ups_charging_yesno UPS Charging Yes/No - UPS
# HELP hwi_ups_discharging_yesno UPS Discharging Yes/No - UPS
# HELP hwi_ups_estimated_runtime_min UPS Estimated Runtime min - UPS
# HELP hwi_ups_input_voltage_v UPS Input Voltage V - UPS
# HELP hwi_ups_output_voltage_v UPS Output Voltage V - UPS
# HELP hwi_ups_ups_load UPS UPS Load % - UPS
# HELP hwi_ups_ups_load_w UPS UPS Load W - UPS

And some actual metrics:

# HELP hwi_ups_ac_power_yesno UPS AC Power Yes/No - UPS
hwi_ups_ac_power_yesno{unit="Yes/No",sensor_type="SENSOR_TYPE_OTHER",sensor="AC Power",source="UPS",host="N3FARIOUS"} 1
# HELP hwi_ups_charge_level UPS Charge Level % - UPS
hwi_ups_charge_level{unit="%",sensor_type="SENSOR_TYPE_USAGE",sensor="Charge Level",source="UPS",host="N3FARIOUS"} 100
# HELP hwi_ups_charging_yesno UPS Charging Yes/No - UPS
hwi_ups_charging_yesno{unit="Yes/No",sensor_type="SENSOR_TYPE_OTHER",sensor="Charging",source="UPS",host="N3FARIOUS"} 0
# HELP hwi_ups_discharging_yesno UPS Discharging Yes/No - UPS
hwi_ups_discharging_yesno{unit="Yes/No",sensor_type="SENSOR_TYPE_OTHER",sensor="Discharging",source="UPS",host="N3FARIOUS"} 0
# HELP hwi_ups_estimated_runtime_min UPS Estimated Runtime min - UPS
hwi_ups_estimated_runtime_min{unit="min",sensor_type="SENSOR_TYPE_OTHER",sensor="Estimated Runtime",source="UPS",host="N3FARIOUS"} 35
# HELP hwi_ups_input_voltage_v UPS Input Voltage V - UPS
hwi_ups_input_voltage_v{unit="V",sensor_type="SENSOR_TYPE_VOLT",sensor="Input Voltage",source="UPS",host="N3FARIOUS"} 118
# HELP hwi_ups_output_voltage_v UPS Output Voltage V - UPS
hwi_ups_output_voltage_v{unit="V",sensor_type="SENSOR_TYPE_VOLT",sensor="Output Voltage",source="UPS",host="N3FARIOUS"} 118
# HELP hwi_ups_ups_load UPS UPS Load % - UPS
hwi_ups_ups_load{unit="%",sensor_type="SENSOR_TYPE_USAGE",sensor="UPS Load",source="UPS",host="N3FARIOUS"} 22
# HELP hwi_ups_ups_load_w UPS UPS Load W - UPS
hwi_ups_ups_load_w{unit="W",sensor_type="SENSOR_TYPE_POWER",sensor="UPS Load",source="UPS",host="N3FARIOUS"} 153.9

I have a CyberPower UPS and am running the PowerPanel Personal. These are the same stats it shows in it's "Current Status" panel.
 
I've been running prometheus with node_exporter for all of my linux boxes for a while, and just found your exporter for hwInfo64. Thank you so much @Kallex ... you rock!

As a tiny contribution, I added my UPS info to the yaml:

YAML:
    # UPS
    - '(?<Entity_UPS>)(?<MetricName>UPS Load|Input Voltage|Output Voltage|Charge Level|Estimated Runtime|AC Power|Charging|Discharging)'

Very cool addition, thanks a lot!

Hey, I started to make support for Linux (already while ago), unifying the adapter output. The thing is of course there is no HWiNFO for Linux, but that's not the whole big picture. Same as WMI support (also quite far, just been busy elsewhere) the idea was to be able to scrape from various sources to provide "common interface" to prometheus.

But if there is already existing what you mention "node_exporter" in Linux - is there any need to bring "unifying experience to Linux"?

I'm thinking the ability to name metrics and their categorization in one common way, so that the Prometheus + Grafana woudln't need to behave any different regardless of the Linux/Windows/Mac/??? behind the scenes.
 
Very cool addition, thanks a lot!

Hey, I started to make support for Linux (already while ago), unifying the adapter output. The thing is of course there is no HWiNFO for Linux, but that's not the whole big picture. Same as WMI support (also quite far, just been busy elsewhere) the idea was to be able to scrape from various sources to provide "common interface" to prometheus.

But if there is already existing what you mention "node_exporter" in Linux - is there any need to bring "unifying experience to Linux"?

I'm thinking the ability to name metrics and their categorization in one common way, so that the Prometheus + Grafana woudln't need to behave any different regardless of the Linux/Windows/Mac/??? behind the scenes.

Thanks for great tool , im using it in unraid (linux) HWiNFO Home Cluster.json imported to Grafana ,but dont have all values.
like all cpu /package ,psu (added line from forum to *.yaml ) also s.m.a.r.t is no data . also they gone in 192.168.0.101:10445/metrics ,but drive data is present here.
where to look for fix thouse problems?
 
You can start adding "catch all" setting to PromDapter.yaml

# Catch all - '(?<MetricName>.*)'

Add it as a last entry before Aggregate values. That will catch all the remaining sensors, that weren't catched before. So after that, examine thorougly the /metrics result - it should have everything that's visible in HWiNFO.

Then to fine-tune the result to be more usable, pick the exact sensor names and try to form a proper regex or paste the lines here and I (or someone else) will try to do them for you.
 
Hey, I started to make support for Linux (already while ago), unifying the adapter output. The thing is of course there is no HWiNFO for Linux, but that's not the whole big picture. Same as WMI support (also quite far, just been busy elsewhere) the idea was to be able to scrape from various sources to provide "common interface" to prometheus.

But if there is already existing what you mention "node_exporter" in Linux - is there any need to bring "unifying experience to Linux"?
node_exporter seems to be the most widely used linux collector set for prometheus tsdb. We use a different collector at work, but only because we use a different tsdb. (We have 50k+ nodes, and it is more complicated to scale Prom like that.)

https://github.com/prometheus/node_exporter details everything out in their README.md

I'm certainly no expert, but it seems to capture most all of the metrics that linux exposes.
 
You can start adding "catch all" setting to PromDapter.yaml

# Catch all - '(?<MetricName>.*)'

Add it as a last entry before Aggregate values. That will catch all the remaining sensors, that weren't catched before. So after that, examine thorougly the /metrics result - it should have everything that's visible in HWiNFO.

Then to fine-tune the result to be more usable, pick the exact sensor names and try to form a proper regex or paste the lines here and I (or someone else) will try to do them for you.
i added this line , restarted service,restarted prometheus...
Strange but i think its not added more sensors .... its same metrics like it was befor .
 
Martin, if you happen to follow this thread, we got an issue that I could use some assistance with.

GitHub Issue About Few Missing Metrics.

The issue is about new RTX 3080 Ti and its additional temps. Could there be anything special why they wouldn't behave alike in Shared Memory Interface? All the other metrics seem to "passthrough" properly, but for some reason those are missing.

I try to replicate with my code too, but as I don't have identical hardware as the user, I might not be able to replicate (I'll see if my own RTX 3080 replicates this).
 
Nothing special with those values, they should be included in shared memory as any other.
So I'm really wondering why this is happening.
 
Nothing special with those values, they should be included in shared memory as any other.
So I'm really wondering why this is happening.
No problem!

It could very well be something in my own code - just figured to quickly ask you if there was something special with those values. I'll grab newest versions myself and see if I can repro with my RTX 3080.

I'll get back once I can gather more details, thanks for the really swift reply!
 
It was cleared out, everything worked OK, just pattern matching caused some boggling issues, but it got resolved by the user.
 
Weird.. getting 500 errors starting this morning. When I checked the event viewer for errors at the time of my last data point in grafana, I see the following Warning and two Errors. The service still shows as running, and the port is listening per netstat.

EDIT: Hmm... more concerning, just a reboot fixed it. Any thoughts on cause or where I can look next?

Code:
The description for Event ID 0 from source PromDapterSvc cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

If the event originated on another computer, the display information had to be saved with the event.

The following information was included with the event:

Category: PromDapterSvc.Controllers.MetricsController
EventId: 0
ConnectionId: 0HMB46IPN2BG6
RequestId: 0HMB46IPN2BG6:00000001
RequestPath: /metrics/
SpanId: |41073687-4fa6ffe5e714e27d.
TraceId: 41073687-4fa6ffe5e714e27d
ParentId:
ActionId: 64e8a736-be31-43d1-86f1-01089ecc2c95
ActionName: PromDapterSvc.Controllers.MetricsController.Get (PromDapterSvc)

No prefix defined in configuration; defaulting to hwi_


The message resource is present but the message was not found in the message table

Code:
The description for Event ID 0 from source PromDapterSvc cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

If the event originated on another computer, the display information had to be saved with the event.

The following information was included with the event:

Category: PromDapterSvc.Controllers.MetricsController
EventId: 0
ConnectionId: 0HMB46IPN2BG6
RequestId: 0HMB46IPN2BG6:00000001
RequestPath: /metrics/
SpanId: |41073687-4fa6ffe5e714e27d.
TraceId: 41073687-4fa6ffe5e714e27d
ParentId:
ActionId: 64e8a736-be31-43d1-86f1-01089ecc2c95
ActionName: PromDapterSvc.Controllers.MetricsController.Get (PromDapterSvc)

Unhandled error

Exception:
System.IO.FileNotFoundException: Unable to find the specified file.
   at System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(String mapName, HandleInheritability inheritability, Int32 desiredAccessRights, Boolean createOrOpen)
   at System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(String mapName, HandleInheritability inheritability, MemoryMappedFileRights rights, Boolean createOrOpen)
   at System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability)
   at System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName, MemoryMappedFileRights desiredAccessRights)
   at SensorMonHTTP.HWiNFOProvider..MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at PrometheusProcessor.ServiceProcessor...MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at PromDapterSvc.Controllers.MetricsController..MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at PromDapterSvc.Controllers.MetricsController..MoveNext()


The message resource is present but the message was not found in the message table

Code:
Category: Microsoft.AspNetCore.Server.Kestrel
EventId: 13
ConnectionId: 0HMB46IPN2BG6
RequestId: 0HMB46IPN2BG6:00000001
RequestPath: /metrics/
SpanId: |41073687-4fa6ffe5e714e27d.
TraceId: 41073687-4fa6ffe5e714e27d
ParentId:

Connection id "0HMB46IPN2BG6", Request id "0HMB46IPN2BG6:00000001": An unhandled exception was thrown by the application.

Exception:
System.IO.FileNotFoundException: Unable to find the specified file.
   at System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(String mapName, HandleInheritability inheritability, Int32 desiredAccessRights, Boolean createOrOpen)
   at System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(String mapName, HandleInheritability inheritability, MemoryMappedFileRights rights, Boolean createOrOpen)
   at System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability)
   at System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName, MemoryMappedFileRights desiredAccessRights)
   at SensorMonHTTP.HWiNFOProvider..MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at PrometheusProcessor.ServiceProcessor...MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at PromDapterSvc.Controllers.MetricsController..MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at PromDapterSvc.Controllers.MetricsController..MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at lambda_method(Closure , Object )
   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
 
Last edited:
Efff... ignore the last message. I think it is because of the attached error and 7.x non-pro limitation.
 

Attachments

  • hwinfo-error.PNG
    hwinfo-error.PNG
    62.6 KB · Views: 9
You can start adding "catch all" setting to PromDapter.yaml

# Catch all - '(?<MetricName>.*)'

Add it as a last entry before Aggregate values. That will catch all the remaining sensors, that weren't catched before. So after that, examine thorougly the /metrics result - it should have everything that's visible in HWiNFO.

Then to fine-tune the result to be more usable, pick the exact sensor names and try to form a proper regex or paste the lines here and I (or someone else) will try to do them for you.

That is great as it would allow me to capture the memory junction temperature sensor for the 3000 series gpus (esp. 3080/3090 because it runs very hot on them).

I've been running prometheus with node_exporter for all of my linux boxes for a while, and just found your exporter for hwInfo64. Thank you so much @Kallex ... you rock!

As a tiny contribution, I added my UPS info to the yaml:

YAML:
    # UPS
    - '(?<Entity_UPS>)(?<MetricName>UPS Load|Input Voltage|Output Voltage|Charge Level|Estimated Runtime|AC Power|Charging|Discharging)'

That results in:

# HELP hwi_ups_ac_power_yesno UPS AC Power Yes/No - UPS
# HELP hwi_ups_charge_level UPS Charge Level % - UPS
# HELP hwi_ups_charging_yesno UPS Charging Yes/No - UPS
# HELP hwi_ups_discharging_yesno UPS Discharging Yes/No - UPS
# HELP hwi_ups_estimated_runtime_min UPS Estimated Runtime min - UPS
# HELP hwi_ups_input_voltage_v UPS Input Voltage V - UPS
# HELP hwi_ups_output_voltage_v UPS Output Voltage V - UPS
# HELP hwi_ups_ups_load UPS UPS Load % - UPS
# HELP hwi_ups_ups_load_w UPS UPS Load W - UPS

And some actual metrics:

# HELP hwi_ups_ac_power_yesno UPS AC Power Yes/No - UPS
hwi_ups_ac_power_yesno{unit="Yes/No",sensor_type="SENSOR_TYPE_OTHER",sensor="AC Power",source="UPS",host="N3FARIOUS"} 1
# HELP hwi_ups_charge_level UPS Charge Level % - UPS
hwi_ups_charge_level{unit="%",sensor_type="SENSOR_TYPE_USAGE",sensor="Charge Level",source="UPS",host="N3FARIOUS"} 100
# HELP hwi_ups_charging_yesno UPS Charging Yes/No - UPS
hwi_ups_charging_yesno{unit="Yes/No",sensor_type="SENSOR_TYPE_OTHER",sensor="Charging",source="UPS",host="N3FARIOUS"} 0
# HELP hwi_ups_discharging_yesno UPS Discharging Yes/No - UPS
hwi_ups_discharging_yesno{unit="Yes/No",sensor_type="SENSOR_TYPE_OTHER",sensor="Discharging",source="UPS",host="N3FARIOUS"} 0
# HELP hwi_ups_estimated_runtime_min UPS Estimated Runtime min - UPS
hwi_ups_estimated_runtime_min{unit="min",sensor_type="SENSOR_TYPE_OTHER",sensor="Estimated Runtime",source="UPS",host="N3FARIOUS"} 35
# HELP hwi_ups_input_voltage_v UPS Input Voltage V - UPS
hwi_ups_input_voltage_v{unit="V",sensor_type="SENSOR_TYPE_VOLT",sensor="Input Voltage",source="UPS",host="N3FARIOUS"} 118
# HELP hwi_ups_output_voltage_v UPS Output Voltage V - UPS
hwi_ups_output_voltage_v{unit="V",sensor_type="SENSOR_TYPE_VOLT",sensor="Output Voltage",source="UPS",host="N3FARIOUS"} 118
# HELP hwi_ups_ups_load UPS UPS Load % - UPS
hwi_ups_ups_load{unit="%",sensor_type="SENSOR_TYPE_USAGE",sensor="UPS Load",source="UPS",host="N3FARIOUS"} 22
# HELP hwi_ups_ups_load_w UPS UPS Load W - UPS
hwi_ups_ups_load_w{unit="W",sensor_type="SENSOR_TYPE_POWER",sensor="UPS Load",source="UPS",host="N3FARIOUS"} 153.9

I have a CyberPower UPS and am running the PowerPanel Personal. These are the same stats it shows in it's "Current Status" panel.

Thanks for that. I have a cyberpower UPS (..but I also have an APC).
 
Trying to wrap my head around how to set this up, anyone got any good guides?

Thoroughly confused

Sorry for long delay. I noticed the message but was busy elsewhere and forgot it.

You need to have Prometheus (and Grafana) installed first. The PromDapter is only Prometheus provider, so that Prometheus scrapes PromDapter's webpage as its data source. So Prometheus and Grafana are independently set up and running - kind of independent of HWiNFO and PromDapter.
 
Hey guys,
iam new to hwinfo and grafana / prometheus.
Unfortunately i miss many metrics what i'm looking for.
I've added
Code:
- '(?<MetricName>.*)'
To the Mapping-yaml. Why arent all values enabled by default? Just because of the prometheus storage size or are there any other disadvantages?
The problem that i've is after adding this line, the prometheus server wont accept my target-host.
He return an error:
Code:
help text is not a valid utf8 string
I've added the whole output from the webserver (host).

Can you help me please?

PS: How can i get the exact sensorname from hwinfo if its missing so that i can build an regex? An short example step by step guide or video would be awesome!
 

Attachments

  • output.txt
    86.9 KB · Views: 7
Hey guys,
iam new to hwinfo and grafana / prometheus.
Unfortunately i miss many metrics what i'm looking for.
I've added
Code:
- '(?<MetricName>.*)'
To the Mapping-yaml. Why arent all values enabled by default? Just because of the prometheus storage size or are there any other disadvantages?

The reason for structurally parsed (= separate regexp) sensor names is to be able to group the CPU cores under same sensor name, but having Core # as separate categorization attribute. So In Prometheus you can then take max frequency out of them. If they are all metricname unique, that grouping goes out of the picture.

The reason you likely had no metrics to begin with is, that after HWiNFO added localization, none of the "out-of-the-box" provided patterns work with non-english systems.

The problem that i've is after adding this line, the prometheus server wont accept my target-host.
He return an error:
Code:
help text is not a valid utf8 string
I've added the whole output from the webserver (host).

Can you help me please?

PS: How can i get the exact sensorname from hwinfo if its missing so that i can build an regex? An short example step by step guide or video would be awesome!

I'll do my best to help with the problem.

We need to figure out / find out what's the breaking non-utf8 string within the help texts. So it's some non-alphabetic character, but for example the Celsius symbol seems to work OK for my system, so it shouldn't be that.
 
My first guess is that the character "ü" is the issue. You can try to use following regexp instead to filter out all of them. It will break the names containing that character by cutting out the remainder part, but there are then other ways to fix that part. This is just easy one to filter all of them out to see if that's the problem.

(?<MetricName>[^ü]*).*
 
I think the problem is that HWiNFO doesn't export text in UTF-8 format, but in the locale set for Non-Unicode applications in Windows. This is to maintain backwards compatibility with all clients reading data from HWiNFO. A solution might be to extend the Shared Memory to include text items in UTF-8 too, or trying to enable the "Beta: Use Unicode UTF-8 for worldwide language support" option in Windows Administrative language settings:
1646895311520.png
 
First of all thanks for these quick replys!
I'm completely fine to use english settings from now on, no worry.

My first guess is that the character "ü" is the issue. You can try to use following regexp instead to filter out all of them. It will break the names containing that character by cutting out the remainder part, but there are then other ways to fix that part. This is just easy one to filter all of them out to see if that's the problem.

(?<MetricName>[^ü]*).*
No changes. I've added all further characters
(?<MetricName>[^üöä]*).*
and now its working! So your guess was right.

I think the problem is that HWiNFO doesn't export text in UTF-8 format, but in the locale set for Non-Unicode applications in Windows. This is to maintain backwards compatibility with all clients reading data from HWiNFO. A solution might be to extend the Shared Memory to include text items in UTF-8 too, or trying to enable the "Beta: Use Unicode UTF-8 for worldwide language support" option in Windows Administrative language settings:
View attachment 7497
With enabled Setting i cant see any change with my initial setting.


The reason for structurally parsed (= separate regexp) sensor names is to be able to group the CPU cores under same sensor name, but having Core # as separate categorization attribute. So In Prometheus you can then take max frequency out of them. If they are all metricname unique, that grouping goes out of the picture.
Okay thanks for the insight!


Additional Question: After starting HWInfo the PromDapterSvc wont work until open "Sensors" manually. Are there any settings or tweaks i'm missing?
 
Back
Top