1.1.18 - Increase timeout for loading names and add send support logs

This commit is contained in:
Ryan Wagoner 2024-05-08 17:57:14 -04:00
parent d7eef51adf
commit f297c2fcaa
12 changed files with 90 additions and 53 deletions

View file

@ -44,9 +44,11 @@ namespace OmniLinkBridge
startTime = DateTime.Now; startTime = DateTime.Now;
Program.ShowSendLogsWarning();
using (LogContext.PushProperty("Telemetry", "Startup")) using (LogContext.PushProperty("Telemetry", "Startup"))
log.Information("Started version {Version} on {OperatingSystem} with {Modules}", log.Information("Started version {Version} in {Environment} on {OperatingSystem} with {Modules}",
Assembly.GetExecutingAssembly().GetName().Version, Environment.OSVersion, modules); Assembly.GetExecutingAssembly().GetName().Version, Program.GetEnvironment(), Environment.OSVersion, modules);
// Startup modules // Startup modules
foreach (IModule module in modules) foreach (IModule module in modules)

View file

@ -9,6 +9,11 @@ namespace OmniLinkBridge
{ {
public static class Extensions public static class Extensions
{ {
public static string Truncate(this string value, int maxLength)
{
return value?.Length > maxLength ? value.Substring(0, maxLength) : value;
}
public static double ToCelsius(this double f) public static double ToCelsius(this double f)
{ {
// Convert to celsius // Convert to celsius

View file

@ -10,6 +10,8 @@ namespace OmniLinkBridge
{ {
public static bool DebugSettings { get; set; } public static bool DebugSettings { get; set; }
public static bool UseEnvironment { get; set; } public static bool UseEnvironment { get; set; }
public static bool SendLogs { get; set; }
public static Guid SessionID { get; } = Guid.NewGuid();
// HAI / Leviton Omni Controller // HAI / Leviton Omni Controller
public static string controller_address; public static string controller_address;

View file

@ -402,6 +402,9 @@ namespace OmniLinkBridge.Modules
{ {
log.Debug("Publishing {type}", "buttons"); log.Debug("Publishing {type}", "buttons");
if (Global.mqtt_discovery_button_type == typeof(Switch))
log.Information("See {setting} for new option when publishing {type}", "mqtt_discovery_button_type", "buttons");
for (ushort i = 1; i <= OmniLink.Controller.Buttons.Count; i++) for (ushort i = 1; i <= OmniLink.Controller.Buttons.Count; i++)
{ {
clsButton button = OmniLink.Controller.Buttons[i]; clsButton button = OmniLink.Controller.Buttons[i];
@ -421,8 +424,6 @@ namespace OmniLinkBridge.Modules
if (Global.mqtt_discovery_button_type == typeof(Switch)) if (Global.mqtt_discovery_button_type == typeof(Switch))
{ {
log.Information("See {setting} for new option when publishing {type}", "mqtt_discovery_button_type", "buttons");
PublishAsync($"{Global.mqtt_discovery_prefix}/button/{Global.mqtt_prefix}/button{i}/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/button/{Global.mqtt_prefix}/button{i}/config", null);
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i}/config", PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i}/config",
JsonConvert.SerializeObject(button.ToConfigSwitch())); JsonConvert.SerializeObject(button.ToConfigSwitch()));

View file

@ -201,6 +201,8 @@ namespace OmniLinkBridge.Modules
tstat_timer.Start(); tstat_timer.Start();
OnConnect?.Invoke(this, new EventArgs()); OnConnect?.Invoke(this, new EventArgs());
Program.ShowSendLogsWarning();
} }
#endregion #endregion
@ -231,7 +233,8 @@ namespace OmniLinkBridge.Modules
await Task.Run(() => await Task.Run(() =>
{ {
nameWait.WaitOne(new TimeSpan(0, 0, 10)); if(!nameWait.WaitOne(new TimeSpan(0, 0, 10)))
log.Error("Timeout occurred waiting system formats");
}); });
} }
@ -244,7 +247,8 @@ namespace OmniLinkBridge.Modules
await Task.Run(() => await Task.Run(() =>
{ {
nameWait.WaitOne(new TimeSpan(0, 0, 10)); if(!nameWait.WaitOne(new TimeSpan(0, 0, 10)))
log.Error("Timeout occurred waiting for system troubles");
}); });
} }
@ -256,7 +260,8 @@ namespace OmniLinkBridge.Modules
await Task.Run(() => await Task.Run(() =>
{ {
nameWait.WaitOne(new TimeSpan(0, 0, 10)); if (!nameWait.WaitOne(new TimeSpan(0, 0, 30)))
log.Error("Timeout occurred waiting for named units {unitType}", type.ToString());
}); });
} }

View file

@ -4,7 +4,9 @@ using Serilog.Events;
using Serilog.Filters; using Serilog.Filters;
using Serilog.Formatting.Compact; using Serilog.Formatting.Compact;
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.ServiceProcess; using System.ServiceProcess;
@ -12,11 +14,11 @@ using System.Threading.Tasks;
namespace OmniLinkBridge namespace OmniLinkBridge
{ {
class Program internal class Program
{ {
static CoreServer server; private static CoreServer server;
static int Main(string[] args) private static int Main(string[] args)
{ {
bool interactive = false; bool interactive = false;
@ -55,6 +57,10 @@ namespace OmniLinkBridge
case "-ll": case "-ll":
Enum.TryParse(args[++i], out log_level); Enum.TryParse(args[++i], out log_level);
break; break;
case "-ld":
Global.DebugSettings = true;
Global.SendLogs = true;
break;
case "-s": case "-s":
Global.webapi_subscriptions_file = args[++i]; Global.webapi_subscriptions_file = args[++i];
break; break;
@ -64,6 +70,12 @@ namespace OmniLinkBridge
} }
} }
if (string.Compare(Environment.GetEnvironmentVariable("SEND_LOGS"), "1") == 0)
{
Global.DebugSettings = true;
Global.SendLogs = true;
}
config_file = GetFullPath(config_file); config_file = GetFullPath(config_file);
Global.webapi_subscriptions_file = GetFullPath(Global.webapi_subscriptions_file ?? "WebSubscriptions.json"); Global.webapi_subscriptions_file = GetFullPath(Global.webapi_subscriptions_file ?? "WebSubscriptions.json");
@ -76,7 +88,7 @@ namespace OmniLinkBridge
var log_config = new LoggerConfiguration() var log_config = new LoggerConfiguration()
.MinimumLevel.Verbose() .MinimumLevel.Verbose()
.Enrich.WithProperty("Application", "OmniLinkBridge") .Enrich.WithProperty("Application", "OmniLinkBridge")
.Enrich.WithProperty("Session", Guid.NewGuid()) .Enrich.WithProperty("Session", Global.SessionID)
.Enrich.With<ControllerEnricher>() .Enrich.With<ControllerEnricher>()
.Enrich.FromLogContext(); .Enrich.FromLogContext();
@ -92,7 +104,10 @@ namespace OmniLinkBridge
rollingInterval: RollingInterval.Day, retainedFileCountLimit: 15)); rollingInterval: RollingInterval.Day, retainedFileCountLimit: 15));
} }
if (UseTelemetry()) if (Global.SendLogs)
log_config = log_config.WriteTo.Logger(lc => lc
.WriteTo.Http("https://telemetry.excalibur-partners.com"));
else if (UseTelemetry())
log_config = log_config.WriteTo.Logger(lc => lc log_config = log_config.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(Matching.WithProperty("Telemetry")) .Filter.ByIncludingOnly(Matching.WithProperty("Telemetry"))
.WriteTo.Http("https://telemetry.excalibur-partners.com")); .WriteTo.Http("https://telemetry.excalibur-partners.com"));
@ -155,7 +170,7 @@ namespace OmniLinkBridge
return 0; return 0;
} }
static string GetFullPath(string file) private static string GetFullPath(string file)
{ {
if (Path.IsPathRooted(file)) if (Path.IsPathRooted(file))
return file; return file;
@ -169,21 +184,38 @@ namespace OmniLinkBridge
args.Cancel = true; args.Cancel = true;
} }
static bool IsRunningOnMono() private static bool IsRunningOnMono()
{ {
return Type.GetType("Mono.Runtime") != null; return Type.GetType("Mono.Runtime") != null;
} }
static bool UseTelemetry() public static string GetEnvironment()
{
if (Environment.GetEnvironmentVariable("HASSIO_TOKEN") != null)
return "Home Assistant";
else if (IsRunningOnMono())
return Process.GetProcesses().Any(w => w.Id == 2) ? "Mono" : "Docker";
else
return "Native";
}
private static bool UseTelemetry()
{ {
return string.Compare(Environment.GetEnvironmentVariable("TELEMETRY_OPTOUT"), "1") != 0; return string.Compare(Environment.GetEnvironmentVariable("TELEMETRY_OPTOUT"), "1") != 0;
} }
static void ShowHelp() public static void ShowSendLogsWarning()
{
if (Global.SendLogs)
Log.Warning("SENDING LOGS TO DEVELOPER Controller: {ControllerID}, Session: {Session}",
Global.controller_id, Global.SessionID);
}
private static void ShowHelp()
{ {
Console.WriteLine( Console.WriteLine(
AppDomain.CurrentDomain.FriendlyName + " [-c config_file] [-e] [-d] [-j] [-s subscriptions_file]\n" + AppDomain.CurrentDomain.FriendlyName + " [-c config_file] [-e] [-d] [-j] [-s subscriptions_file]\n" +
"\t[-lf log_file|disable] [-lj [-ll verbose|debug|information|warning|error] [-i]\n" + "\t[-lf log_file|disable] [-lj [-ll verbose|debug|information|warning|error] [-ld] [-i]\n" +
"\t-c Specifies the configuration file. Default is OmniLinkBridge.ini\n" + "\t-c Specifies the configuration file. Default is OmniLinkBridge.ini\n" +
"\t-e Check environment variables for configuration settings\n" + "\t-e Check environment variables for configuration settings\n" +
"\t-d Show debug ouput for configuration loading\n" + "\t-d Show debug ouput for configuration loading\n" +
@ -191,8 +223,14 @@ namespace OmniLinkBridge
"\t-lf Specifies the rolling log file. Retention is 15 days. Default is log.txt.\n" + "\t-lf Specifies the rolling log file. Retention is 15 days. Default is log.txt.\n" +
"\t-lj Write logs as CLEF (compact log event format) JSON.\n" + "\t-lj Write logs as CLEF (compact log event format) JSON.\n" +
"\t-ll Minimum level at which events will be logged. Default is information.\n" + "\t-ll Minimum level at which events will be logged. Default is information.\n" +
"\t-ld Send logs to developer. ONLY USE WHEN ASKED.\n" +
"\t Also enabled by setting a SEND_LOGS environment variable to 1.\n" +
"\t-i Run in interactive mode"); "\t-i Run in interactive mode");
Console.WriteLine(
"\nVersion: " + Assembly.GetExecutingAssembly().GetName().Version +
"\nEnvironment: " + GetEnvironment());
Console.WriteLine( Console.WriteLine(
"\nOmniLink Bridge collects anonymous telemetry data to help improve the software.\n" + "\nOmniLink Bridge collects anonymous telemetry data to help improve the software.\n" +
"You can opt of telemetry by setting a TELEMETRY_OPTOUT environment variable to 1."); "You can opt of telemetry by setting a TELEMETRY_OPTOUT environment variable to 1.");

View file

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.17.0")] [assembly: AssemblyVersion("1.1.18.0")]
[assembly: AssemblyFileVersion("1.1.17.0")] [assembly: AssemblyFileVersion("1.1.18.0")]

View file

@ -59,7 +59,7 @@ namespace OmniLinkBridge
// mySQL Logging // mySQL Logging
Global.mysql_logging = settings.ValidateBool("mysql_logging"); Global.mysql_logging = settings.ValidateBool("mysql_logging");
Global.mysql_connection = settings.CheckEnv("mysql_connection"); Global.mysql_connection = settings.CheckEnv("mysql_connection", true);
// Web Service // Web Service
Global.webapi_enabled = settings.ValidateBool("webapi_enabled"); Global.webapi_enabled = settings.ValidateBool("webapi_enabled");
@ -77,8 +77,8 @@ namespace OmniLinkBridge
{ {
Global.mqtt_server = settings.CheckEnv("mqtt_server"); Global.mqtt_server = settings.CheckEnv("mqtt_server");
Global.mqtt_port = settings.ValidatePort("mqtt_port"); Global.mqtt_port = settings.ValidatePort("mqtt_port");
Global.mqtt_username = settings.CheckEnv("mqtt_username"); Global.mqtt_username = settings.CheckEnv("mqtt_username", true);
Global.mqtt_password = settings.CheckEnv("mqtt_password"); Global.mqtt_password = settings.CheckEnv("mqtt_password", true);
Global.mqtt_prefix = settings.CheckEnv("mqtt_prefix") ?? "omnilink"; Global.mqtt_prefix = settings.CheckEnv("mqtt_prefix") ?? "omnilink";
Global.mqtt_discovery_prefix = settings.CheckEnv("mqtt_discovery_prefix") ?? "homeassistant"; Global.mqtt_discovery_prefix = settings.CheckEnv("mqtt_discovery_prefix") ?? "homeassistant";
Global.mqtt_discovery_name_prefix = settings.CheckEnv("mqtt_discovery_name_prefix") ?? string.Empty; Global.mqtt_discovery_name_prefix = settings.CheckEnv("mqtt_discovery_name_prefix") ?? string.Empty;
@ -107,27 +107,29 @@ namespace OmniLinkBridge
{ {
Global.mail_tls = settings.ValidateBool("mail_tls"); Global.mail_tls = settings.ValidateBool("mail_tls");
Global.mail_port = settings.ValidatePort("mail_port"); Global.mail_port = settings.ValidatePort("mail_port");
Global.mail_username = settings.CheckEnv("mail_username"); Global.mail_username = settings.CheckEnv("mail_username", true);
Global.mail_password = settings.CheckEnv("mail_password"); Global.mail_password = settings.CheckEnv("mail_password", true);
Global.mail_from = settings.ValidateMailFrom("mail_from"); Global.mail_from = settings.ValidateMailFrom("mail_from");
Global.mail_to = settings.ValidateMailTo("mail_to"); Global.mail_to = settings.ValidateMailTo("mail_to");
} }
// Prowl Notifications // Prowl Notifications
Global.prowl_key = settings.ValidateMultipleStrings("prowl_key"); Global.prowl_key = settings.ValidateMultipleStrings("prowl_key", true);
// Pushover Notifications // Pushover Notifications
Global.pushover_token = settings.CheckEnv("pushover_token"); Global.pushover_token = settings.CheckEnv("pushover_token", true);
Global.pushover_user = settings.ValidateMultipleStrings("pushover_user"); Global.pushover_user = settings.ValidateMultipleStrings("pushover_user", true);
} }
private static string CheckEnv(this NameValueCollection settings, string name) private static string CheckEnv(this NameValueCollection settings, string name, bool sensitive = false)
{ {
string env = Global.UseEnvironment ? Environment.GetEnvironmentVariable(name.ToUpper()) : null; string env = Global.UseEnvironment ? Environment.GetEnvironmentVariable(name.ToUpper()) : null;
string value = !string.IsNullOrEmpty(env) ? env : settings[name]; string value = !string.IsNullOrEmpty(env) ? env : settings[name];
if (Global.DebugSettings) if (Global.DebugSettings)
log.Debug((!string.IsNullOrEmpty(env) ? "ENV" : "CONF").PadRight(5) + $"{name}: {value}"); log.Debug("{ConfigType} {ConfigName}: {ConfigValue}",
(!string.IsNullOrEmpty(env) ? "ENV" : "CONF").PadRight(4), name,
sensitive && value != null ? value.Truncate(3) + "***MASKED***" : value);
return value; return value;
} }
@ -242,7 +244,7 @@ namespace OmniLinkBridge
private static string ValidateEncryptionKey(this NameValueCollection settings, string section) private static string ValidateEncryptionKey(this NameValueCollection settings, string section)
{ {
string value = settings.CheckEnv(section).Replace("-",""); string value = settings.CheckEnv(section, true).Replace("-","");
if (string.IsNullOrEmpty(value) || value.Length != 16) if (string.IsNullOrEmpty(value) || value.Length != 16)
{ {
@ -339,14 +341,14 @@ namespace OmniLinkBridge
} }
} }
private static string[] ValidateMultipleStrings(this NameValueCollection settings, string section) private static string[] ValidateMultipleStrings(this NameValueCollection settings, string section, bool sensitive = false)
{ {
try try
{ {
if (settings.CheckEnv(section) == null) if (settings.CheckEnv(section, true) == null)
return new string[] { }; return new string[] { };
return settings.CheckEnv(section).Split(','); return settings.CheckEnv(section, sensitive).Split(',');
} }
catch catch
{ {

View file

@ -1,10 +1,4 @@
using System; namespace OmniLinkBridge.WebAPI
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OmniLinkBridge.WebAPI
{ {
public enum DeviceType public enum DeviceType
{ {

View file

@ -1,9 +1,4 @@
using HAI_Shared; using HAI_Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OmniLinkBridge.WebAPI namespace OmniLinkBridge.WebAPI
{ {

View file

@ -1,5 +1,4 @@
using HAI_Shared; using HAI_Shared;
using OmniLinkBridge.WebAPI;
using Serilog; using Serilog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View file

@ -1,10 +1,4 @@
using System; namespace OmniLinkBridge.WebAPI
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OmniLinkBridge.WebAPI
{ {
public class OverrideZone public class OverrideZone
{ {