using System.Net; using System.Text; using LibreHardwareMonitor.Hardware; var port = Environment.GetEnvironmentVariable("PORT"); if (!int.TryParse(port, out var httpPort)) { httpPort = 9646; // default port } var listener = new HttpListener(); listener.Prefixes.Add($"http://*:{httpPort}/"); listener.Start(); var computer = new Computer { IsCpuEnabled = true, IsGpuEnabled = true, IsMemoryEnabled = true, IsMotherboardEnabled = true, IsControllerEnabled = true, IsNetworkEnabled = true, IsStorageEnabled = true }; computer.Open(); Console.WriteLine($"LibreHardwareMonitorExporter listening on http://localhost:{httpPort}/metrics"); while (true) { var context = await listener.GetContextAsync(); if (context.Request.HttpMethod != "GET") { context.Response.StatusCode = 405; context.Response.Close(); continue; } if (context.Request.Url?.AbsolutePath != "/metrics") { context.Response.StatusCode = 404; context.Response.Close(); continue; } var body = new StringBuilder(); AppendMetrics(body, computer); var bytes = Encoding.UTF8.GetBytes(body.ToString()); context.Response.StatusCode = 200; context.Response.ContentType = "text/plain; version=0.0.4"; context.Response.ContentEncoding = Encoding.UTF8; context.Response.ContentLength64 = bytes.Length; await context.Response.OutputStream.WriteAsync(bytes, 0, bytes.Length); context.Response.Close(); } static void AppendMetrics(StringBuilder output, Computer computer) { var updateVisitor = new UpdateVisitor(); computer.Accept(updateVisitor); // Basic example metrics for temperature, load, clock, power, fan foreach (var hardware in computer.Hardware) { EmitHardwareMetrics(output, hardware); foreach (var sub in hardware.SubHardware) { EmitHardwareMetrics(output, sub); } } } static void EmitHardwareMetrics(StringBuilder output, IHardware hardware) { var hardwareLabel = SanitizeLabel(hardware.Name); foreach (var sensor in hardware.Sensors) { if (sensor.Value is null) continue; var sensorLabel = SanitizeLabel(sensor.Name); var value = sensor.Value.Value; var metricName = sensor.SensorType switch { SensorType.Temperature => "lhm_temperature_celsius", SensorType.Load => "lhm_load_percent", SensorType.Clock => "lhm_clock_mhz", SensorType.Power => "lhm_power_watts", SensorType.Fan => "lhm_fan_rpm", SensorType.Voltage => "lhm_voltage_volts", SensorType.Data => "lhm_data", SensorType.Level => "lhm_level", SensorType.Throughput => "lhm_throughput_bytes_per_sec", SensorType.Factor => "lhm_factor", SensorType.Flow => "lhm_flow_lph", SensorType.Control => "lhm_control_percent", _ => null }; if (metricName == null) continue; output.Append(metricName); output.Append("{"); output.Append($"hardware=\"{hardwareLabel}\",sensor=\"{sensorLabel}\",type=\"{sensor.SensorType}\""); output.Append("} "); output.AppendLine(value.ToString(System.Globalization.CultureInfo.InvariantCulture)); } } static string SanitizeLabel(string raw) { var sb = new StringBuilder(raw.Length); foreach (var ch in raw) { if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == ':' || ch == '.') { sb.Append(ch); } else { sb.Append('_'); } } return sb.ToString(); } sealed class UpdateVisitor : IVisitor { public void VisitComputer(IComputer computer) { computer.Traverse(this); } public void VisitHardware(IHardware hardware) { hardware.Update(); foreach (var sub in hardware.SubHardware) { sub.Accept(this); } } public void VisitSensor(ISensor sensor) { } public void VisitParameter(IParameter parameter) { } }