1
0

MetricConfig.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Security;
  6. using System.Security.Cryptography.X509Certificates;
  7. using System.Text.RegularExpressions;
  8. namespace OhmGraphite
  9. {
  10. public record EnabledHardware(bool Cpu, bool Gpu, bool Motherboard, bool Ram, bool Network, bool Storage,
  11. bool Controller, bool Psu, bool Battery);
  12. public class MetricConfig
  13. {
  14. private readonly INameResolution _nameLookup;
  15. public MetricConfig(TimeSpan interval, INameResolution nameLookup, GraphiteConfig graphite, InfluxConfig influx,
  16. PrometheusConfig prometheus, TimescaleConfig timescale, Dictionary<string, string> aliases, List<Regex> hiddenSensors, Influx2Config influx2, EnabledHardware enabledHardware)
  17. {
  18. _nameLookup = nameLookup;
  19. Interval = interval;
  20. Graphite = graphite;
  21. Influx = influx;
  22. Prometheus = prometheus;
  23. Timescale = timescale;
  24. Aliases = aliases;
  25. HiddenSensors = hiddenSensors;
  26. Influx2 = influx2;
  27. EnabledHardware = enabledHardware;
  28. }
  29. public string LookupName() => _nameLookup.LookupName();
  30. public TimeSpan Interval { get; }
  31. public GraphiteConfig Graphite { get; }
  32. public InfluxConfig Influx { get; }
  33. public Influx2Config Influx2 { get; }
  34. public EnabledHardware EnabledHardware { get; }
  35. public PrometheusConfig Prometheus { get; }
  36. public TimescaleConfig Timescale { get; }
  37. public Dictionary<string, string> Aliases { get; }
  38. public List<Regex> HiddenSensors { get; }
  39. public static MetricConfig ParseAppSettings(IAppConfig config)
  40. {
  41. if (!int.TryParse(config["interval"], out int seconds))
  42. {
  43. seconds = 5;
  44. }
  45. var interval = TimeSpan.FromSeconds(seconds);
  46. INameResolution nameLookup = NameLookup(config["name_lookup"] ?? "netbios");
  47. InstallCertificateVerification(config["certificate_verification"] ?? "True");
  48. var enabledHardware = ParseEnabledHardware(config);
  49. var type = config["type"] ?? "graphite";
  50. GraphiteConfig gconfig = null;
  51. InfluxConfig iconfig = null;
  52. PrometheusConfig pconfig = null;
  53. TimescaleConfig timescale = null;
  54. Influx2Config influx2 = null;
  55. switch (type.ToLowerInvariant())
  56. {
  57. case "graphite":
  58. gconfig = GraphiteConfig.ParseAppSettings(config);
  59. break;
  60. case "influxdb":
  61. case "influx":
  62. iconfig = InfluxConfig.ParseAppSettings(config);
  63. break;
  64. case "influx2":
  65. influx2 = Influx2Config.ParseAppSettings(config);
  66. break;
  67. case "prometheus":
  68. pconfig = PrometheusConfig.ParseAppSettings(config);
  69. break;
  70. case "timescale":
  71. case "timescaledb":
  72. timescale = TimescaleConfig.ParseAppSettings(config);
  73. break;
  74. }
  75. // Trim off the LibreHardwareMonitor "/name" suffix so that it is just the
  76. // the sensor ID.
  77. var aliases = config.GetKeys().Where(x => x.EndsWith("/name"))
  78. .ToDictionary(
  79. x => x.Remove(x.LastIndexOf("/name", StringComparison.Ordinal)),
  80. x => config[x]
  81. );
  82. // Do a similar trim with "/hidden" suffix except treat the prefix as a glob to hide
  83. // a group of sensors like if one wants to hide all power sensors they can do:
  84. // /*/power/*/hidden
  85. // Code to detect interpret strings as globs is shamelessly taken from stackoverflow:
  86. // https://stackoverflow.com/a/4146349/433785
  87. var hiddenSensors = config.GetKeys().Where(x => x.EndsWith("/hidden"))
  88. .Select(x => x.Remove(x.LastIndexOf("/hidden", StringComparison.Ordinal)))
  89. .Select(pattern => new Regex(
  90. "^" + Regex.Escape(pattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$",
  91. RegexOptions.IgnoreCase | RegexOptions.Singleline
  92. )).ToList();
  93. return new MetricConfig(interval, nameLookup, gconfig, iconfig, pconfig, timescale, aliases, hiddenSensors, influx2, enabledHardware);
  94. }
  95. private static EnabledHardware ParseEnabledHardware(IAppConfig config)
  96. {
  97. return new(
  98. config["/cpu/enabled"]?.ToLowerInvariant() != "false",
  99. config["/gpu/enabled"]?.ToLowerInvariant() != "false",
  100. config["/motherboard/enabled"]?.ToLowerInvariant() != "false",
  101. config["/ram/enabled"]?.ToLowerInvariant() != "false",
  102. config["/network/enabled"]?.ToLowerInvariant() != "false",
  103. config["/storage/enabled"]?.ToLowerInvariant() != "false",
  104. config["/controller/enabled"]?.ToLowerInvariant() != "false",
  105. config["/psu/enabled"]?.ToLowerInvariant() != "false",
  106. config["/battery/enabled"]?.ToLowerInvariant() != "false"
  107. );
  108. }
  109. private static INameResolution NameLookup(string lookup)
  110. {
  111. switch (lookup.ToLowerInvariant())
  112. {
  113. case "dns":
  114. return new DnsResolution();
  115. case "netbios":
  116. return new NetBiosResolution();
  117. default:
  118. return new StaticResolution(lookup);
  119. }
  120. }
  121. public static RemoteCertificateValidationCallback CertificateValidationCallback(string type)
  122. {
  123. switch (type.ToLowerInvariant())
  124. {
  125. // Do not change default .net behavior when given True
  126. case "true":
  127. return null;
  128. // Do not verify certificate
  129. case "false":
  130. return (sender, certificate, chain, errors) => true;
  131. // Else assume that it points to a file path of a self signed
  132. // certificate that we will check against
  133. default:
  134. var cert = new X509Certificate2(type);
  135. return (sender, certificate, chain, errors) =>
  136. errors == SslPolicyErrors.None ||
  137. string.Equals(cert.Thumbprint, certificate.GetCertHashString(), StringComparison.InvariantCultureIgnoreCase);
  138. }
  139. }
  140. public static void InstallCertificateVerification(string type)
  141. {
  142. ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallback(type);
  143. }
  144. public bool TryGetAlias(string v, out string alias) => Aliases.TryGetValue(v, out alias);
  145. public bool IsHidden(string id) => HiddenSensors.Any(x => x.IsMatch(id));
  146. }
  147. }