Skip to content

Commit 989b7c5

Browse files
CopilotJusterZhu
andauthored
[REFACTOR] Standardize and Complete Full Lifecycle Tracing for Five Core Components (#173)
* Initial plan * feat: add full lifecycle GeneralTracer tracing to five core components - GeneralUpdate.Bowl: Add Info/Warn/Error/Fatal/Debug tracing across Bowl, AbstractStrategy, WindowStrategy, and LinuxStrategy for all execution stages (initialization, process startup, crash detection, backup/restore, cleanup) - GeneralUpdate.Extension: Link GeneralTracer.cs from Common into project; add comprehensive tracing to GeneralExtensionHost (constructors, QueryExtensionsAsync, DownloadExtensionAsync, UpdateExtensionAsync, InstallExtensionAsync) and DownloadQueueManager (Enqueue, ProcessQueueAsync, ProcessTaskAsync, CancelTask, Dispose) - GeneralUpdate.Core: Add lifecycle tracing to CompressMiddleware, HashMiddleware, PatchMiddleware; add key-step tracing to GeneralUpdateBootstrap.ExecuteWorkflowAsync and LaunchAsync; add pipeline construction/StartApp tracing to WindowsStrategy and LinuxStrategy - GeneralUpdate.ClientCore: Add lifecycle tracing to CompressMiddleware, HashMiddleware, PatchMiddleware; add pipeline/StartApp tracing to WindowsStrategy and LinuxStrategy; add comprehensive step tracing to SilentUpdateMode (StartAsync, PollLoopAsync, PrepareUpdateIfNeededAsync, OnProcessExit); add connection-state tracing to UpgradeHubService; add key-workflow tracing to GeneralClientBootstrap.ExecuteWorkflowAsync - GeneralUpdate.Drivelution: Add missing using directive and tracing to all static entry points in GeneralDrivelution (QuickUpdateAsync, ValidateAsync, GetDriversFromDirectoryAsync, GetPlatformInfo) Agent-Logs-Url: https://github.com/GeneralLibrary/GeneralUpdate/sessions/fab83fb2-df34-4932-b476-6a6a8299567b Co-authored-by: JusterZhu <11714536+JusterZhu@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JusterZhu <11714536+JusterZhu@users.noreply.github.com>
1 parent dd80393 commit 989b7c5

22 files changed

Lines changed: 465 additions & 54 deletions

src/c#/GeneralUpdate.Bowl/Bowl.cs

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using GeneralUpdate.Bowl.Strategys;
66
using GeneralUpdate.Common.Internal.Bootstrap;
77
using GeneralUpdate.Common.Internal.JsonContext;
8+
using GeneralUpdate.Common.Shared;
89
using GeneralUpdate.Common.Shared.Object;
910

1011
namespace GeneralUpdate.Bowl;
@@ -20,31 +21,60 @@ private Bowl() { }
2021

2122
private static void CreateStrategy()
2223
{
24+
GeneralTracer.Info("Bowl.CreateStrategy: detecting current OS platform.");
2325
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
26+
{
27+
GeneralTracer.Info("Bowl.CreateStrategy: Windows platform detected, creating WindowStrategy.");
2428
_strategy = new WindowStrategy();
25-
29+
}
30+
2631
if (_strategy == null)
32+
{
33+
GeneralTracer.Fatal("Bowl.CreateStrategy: unsupported operating system, no strategy created.");
2734
throw new PlatformNotSupportedException("Unsupported operating system");
35+
}
36+
37+
GeneralTracer.Info("Bowl.CreateStrategy: strategy created successfully.");
2838
}
29-
39+
3040
public static void Launch(MonitorParameter? monitorParameter = null)
3141
{
32-
monitorParameter ??= CreateParameter();
33-
CreateStrategy();
34-
_strategy?.SetParameter(monitorParameter);
35-
_strategy?.Launch();
42+
GeneralTracer.Info("Bowl.Launch: starting surveillance launch.");
43+
try
44+
{
45+
monitorParameter ??= CreateParameter();
46+
GeneralTracer.Info($"Bowl.Launch: monitor parameter resolved. ProcessNameOrId={monitorParameter.ProcessNameOrId}, TargetPath={monitorParameter.TargetPath}");
47+
CreateStrategy();
48+
_strategy?.SetParameter(monitorParameter);
49+
GeneralTracer.Info("Bowl.Launch: strategy parameter set, invoking Launch.");
50+
_strategy?.Launch();
51+
GeneralTracer.Info("Bowl.Launch: strategy Launch completed.");
52+
}
53+
catch (Exception ex)
54+
{
55+
GeneralTracer.Error("Bowl.Launch: exception occurred during surveillance launch.", ex);
56+
throw;
57+
}
3658
}
3759

3860
private static MonitorParameter CreateParameter()
3961
{
62+
GeneralTracer.Info("Bowl.CreateParameter: reading ProcessInfo from environment variable.");
4063
var json = Environments.GetEnvironmentVariable("ProcessInfo");
41-
if(string.IsNullOrWhiteSpace(json))
42-
throw new ArgumentNullException("ProcessInfo environment variable not set !");
43-
64+
if (string.IsNullOrWhiteSpace(json))
65+
{
66+
GeneralTracer.Fatal("Bowl.CreateParameter: ProcessInfo environment variable is not set.");
67+
throw new ArgumentNullException("ProcessInfo environment variable not set !");
68+
}
69+
4470
var processInfo = JsonSerializer.Deserialize<ProcessInfo>(json, ProcessInfoJsonContext.Default.ProcessInfo);
45-
if(processInfo == null)
71+
if (processInfo == null)
72+
{
73+
GeneralTracer.Fatal("Bowl.CreateParameter: failed to deserialize ProcessInfo JSON.");
4674
throw new ArgumentNullException("ProcessInfo json deserialize fail!");
47-
75+
}
76+
77+
GeneralTracer.Info($"Bowl.CreateParameter: ProcessInfo deserialized successfully. AppName={processInfo.AppName}, LastVersion={processInfo.LastVersion}");
4878
return new MonitorParameter
4979
{
5080
ProcessNameOrId = processInfo.AppName,

src/c#/GeneralUpdate.Bowl/Strategys/AbstractStrategy.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Diagnostics;
33
using System.IO;
44
using GeneralUpdate.Common.FileBasic;
5+
using GeneralUpdate.Common.Shared;
56

67
namespace GeneralUpdate.Bowl.Strategys;
78

@@ -14,17 +15,22 @@ internal abstract class AbstractStrategy : IStrategy
1415

1516
public virtual void Launch()
1617
{
18+
GeneralTracer.Info($"AbstractStrategy.Launch: starting inner application. App={_parameter.InnerApp}, Args={_parameter.InnerArguments}");
1719
Startup(_parameter.InnerApp, _parameter.InnerArguments);
20+
GeneralTracer.Info("AbstractStrategy.Launch: inner application process finished.");
1821
}
1922

2023
private void Startup(string appName, string arguments)
2124
{
25+
GeneralTracer.Info($"AbstractStrategy.Startup: preparing process. FileName={appName}");
2226
if (Directory.Exists(_parameter.FailDirectory))
2327
{
28+
GeneralTracer.Info($"AbstractStrategy.Startup: removing existing fail directory: {_parameter.FailDirectory}");
2429
StorageManager.DeleteDirectory(_parameter.FailDirectory);
2530
}
2631
Directory.CreateDirectory(_parameter.FailDirectory);
27-
32+
GeneralTracer.Info($"AbstractStrategy.Startup: fail directory created: {_parameter.FailDirectory}");
33+
2834
var startInfo = new ProcessStartInfo
2935
{
3036
FileName = appName,
@@ -39,15 +45,20 @@ private void Startup(string appName, string arguments)
3945
process.OutputDataReceived += OutputHandler;
4046
process.ErrorDataReceived += OutputHandler;
4147
process.Start();
48+
GeneralTracer.Info($"AbstractStrategy.Startup: process started. PID={process.Id}");
4249
process.BeginOutputReadLine();
4350
process.BeginErrorReadLine();
4451
process.WaitForExit(1000 * 10);
52+
GeneralTracer.Info($"AbstractStrategy.Startup: process exited. ExitCode={process.ExitCode}");
4553
}
4654

4755
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
4856
{
4957
var data = outLine.Data;
5058
if (!string.IsNullOrEmpty(data))
59+
{
60+
GeneralTracer.Debug($"AbstractStrategy.OutputHandler: {data}");
5161
OutputList.Add(data);
62+
}
5263
}
5364
}

src/c#/GeneralUpdate.Bowl/Strategys/LinuxStrategy.cs

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Linq;
66
using GeneralUpdate.Bowl.Internal;
7+
using GeneralUpdate.Common.Shared;
78

89
namespace GeneralUpdate.Bowl.Strategys;
910

@@ -24,15 +25,34 @@ internal class LinuxStrategy : AbstractStrategy
2425

2526
public override void Launch()
2627
{
27-
Install();
28-
base.Launch();
28+
GeneralTracer.Info("LinuxStrategy.Launch: starting Linux surveillance launch.");
29+
try
30+
{
31+
Install();
32+
GeneralTracer.Info("LinuxStrategy.Launch: procdump installation completed, invoking base launch.");
33+
base.Launch();
34+
GeneralTracer.Info("LinuxStrategy.Launch: launch lifecycle completed.");
35+
}
36+
catch (Exception ex)
37+
{
38+
GeneralTracer.Error("LinuxStrategy.Launch: exception occurred during Linux surveillance launch.", ex);
39+
throw;
40+
}
2941
}
3042

3143
private void Install()
3244
{
45+
GeneralTracer.Info("LinuxStrategy.Install: determining procdump package and running install script.");
3346
string scriptPath = "./install.sh";
3447
string packageFile = GetPacketName();
35-
48+
49+
if (string.IsNullOrEmpty(packageFile))
50+
{
51+
GeneralTracer.Warn("LinuxStrategy.Install: no matching procdump package found for the current Linux distribution.");
52+
return;
53+
}
54+
55+
GeneralTracer.Info($"LinuxStrategy.Install: executing install.sh with package={packageFile}.");
3656
ProcessStartInfo processStartInfo = new ProcessStartInfo()
3757
{
3858
FileName = "/bin/bash",
@@ -50,25 +70,33 @@ private void Install()
5070
string error = process.StandardError.ReadToEnd();
5171
process.WaitForExit();
5272

53-
Console.WriteLine("Output:");
54-
Console.WriteLine(output);
73+
if (!string.IsNullOrEmpty(output))
74+
GeneralTracer.Info($"LinuxStrategy.Install output: {output}");
5575

5676
if (!string.IsNullOrEmpty(error))
77+
GeneralTracer.Warn($"LinuxStrategy.Install error output: {error}");
78+
79+
if (process.ExitCode != 0)
5780
{
58-
Console.WriteLine("Error:");
59-
Console.WriteLine(error);
81+
GeneralTracer.Error($"LinuxStrategy.Install: install script exited with code {process.ExitCode}.");
82+
}
83+
else
84+
{
85+
GeneralTracer.Info("LinuxStrategy.Install: procdump installation succeeded.");
6086
}
6187
}
6288
catch (Exception e)
6389
{
64-
Console.WriteLine($"An error occurred: {e.Message}");
90+
GeneralTracer.Error("LinuxStrategy.Install: exception occurred while running install script.", e);
6591
}
6692
}
6793

6894
private string GetPacketName()
6995
{
96+
GeneralTracer.Info("LinuxStrategy.GetPacketName: detecting Linux distribution.");
7097
var packageFileName = string.Empty;
7198
var system = GetSystem();
99+
GeneralTracer.Info($"LinuxStrategy.GetPacketName: detected distribution={system.Name}, version={system.Version}.");
72100
if (_rocdumpAmd64.Contains(system.Name))
73101
{
74102
packageFileName = $"procdump_3.3.0_amd64.deb";
@@ -82,11 +110,17 @@ private string GetPacketName()
82110
packageFileName = $"procdump-3.3.0-0.cm2.x86_64.rpm";
83111
}
84112

113+
if (string.IsNullOrEmpty(packageFileName))
114+
GeneralTracer.Warn($"LinuxStrategy.GetPacketName: no matching package for distribution={system.Name}.");
115+
else
116+
GeneralTracer.Info($"LinuxStrategy.GetPacketName: resolved package={packageFileName}.");
117+
85118
return packageFileName;
86119
}
87120

88121
private LinuxSystem GetSystem()
89122
{
123+
GeneralTracer.Info("LinuxStrategy.GetSystem: reading /etc/os-release.");
90124
string osReleaseFile = "/etc/os-release";
91125
if (File.Exists(osReleaseFile))
92126
{
@@ -106,9 +140,11 @@ private LinuxSystem GetSystem()
106140
}
107141
}
108142

143+
GeneralTracer.Info($"LinuxStrategy.GetSystem: distro={distro}, version={version}.");
109144
return new LinuxSystem(distro, version);
110145
}
111-
146+
147+
GeneralTracer.Fatal("LinuxStrategy.GetSystem: /etc/os-release not found, cannot determine Linux distribution.");
112148
throw new FileNotFoundException("Cannot determine the Linux distribution. The /etc/os-release file does not exist.");
113149
}
114150
}

src/c#/GeneralUpdate.Bowl/Strategys/WindowStrategy.cs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using GeneralUpdate.Bowl.Internal;
77
using GeneralUpdate.Common.FileBasic;
88
using GeneralUpdate.Common.Internal.Bootstrap;
9+
using GeneralUpdate.Common.Shared;
910

1011
namespace GeneralUpdate.Bowl.Strategys;
1112

@@ -17,32 +18,48 @@ internal class WindowStrategy : AbstractStrategy
1718

1819
public override void Launch()
1920
{
21+
GeneralTracer.Info("WindowStrategy.Launch: initializing actions pipeline.");
2022
InitializeActions();
2123
_applicationsDirectory = Path.Combine(_parameter.TargetPath, "Applications", "Windows");
2224
_parameter.InnerApp = Path.Combine(_applicationsDirectory, GetAppName());
2325
var dmpFullName = Path.Combine(_parameter.FailDirectory, _parameter.DumpFileName);
2426
_parameter.InnerArguments = $"-e -ma {_parameter.ProcessNameOrId} {dmpFullName}";
27+
GeneralTracer.Info($"WindowStrategy.Launch: launching inner app={_parameter.InnerApp}, dumpFile={dmpFullName}.");
2528
//This method is used to launch scripts in applications.
2629
base.Launch();
30+
GeneralTracer.Info("WindowStrategy.Launch: base launch completed, executing final treatment.");
2731
ExecuteFinalTreatment();
32+
GeneralTracer.Info("WindowStrategy.Launch: launch lifecycle completed.");
2833
}
2934

30-
private string GetAppName() => RuntimeInformation.OSArchitecture switch
35+
private string GetAppName()
3136
{
32-
Architecture.X86 => "procdump.exe",
33-
Architecture.X64 => "procdump64.exe",
34-
_ => "procdump64a.exe"
35-
};
37+
var name = RuntimeInformation.OSArchitecture switch
38+
{
39+
Architecture.X86 => "procdump.exe",
40+
Architecture.X64 => "procdump64.exe",
41+
_ => "procdump64a.exe"
42+
};
43+
GeneralTracer.Info($"WindowStrategy.GetAppName: resolved procdump executable={name} for arch={RuntimeInformation.OSArchitecture}.");
44+
return name;
45+
}
3646

3747
private void ExecuteFinalTreatment()
3848
{
3949
var dumpFile = Path.Combine(_parameter.FailDirectory, _parameter.DumpFileName);
50+
GeneralTracer.Info($"WindowStrategy.ExecuteFinalTreatment: checking for dump file at {dumpFile}.");
4051
if (File.Exists(dumpFile))
4152
{
53+
GeneralTracer.Info($"WindowStrategy.ExecuteFinalTreatment: dump file found, executing {_actions.Count} remediation action(s).");
4254
foreach (var action in _actions)
4355
{
4456
action.Invoke();
4557
}
58+
GeneralTracer.Info("WindowStrategy.ExecuteFinalTreatment: all remediation actions completed.");
59+
}
60+
else
61+
{
62+
GeneralTracer.Info("WindowStrategy.ExecuteFinalTreatment: no dump file found, monitored process exited normally.");
4663
}
4764
}
4865

@@ -52,41 +69,58 @@ private void InitializeActions()
5269
_actions.Add(Export);
5370
_actions.Add(Restore);
5471
_actions.Add(SetEnvironment);
72+
GeneralTracer.Debug("WindowStrategy.InitializeActions: registered actions: CreateCrash, Export, Restore, SetEnvironment.");
5573
}
5674

5775
/// <summary>
5876
/// Export the crash output information from procdump.exe and the monitoring parameters of Bowl.
5977
/// </summary>
6078
private void CreateCrash()
6179
{
80+
GeneralTracer.Info("WindowStrategy.CreateCrash: serializing crash report.");
6281
var crash = new Crash
6382
{
6483
Parameter = _parameter,
6584
ProcdumpOutPutLines = OutputList
6685
};
6786
var failJsonPath = Path.Combine(_parameter.FailDirectory, _parameter.FailFileName);
6887
StorageManager.CreateJson(failJsonPath, crash, CrashJsonContext.Default.Crash);
88+
GeneralTracer.Info($"WindowStrategy.CreateCrash: crash report written to {failJsonPath}.");
6989
}
7090

7191
/// <summary>
7292
/// Export operating system information, system logs, and system driver information.
7393
/// </summary>
7494
private void Export()
7595
{
96+
GeneralTracer.Info("WindowStrategy.Export: exporting OS and system diagnostic information.");
7697
var batPath = Path.Combine(_applicationsDirectory, "export.bat");
77-
if(!File.Exists(batPath))
98+
if (!File.Exists(batPath))
99+
{
100+
GeneralTracer.Error($"WindowStrategy.Export: export.bat not found at {batPath}.");
78101
throw new FileNotFoundException("export.bat not found!");
79-
102+
}
103+
80104
Process.Start(batPath, _parameter.FailDirectory);
105+
GeneralTracer.Info($"WindowStrategy.Export: export.bat started targeting {_parameter.FailDirectory}.");
81106
}
82107

83108
/// <summary>
84109
/// Within the GeneralUpdate upgrade system, restore the specified backup version files to the current working directory.
85110
/// </summary>
86111
private void Restore()
87112
{
113+
GeneralTracer.Info($"WindowStrategy.Restore: checking work model. CurrentModel={_parameter.WorkModel}, ExpectedModel={WorkModel}.");
88114
if (string.Equals(_parameter.WorkModel, WorkModel))
115+
{
116+
GeneralTracer.Info($"WindowStrategy.Restore: restoring backup from {_parameter.BackupDirectory} to {_parameter.TargetPath}.");
89117
StorageManager.Restore(_parameter.BackupDirectory, _parameter.TargetPath);
118+
GeneralTracer.Info("WindowStrategy.Restore: restore completed successfully.");
119+
}
120+
else
121+
{
122+
GeneralTracer.Info("WindowStrategy.Restore: restore skipped, work model is not Upgrade.");
123+
}
90124
}
91125

92126
/// <summary>
@@ -95,13 +129,17 @@ private void Restore()
95129
private void SetEnvironment()
96130
{
97131
if (!string.Equals(_parameter.WorkModel, WorkModel))
132+
{
133+
GeneralTracer.Info("WindowStrategy.SetEnvironment: skipped, work model is not Upgrade.");
98134
return;
135+
}
99136

100137
/*
101138
* The `UpgradeFail` environment variable is used to mark an exception version number during updates.
102139
* If the latest version number obtained via an HTTP request is less than or equal to the exception version number, the update is skipped.
103140
* Once this version number is set, it will not be removed, and updates will not proceed until a version greater than the exception version number is obtained through the HTTP request.
104141
*/
105142
Environments.SetEnvironmentVariable("UpgradeFail", _parameter.ExtendedField);
143+
GeneralTracer.Warn($"WindowStrategy.SetEnvironment: UpgradeFail environment variable set to version={_parameter.ExtendedField}.");
106144
}
107145
}

0 commit comments

Comments
 (0)