1
0

MetricConfig.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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);
  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. );
  107. }
  108. private static INameResolution NameLookup(string lookup)
  109. {
  110. switch (lookup.ToLowerInvariant())
  111. {
  112. case "dns":
  113. return new DnsResolution();
  114. case "netbios":
  115. return new NetBiosResolution();
  116. default:
  117. return new StaticResolution(lookup);
  118. }
  119. }
  120. public static void InstallCertificateVerification(string type)
  121. {
  122. switch (type.ToLowerInvariant())
  123. {
  124. // Do not change default .net behavior when given True
  125. case "true":
  126. break;
  127. // Do not verify certificate
  128. case "false":
  129. ServicePointManager.ServerCertificateValidationCallback =
  130. (sender, certificate, chain, errors) => true;
  131. break;
  132. // Else assume that it points to a file path of a self signed
  133. // certificate that we will check against
  134. default:
  135. var cert = new X509Certificate2(type);
  136. ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) =>
  137. errors == SslPolicyErrors.None ||
  138. string.Equals(cert.Thumbprint, certificate.GetCertHashString(), StringComparison.InvariantCultureIgnoreCase);
  139. break;
  140. }
  141. }
  142. public bool TryGetAlias(string v, out string alias) => Aliases.TryGetValue(v, out alias);
  143. public bool IsHidden(string id) => HiddenSensors.Any(x => x.IsMatch(id));
  144. }
  145. }