From 555059a2a95ba329898d3ceb5504d4b827417dec Mon Sep 17 00:00:00 2001 From: 500Foods Date: Tue, 14 Nov 2023 20:29:57 -0800 Subject: [PATCH] Common Updates - Added LogEvent and LogException functions - Added SendActivityLog function - Various updates to bring this in line with other XData servers --- HexaGongsX.dpr => HexaGongsServer.dpr | 2 +- HexaGongsX.dproj => HexaGongsServer.dproj | 28 +- HexaGongsServer.res | Bin 0 -> 6876 bytes Unit2.dfm | 11 +- Unit2.pas | 310 ++++++++++++++++++---- 5 files changed, 278 insertions(+), 73 deletions(-) rename HexaGongsX.dpr => HexaGongsServer.dpr (94%) rename HexaGongsX.dproj => HexaGongsServer.dproj (98%) create mode 100644 HexaGongsServer.res diff --git a/HexaGongsX.dpr b/HexaGongsServer.dpr similarity index 94% rename from HexaGongsX.dpr rename to HexaGongsServer.dpr index 1fb9d39..e3bcd6e 100644 --- a/HexaGongsX.dpr +++ b/HexaGongsServer.dpr @@ -1,4 +1,4 @@ -program HexaGongsX; +program HexaGongsServer; uses Vcl.Forms, diff --git a/HexaGongsX.dproj b/HexaGongsServer.dproj similarity index 98% rename from HexaGongsX.dproj rename to HexaGongsServer.dproj index 9402ff1..3c45f83 100644 --- a/HexaGongsX.dproj +++ b/HexaGongsServer.dproj @@ -3,7 +3,7 @@ {B7FA4D30-BDBC-4EE9-B033-9D8BA9062E07} 18.7 VCL - HexaGongsX.dpr + HexaGongsServer.dpr True Release Win64 @@ -68,7 +68,7 @@ System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) $(BDS)\bin\delphi_PROJECTICON.ico $(BDS)\bin\delphi_PROJECTICNS.icns - HexaGongsX + HexaGongsServer DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;FmxTeeUI926;VCLTMSFNCChartPkgDXE12;vclactnband;vclFireDAC;emsclientfiredac;tethering;svnui;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;TMSQueryStudio;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;JSExtend;vcltouch;rbUSERDesign2126;FMXTMSFNCUIPackPkgDXE12;vcldb;bindcompfmx;svn;TMSWEBCorePkgLibDXE12;DBXOracleDriver;TMSCloudPkgDXE12;inetdb;IcsFmxD103Run;CEF4Delphi;FMXTMSFNCWebSocketPkgDXE12;IcsVclD103Run;rbTC2126;FMXTMSFNCWXPackPkgDXE12;emsedge;fmx;FireDACIBDriver;fmxdae;vclib;rbBDE2126;FireDACDBXDriver;dbexpress;IndyCore;DCEF_XE5;xdata;vclx;dsnap;emsclient;DataSnapCommon;rbRCL2126;FireDACCommon;VCLTMSFNCUIPackPkgDXE12;RESTBackendComponents;DataSnapConnectors;TMSCloudPkgDEDXE12;VCLRESTComponents;soapserver;vclie;FMXTeeDB926;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;CData.QuickBooksOnline.D26;FireDACCommonODBC;FireDACCommonDriver;VCLTMSFNCCorePkgDXE12;DataSnapClient;inet;rbTCUI2126;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;sparkle;tmsbcl;IndySystem;FireDACDb2Driver;VCLTMSFNCDashboardPackPkgDXE12;FMXTee926;dsnapcon;VCLTMSFNCMapsPkgDXE12;FMXTMSFNCCorePkgDXE12;TMSWorkflow;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;FMXTMSFNCMapsPkgDXE12;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;advmemopkgdXE12;DBXOdbcDriver;FireDACTDataDriver;TMSDiagram;soaprtl;DbxCommonDriver;FMXTMSFNCDashboardPackPkgDXE12;ibxpress;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;ibxbindings;DBXSybaseASADriver;CustomIPTransport;vcldsnap;VCLTMSFNCWebSocketPkgDXE12;rbIDE2126;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;EurekaLogCore;rbCloudSC2126;bindcompvcl;IcsCommonD103Run;rbUSER2126;TMSCryptoPkgDXE12;dclTMSQueryStudio;TMSWEBCorePkgDXE12;dbxcds;VclSmp;adortl;FireDACODBCDriver;VCLTMSFNCWXPackPkgDXE12;DataSnapIndy10ServerTransport;aurelius;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;TMSCryptoPkgDEDXE12;FMXTMSFNCChartPkgDXE12;DataSnapServerMidas;$(DCC_UsePackage) @@ -164,7 +164,7 @@ - HexaGongsX.dpr + HexaGongsServer.dpr TeeChart Standard 2022 Components @@ -177,28 +177,28 @@ - + - HexaGongsX.exe + Assets\ + Logo44x44.png true - - - HexaGongsX.exe + + + HexaGongsServer.exe true - - - HexaGongsX.exe + + + HexaGongsServer.exe true - + - Assets\ - Logo44x44.png + HexaGongsServer.exe true diff --git a/HexaGongsServer.res b/HexaGongsServer.res new file mode 100644 index 0000000000000000000000000000000000000000..468ae2ea7af72d72540852eddaff64b33108acfd GIT binary patch literal 6876 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 15) then + begin + LastException := Now; + SendActivityLog('Exception Detected'); + end; +end; + +procedure TMainForm.SendActivityLog(Subject: String); +var + SMTP1: TIdSMTP; + Msg1: TIdMessage; + Addr1: TIdEmailAddressItem; + Html1: TIdMessageBuilderHtml; + SMTPResult: WideString; +begin + if not(MailServerAvailable) then + begin + LogEvent('WARNING: '+Subject+' e-mail not sent (Mail services not configured)'); + end + else + begin + + // Send warning email + Msg1 := nil; + Addr1 := nil; + SMTP1 := TIdSMTP.Create(nil); + SMTP1.Host := MainForm.MailServerHost; + SMTP1.Port := MainForm.MailServerPort; + SMTP1.Username := MainForm.MailServerUser; + SMTP1.Password := MainForm.MailServerPass; + + try + Html1 := TIdMessageBuilderHtml.Create; + try + Html1.Html.Add(''); + Html1.Html.Add(''); + Html1.Html.Add(''); + Html1.Html.Add('
');
+        Html1.Html.Add(mmInfo.Lines.Text);
+        Html1.Html.Add('
'); + Html1.Html.Add(''); + Html1.HtmlCharSet := 'utf-8'; + + Msg1 := Html1.NewMessage(nil); + + // Startup should be < 10s but otherwise send the running time + if MillisecondsBetween(Now, AppStartup) < 10000 + then Msg1.Subject := '['+GetEnvironmentVariable('COMPUTERNAME')+'] '+Subject+': '+MainForm.Caption+' ('+IntToStr(MillisecondsBetween(Now, AppStartup))+'ms)' + else Msg1.Subject := '['+GetEnvironmentVariable('COMPUTERNAME')+'] '+Subject+': '+MainForm.Caption+' ('+FormatDateTime('hh:nn:ss', Now - AppStartup)+'}'; + + Msg1.From.Text := MainForm.MailServerFrom; + Msg1.From.Name := MainForm.MailServerName; + + Addr1 := Msg1.Recipients.Add; + Addr1.Address := MainForm.MailserverFrom; + + SMTP1.Connect; + try + try + SMTP1.Send(Msg1); + except on E: Exception do + begin + SMTPResult := SMTPResult+'[ '+E.ClassName+' ] '+E.Message+Chr(10); + end; + end; + finally + SMTP1.Disconnect(); + end; + finally + Addr1.Free; + Msg1.Free; + Html1.Free; + end; + except on E: Exception do + begin + SMTPResult := SMTPResult+'[ '+E.ClassName+' ] '+E.Message+Chr(10); + end; + end; + SMTP1.Free; + + if SMTPResult = '' + then LogEvent('NOTICE: '+Subject+' e-mail sent to '+MailServerName+' <'+MailServerFrom+'>') + else + begin + LogEvent('WARNING: '+Subject+' e-mail to '+MailServerName+' <'+MailServerFrom+'> FAILED.'); + LogEvent('WARNING: SMTP Error: '+SMTPResult); + end; + end; +end; procedure TMainForm.tmrInitTimer(Sender: TObject); var @@ -334,7 +510,7 @@ procedure TMainForm.tmrInitTimer(Sender: TObject); GetIPAddresses(IPAddresses); // Load JSON Configuration - mmINfo.Lines.Add('Loading Configuration ...'); + LogEvent('Loading Configuration.'); AppConfigFile := StringReplace(ExtractFileName(ParamStr(0)),'exe','json',[]); i := 0; while i < AppParameters.Count do @@ -348,18 +524,17 @@ procedure TMainForm.tmrInitTimer(Sender: TObject); begin try ConfigFile.LoadFromFile(AppConfigFile); - mmInfo.Lines.Add('...Configuration File Loaded: '+AppConfigFile); + LogEvent('- Configuration File Loaded: '+AppConfigFile); AppConfiguration := TJSONObject.ParseJSONValue(ConfigFile.Text) as TJSONObject; except on E: Exception do begin - mmInfo.Lines.Add('...Configuration File Error: '+AppConfigFile); - mmInfo.Lines.Add('...['+E.ClassName+'] '+E.Message); + LogException('Configuration File Error', E.ClassName, E.Message, AppConfigFile); end; end; end else // File doesn't exist begin - mmInfo.Lines.Add('...Configuration File Not Found: '+AppConfigFile); + LogEvent('- Configuration File Not Found: '+AppConfigFile); end; ConfigFile.Free; Application.ProcessMessages; @@ -367,12 +542,31 @@ procedure TMainForm.tmrInitTimer(Sender: TObject); if Appconfiguration = nil then begin // Create an empty AppConfiguration - mmInfo.Lines.Add('...Using Default Configuration'); + LogEvent('- Using Default Configuration'); AppConfiguration := TJSONObject.Create; AppConfiguration.AddPair('BaseURL','http://+:65432/hexagongs'); end; - mmInfo.Lines.Add('Done.'); - mmInfo.Lines.Add(''); + + // Get Mail Configuration + MailServerAvailable := False; + if AppConfiguration.GetValue('Mail Services') <> nil then + begin + MailServerAvailable := True; + MailServerHost := ((AppConfiguration.GetValue('Mail Services') as TJSONObject).GetValue('SMTP Host') as TJSONString).Value; + MailServerPort := ((AppConfiguration.GetValue('Mail Services') as TJSONObject).GetValue('SMTP Port') as TJSONNumber).AsInt; + MailServerUser := ((AppConfiguration.GetValue('Mail Services') as TJSONObject).GetValue('SMTP User') as TJSONString).Value; + MailServerPass := ((AppConfiguration.GetValue('Mail Services') as TJSONObject).GetValue('SMTP Pass') as TJSONString).Value; + MailServerFrom := ((AppConfiguration.GetValue('Mail Services') as TJSONObject).GetValue('SMTP From') as TJSONString).Value; + MailServerName := ((AppConfiguration.GetValue('Mail Services') as TJSONObject).GetValue('SMTP Name') as TJSONString).Value; + LogEvent('- SMTP Mail Server: '+MailServerHost+' / '+IntToStr(MailServerPort)); + end + else + begin + LogEvent('- SMTP Mail Server: Unavailable'); + end; + + LogEvent('Done.'); + LogEvent(''); Application.ProcessMessages; ServerContainer.XDataServer.BaseURL := (AppConfiguration.getValue('BaseURL') as TJSONString).Value; @@ -418,13 +612,13 @@ procedure TMainForm.tmrStartTimer(Sender: TObject); then AppCacheFolder := AppCacheFolder + '/'; if not(ForceDirectories(AppCacheFolder)) - then mmInfo.Lines.Add('ERROR Initializing Cache Folder: '+AppCacheFolder); + then LogEvent('ERROR Initializing Cache Folder: '+AppCacheFolder); if not(ForceDirectories(AppCacheFolder+'images')) - then mmInfo.Lines.Add('ERROR Initializing Cache Folder: '+AppCacheFolder+'images'); + then LogEvent('ERROR Initializing Cache Folder: '+AppCacheFolder+'images'); if not(ForceDirectories(AppCacheFolder+'images/ai')) - then mmInfo.Lines.Add('ERROR Initializing Cache Folder: '+AppCacheFolder+'images/ai'); + then LogEvent('ERROR Initializing Cache Folder: '+AppCacheFolder+'images/ai'); if not(ForceDirectories(AppCacheFolder+'images/people')) - then mmInfo.Lines.Add('ERROR Initializing Cache Folder: '+AppCacheFolder+'images/people'); + then LogEvent('ERROR Initializing Cache Folder: '+AppCacheFolder+'images/people'); CacheFolderDirs := FloatToStrF(Length(TDirectory.GetDirectories(AppCacheFolder,'*',TsearchOption.soAllDirectories)),ffNumber,8,0); CacheFolderList := TDirectory.GetFiles(AppCacheFolder,'*.*',TsearchOption.soAllDirectories); @@ -434,47 +628,47 @@ procedure TMainForm.tmrStartTimer(Sender: TObject); CacheFolderSize := CacheFolderSize + (FileSizeByName(CacheFolderList[i]) / 1024 / 1024); // Display System Values - mmInfo.Lines.Add('App Name: '+AppName); - mmInfo.Lines.Add('...Version: '+AppVersion); - mmInfo.Lines.Add('...Release: '+FormatDateTime('yyyy-mmm-dd (ddd) hh:nn:ss', AppRelease)); - mmInfo.Lines.Add('...Release UTC: '+FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', AppReleaseUTC)); - mmInfo.Lines.Add('...Server Time: '+FormatDateTime('yyyy-mmm-dd (ddd) hh:nn:ss', Now)); - mmInfo.Lines.Add('...TimeZone: '+AppTimeZone); - mmInfo.Lines.Add('...TimeZone Offset: '+IntToStr(AppTimeZoneOffset)+'m'); - mmInfo.Lines.Add('...Base URL: '+ServerContainer.XDataServer.BaseURL); - mmInfo.Lines.Add('...File Name: '+AppFileName); - mmInfo.Lines.Add('...File Size: '+Format('%.1n',[AppFileSize / 1024 / 1024])+' MB'); - mmInfo.Lines.Add('...Cache Folder: '+AppCacheFolder); - mmInfo.Lines.Add('...Cache Statistics: '+CacheFolderDirs+' Folders, '+CacheFolderFiles+' Files, '+FloatToStrF(CacheFolderSize,ffNumber,8,1)+' MB'); - mmInfo.Lines.Add('...Memory Usage: '+Format('%.1n',[GetMemoryUsage / 1024 / 1024])+' MB'); - - mmInfo.Lines.Add('...Parameters:'); + LogEvent('App Name: '+AppName); + LogEvent('...Version: '+AppVersion); + LogEvent('...Release: '+FormatDateTime('yyyy-mmm-dd (ddd) hh:nn:ss', AppRelease)); + LogEvent('...Release UTC: '+FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', AppReleaseUTC)); + LogEvent('...Server Time: '+FormatDateTime('yyyy-mmm-dd (ddd) hh:nn:ss', Now)); + LogEvent('...TimeZone: '+AppTimeZone); + LogEvent('...TimeZone Offset: '+IntToStr(AppTimeZoneOffset)+'m'); + LogEvent('...Base URL: '+ServerContainer.XDataServer.BaseURL); + LogEvent('...File Name: '+AppFileName); + LogEvent('...File Size: '+Format('%.1n',[AppFileSize / 1024 / 1024])+' MB'); + LogEvent('...Cache Folder: '+AppCacheFolder); + LogEvent('...Cache Statistics: '+CacheFolderDirs+' Folders, '+CacheFolderFiles+' Files, '+FloatToStrF(CacheFolderSize,ffNumber,8,1)+' MB'); + LogEvent('...Memory Usage: '+Format('%.1n',[GetMemoryUsage / 1024 / 1024])+' MB'); + + LogEvent('...Parameters:'); i := 0; while i < AppParameters.Count do begin - mmInfo.Lines.Add(' '+StringReplace(AppParameters[i],'"','',[rfReplaceAll])); + LogEvent(' '+StringReplace(AppParameters[i],'"','',[rfReplaceAll])); i := i + 1; end; - mmInfo.Lines.Add('...IP Addresses:'); + LogEvent('...IP Addresses:'); i := 0; while i < IPAddresses.Count do begin - mmInfo.Lines.Add(' '+StringReplace(IPAddresses[i],'"','',[rfReplaceAll])); + LogEvent(' '+StringReplace(IPAddresses[i],'"','',[rfReplaceAll])); i := i + 1; end; // Are chat services avialable? if (AppConfiguration.GetValue('Chat Interface') as TJSONArray) = nil - then mmInfo.Lines.Add('...Chat: UNAVAILABLE') + then LogEvent('...Chat: UNAVAILABLE') else begin - mmInfo.Lines.Add('...Chat:'); + LogEvent('...Chat:'); i := 0; while i < (AppConfiguration.GetValue('Chat Interface') as TJSONArray).Count do begin; - mmInfo.Lines.Add(' '+(((AppConfiguration.GetValue('Chat Interface') as TJSONArray).items[i] as TJSONObject).getValue('Name') as TJSONString).Value); + LogEvent(' '+(((AppConfiguration.GetValue('Chat Interface') as TJSONArray).items[i] as TJSONObject).getValue('Name') as TJSONString).Value); i := i + 1; end; end; @@ -495,11 +689,11 @@ procedure TMainForm.tmrStartTimer(Sender: TObject); if length(IconFiles) = 0 then begin - mmInfo.Lines.Add('...No Icon Sets Loaded: None Found.'); + LogEvent('...No Icon Sets Loaded: None Found.'); end else begin - mmInfo.Lines.Add('...Loading '+IntToStr(Length(IconFiles))+' Icon Sets:'); + LogEvent('...Loading '+IntToStr(Length(IconFiles))+' Icon Sets:'); IconFile := TStringList.Create; for i := 0 to Length(IconFiles)-1 do @@ -514,7 +708,7 @@ procedure TMainForm.tmrStartTimer(Sender: TObject); IconTotal := IconTotal + IconCount; // Log what we're doing - mmInfo.Lines.Add(' ['+TPath.GetFileName(IconFiles[i])+'] '+ + LogEvent(' ['+TPath.GetFileName(IconFiles[i])+'] '+ ((IconJSON.GetValue('info') as TJSONObject).GetValue('name') as TJSONString).Value+' - '+ IntToStr(IconCount)+' Icons'); @@ -550,7 +744,7 @@ procedure TMainForm.tmrStartTimer(Sender: TObject); end; IconFile.Free; end; - mmInfo.Lines.Add(' Icons Loaded: '+FloatToStrF(IconTotal,ffNumber,10,0)); + LogEvent(' Icons Loaded: '+FloatToStrF(IconTotal,ffNumber,10,0)); // We don't need to do anything else with this, so we'll store it as a string and // then return just that when asked for this ata. @@ -570,11 +764,11 @@ procedure TMainForm.tmrStartTimer(Sender: TObject); if length(AudioClips) = 0 then begin - mmInfo.Lines.Add('...No Audio Clips Loaded: None Found.'); + LogEvent('...No Audio Clips Loaded: None Found.'); end else begin - mmInfo.Lines.Add('...Found '+IntToStr(Length(AudioClips))+' Audio Clips'); + LogEvent('...Found '+IntToStr(Length(AudioClips))+' Audio Clips'); for i := 0 to Length(AudioClips)-1 do begin ClipName := StringReplace(copy(AudioClips[i],length(AppAudioClipsFolder)+1,length(AudioClips[i])),'\','/',[rfReplaceAll]); @@ -595,14 +789,16 @@ procedure TMainForm.tmrStartTimer(Sender: TObject); end; - mmInfo.Lines.Add('...Memory Usage: '+Format('%.1n',[GetMemoryUsage / 1024 / 1024])+' MB'); - mmInfo.Lines.Add('Done.'); - mmInfo.Lines.Add(''); + LogEvent('...Memory Usage: '+Format('%.1n',[GetMemoryUsage / 1024 / 1024])+' MB'); + LogEvent('Done.'); + LogEvent(''); // Start Server ServerContainer.SparkleHttpSysDispatcher.Active := True; UpdateGUI; + SendActivityLog('Startup Confirmation'); + // Cleanup ImageFile.Free; end; @@ -616,13 +812,13 @@ procedure TMainForm.UpdateGUI; btStop.Enabled := not btStart.Enabled; if ServerContainer.SparkleHttpSysDispatcher.Active then begin - mmInfo.Lines.Add('XData Server started at '+StringReplace( ServerContainer.XDataServer.BaseUrl, cHttp, cHttpLocalhost, [rfIgnoreCase])); - mmInfo.Lines.Add('SwaggerUI started at '+StringReplace( ServerContainer.XDataServer.BaseUrl, cHttp, cHttpLocalhost, [rfIgnoreCase])+'/swaggerui'); - mmInfo.Lines.Add('Redoc started at '+StringReplace( ServerContainer.XDataServer.BaseUrl, cHttp, cHttpLocalhost, [rfIgnoreCase])+'/redoc'); + LogEvent('XData Server started at '+StringReplace( ServerContainer.XDataServer.BaseUrl, cHttp, cHttpLocalhost, [rfIgnoreCase])); + LogEvent('SwaggerUI started at '+StringReplace( ServerContainer.XDataServer.BaseUrl, cHttp, cHttpLocalhost, [rfIgnoreCase])+'/swaggerui'); + LogEvent('Redoc started at '+StringReplace( ServerContainer.XDataServer.BaseUrl, cHttp, cHttpLocalhost, [rfIgnoreCase])+'/redoc'); end else begin - mmInfo.Lines.Add('XData Server stopped'); + LogEvent('XData Server stopped'); end; end;