mirror of
https://github.com/gnh1201/welsonjs.git
synced 2025-12-06 06:14:22 +00:00
Add a telemetry to WelsonJS Launcher
Add a telemetry to WelsonJS Launcher, To improve debugging experience.
This commit is contained in:
parent
bf4b2214bc
commit
c4e6acc8cd
|
|
@ -11,6 +11,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using WelsonJS.Launcher.Telemetry;
|
||||
|
||||
namespace WelsonJS.Launcher
|
||||
{
|
||||
|
|
@ -21,6 +22,7 @@ namespace WelsonJS.Launcher
|
|||
public static Mutex _mutex;
|
||||
public static ResourceServer _resourceServer;
|
||||
public static string _dateTimeFormat;
|
||||
public static TelemetryClient _telemetryClient;
|
||||
|
||||
static Program()
|
||||
{
|
||||
|
|
@ -32,10 +34,10 @@ namespace WelsonJS.Launcher
|
|||
|
||||
// load native libraries
|
||||
string appDataSubDirectory = "WelsonJS";
|
||||
bool requireSigned = string.Equals(
|
||||
GetAppConfig("NativeRequireSigned"),
|
||||
"true",
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
bool requireSigned = string.Equals(
|
||||
GetAppConfig("NativeRequireSigned"),
|
||||
"true",
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
NativeBootstrap.Init(
|
||||
dllNames: new[] { "ChakraCore.dll" },
|
||||
|
|
@ -43,6 +45,17 @@ namespace WelsonJS.Launcher
|
|||
logger: _logger,
|
||||
requireSigned: requireSigned
|
||||
);
|
||||
|
||||
// telemetry
|
||||
var telemetryProvider = GetAppConfig("TelemetryProvider");
|
||||
var telemetryOptions = new TelemetryOptions
|
||||
{
|
||||
ApiKey = GetAppConfig("TelemetryApiKey"),
|
||||
BaseUrl = GetAppConfig("TelemetryBaseUrl"),
|
||||
DistinctId = Environment.MachineName,
|
||||
Disabled = string.Equals(GetAppConfig("TelemetryDisabled"), "true", StringComparison.OrdinalIgnoreCase)
|
||||
};
|
||||
_telemetryClient = new TelemetryClient(telemetryProvider, telemetryOptions, _logger);
|
||||
}
|
||||
|
||||
[STAThread]
|
||||
|
|
@ -70,6 +83,9 @@ namespace WelsonJS.Launcher
|
|||
return;
|
||||
}
|
||||
|
||||
// send event to the telemetry server
|
||||
_telemetryClient.TrackAppStartedAsync("WelsonJS.Launcher", "0.2.7.57");
|
||||
|
||||
// draw the main form
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
|
|
|||
|
|
@ -378,6 +378,42 @@ namespace WelsonJS.Launcher.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// phc_pmRHJ0aVEhtULRT4ilexwCjYpGtE9VYRhlA05fwiYt8과(와) 유사한 지역화된 문자열을 찾습니다.
|
||||
/// </summary>
|
||||
internal static string TelemetryApiKey {
|
||||
get {
|
||||
return ResourceManager.GetString("TelemetryApiKey", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://us.i.posthog.com과(와) 유사한 지역화된 문자열을 찾습니다.
|
||||
/// </summary>
|
||||
internal static string TelemetryBaseUrl {
|
||||
get {
|
||||
return ResourceManager.GetString("TelemetryBaseUrl", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// false과(와) 유사한 지역화된 문자열을 찾습니다.
|
||||
/// </summary>
|
||||
internal static string TelemetryDisabled {
|
||||
get {
|
||||
return ResourceManager.GetString("TelemetryDisabled", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// posthog과(와) 유사한 지역화된 문자열을 찾습니다.
|
||||
/// </summary>
|
||||
internal static string TelemetryProvider {
|
||||
get {
|
||||
return ResourceManager.GetString("TelemetryProvider", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 141.101.82.1과(와) 유사한 지역화된 문자열을 찾습니다.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -229,4 +229,16 @@
|
|||
<data name="icon_editor_32" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\icon_editor_32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="TelemetryApiKey" xml:space="preserve">
|
||||
<value>phc_pmRHJ0aVEhtULRT4ilexwCjYpGtE9VYRhlA05fwiYt8</value>
|
||||
</data>
|
||||
<data name="TelemetryBaseUrl" xml:space="preserve">
|
||||
<value>https://us.i.posthog.com</value>
|
||||
</data>
|
||||
<data name="TelemetryProvider" xml:space="preserve">
|
||||
<value>posthog</value>
|
||||
</data>
|
||||
<data name="TelemetryDisabled" xml:space="preserve">
|
||||
<value>false</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// ITelemetryProvider.cs
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2025 Catswords OSS and WelsonJS Contributors
|
||||
// https://github.com/gnh1201/welsonjs
|
||||
//
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WelsonJS.Launcher.Telemetry
|
||||
{
|
||||
public interface ITelemetryProvider
|
||||
{
|
||||
Task TrackEventAsync(
|
||||
string eventName,
|
||||
IDictionary<string, object> properties = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// PosthogTelemetryProvider.cs
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2025 Catswords OSS and WelsonJS Contributors
|
||||
// https://github.com/gnh1201/welsonjs
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WelsonJS.Launcher.Telemetry
|
||||
{
|
||||
public sealed class PosthogTelemetryProvider : ITelemetryProvider, IDisposable
|
||||
{
|
||||
private readonly TelemetryOptions _options;
|
||||
private readonly HttpClient _httpClient;
|
||||
private bool _disposed;
|
||||
|
||||
public PosthogTelemetryProvider(TelemetryOptions options)
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_options.ApiKey))
|
||||
throw new ArgumentException("PostHog API key is missing.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_options.BaseUrl))
|
||||
throw new ArgumentException("PostHog BaseUrl is missing.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_options.DistinctId))
|
||||
_options.DistinctId = $"anon-{Guid.NewGuid():N}";
|
||||
|
||||
_httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(5) };
|
||||
}
|
||||
|
||||
public async Task TrackEventAsync(
|
||||
string eventName,
|
||||
IDictionary<string, object> properties = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_disposed) throw new ObjectDisposedException(nameof(PosthogTelemetryProvider));
|
||||
if (_options.Disabled) return;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(eventName))
|
||||
return;
|
||||
|
||||
string json;
|
||||
using (var ser = new JsSerializer())
|
||||
{
|
||||
var payload = new Dictionary<string, object>
|
||||
{
|
||||
["api_key"] = _options.ApiKey,
|
||||
["distinct_id"] = _options.DistinctId,
|
||||
["event"] = eventName,
|
||||
["properties"] = properties ?? new Dictionary<string, object>()
|
||||
};
|
||||
|
||||
json = ser.Serialize(payload, 0);
|
||||
}
|
||||
|
||||
var url = $"{_options.BaseUrl.TrimEnd('/')}/i/v0/e";
|
||||
|
||||
try
|
||||
{
|
||||
await _httpClient.PostAsync(
|
||||
url,
|
||||
new StringContent(json, Encoding.UTF8, "application/json"),
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// swallow for fire-and-forget telemetry
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_disposed = true;
|
||||
_httpClient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// TelemetryClient.cs
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2025 Catswords OSS and WelsonJS Contributors
|
||||
// https://github.com/gnh1201/welsonjs
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WelsonJS.Launcher.Telemetry
|
||||
{
|
||||
public sealed class TelemetryClient : IDisposable
|
||||
{
|
||||
private readonly ITelemetryProvider _provider;
|
||||
private readonly ICompatibleLogger _logger;
|
||||
|
||||
public TelemetryClient(string providerName, TelemetryOptions options, ICompatibleLogger logger = null)
|
||||
{
|
||||
_provider = TelemetryProviderFactory.Create(providerName, options);
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task TrackEventAsync(
|
||||
string eventName,
|
||||
IDictionary<string, object> properties = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _provider.TrackEventAsync(eventName, properties, cancellationToken);
|
||||
}
|
||||
|
||||
public Task TrackAppStartedAsync(string appName, string appVersion)
|
||||
{
|
||||
var props = new Dictionary<string, object>
|
||||
{
|
||||
{ "app_name", appName },
|
||||
{ "app_version", appVersion },
|
||||
{ "os_platform", Environment.OSVersion.Platform.ToString() },
|
||||
{ "os_version", Environment.OSVersion.Version.ToString() },
|
||||
{ "timestamp_utc", DateTime.UtcNow.ToString("o") }
|
||||
};
|
||||
|
||||
return TrackEventAsync("app_started", props);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
(_provider as IDisposable)?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// TelemetryOptions.cs
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2025 Catswords OSS and WelsonJS Contributors
|
||||
// https://github.com/gnh1201/welsonjs
|
||||
//
|
||||
namespace WelsonJS.Launcher.Telemetry
|
||||
{
|
||||
public class TelemetryOptions
|
||||
{
|
||||
public string ApiKey { get; set; }
|
||||
public string BaseUrl { get; set; }
|
||||
public string DistinctId { get; set; }
|
||||
public bool Disabled { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// TelemetryProviderFactory.cs
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2025 Catswords OSS and WelsonJS Contributors
|
||||
// https://github.com/gnh1201/welsonjs
|
||||
//
|
||||
using System;
|
||||
|
||||
namespace WelsonJS.Launcher.Telemetry
|
||||
{
|
||||
public static class TelemetryProviderFactory
|
||||
{
|
||||
public static ITelemetryProvider Create(string provider, TelemetryOptions options)
|
||||
{
|
||||
if (options == null)
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
|
||||
if (provider == null)
|
||||
throw new ArgumentNullException(nameof(provider));
|
||||
|
||||
provider = provider.ToLowerInvariant();
|
||||
|
||||
switch (provider)
|
||||
{
|
||||
case "posthog":
|
||||
return new PosthogTelemetryProvider(options);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(
|
||||
"Unknown telemetry provider: " + provider
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -128,6 +128,11 @@
|
|||
<DependentUpon>GlobalSettingsForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ResourceServer.cs" />
|
||||
<Compile Include="Telemetry\ITelemetryProvider.cs" />
|
||||
<Compile Include="Telemetry\PosthogTelemetryProvider.cs" />
|
||||
<Compile Include="Telemetry\TelemetryClient.cs" />
|
||||
<Compile Include="Telemetry\TelemetryOptions.cs" />
|
||||
<Compile Include="Telemetry\TelemetryProviderFactory.cs" />
|
||||
<Compile Include="TraceLogger.cs" />
|
||||
<Compile Include="WebSocketManager.cs" />
|
||||
<EmbeddedResource Include="EnvForm.resx">
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
<add key="IpQueryApiPrefix2" value="https://api.abuseipdb.com/api/v2/"/>
|
||||
<add key="DateTimeFormat" value="yyyy-MM-dd HH:mm:ss"/>
|
||||
<add key="NativeRequireSigned" value="false"/>
|
||||
<add key="TelemetryProvider" value="posthog"/>
|
||||
<add key="TelemetryApiKey" value="phc_pmRHJ0aVEhtULRT4ilexwCjYpGtE9VYRhlA05fwiYt8"/>
|
||||
<add key="TelemetryBaseUrl" value="https://us.i.posthog.com"/>
|
||||
<add key="TelemetryDisabled" value="false"/>
|
||||
</appSettings>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user