feat: add OpenTelemetry settings UI and sidecar environment wiring

Add a global Telemetry section in the settings panel with:
- Toggle to enable/disable OTLP export
- Text input for the OTLP endpoint URL (default: http://localhost:4317)
- Guidance note about using \un run aspire\ for local testing

Wire the setting through the full stack:
- OpenTelemetrySettings type in shared domain with normalization
- IPC channel, preload binding, and handler for persistence
- SidecarClient forwards settings to createSidecarEnvironment
- Sidecar environment injects OTEL_EXPORTER_OTLP_ENDPOINT when enabled
- Settings loaded from workspace.json on startup and on change

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-04-16 11:10:23 +02:00
co-authored by Copilot
parent f7d376fc41
commit 67fb950e61
12 changed files with 210 additions and 6 deletions
+36
View File
@@ -6,12 +6,14 @@ import {
groupApprovalToolsByProvider,
listApprovalToolDefinitions,
listApprovalToolNames,
normalizeOpenTelemetrySettings,
normalizeWorkspaceSettings,
resolveProjectToolingSettings,
resolveToolLabel,
resolveWorkspaceToolingSettings,
validateLspProfileDefinition,
validateMcpServerDefinition,
DEFAULT_OTEL_ENDPOINT,
type LspProfileDefinition,
type McpServerDefinition,
type WorkspaceToolingSettings,
@@ -118,6 +120,40 @@ describe('tooling settings helpers', () => {
expect(normalizeWorkspaceSettings({ terminalHeight: Number.NaN }).terminalHeight).toBeUndefined();
});
test('normalizes OpenTelemetry settings with defaults', () => {
const otel = normalizeOpenTelemetrySettings();
expect(otel.enabled).toBe(false);
expect(otel.endpoint).toBe(DEFAULT_OTEL_ENDPOINT);
});
test('preserves valid OpenTelemetry settings', () => {
const otel = normalizeOpenTelemetrySettings({ enabled: true, endpoint: 'http://custom:4317' });
expect(otel.enabled).toBe(true);
expect(otel.endpoint).toBe('http://custom:4317');
});
test('trims whitespace from OpenTelemetry endpoint', () => {
const otel = normalizeOpenTelemetrySettings({ enabled: true, endpoint: ' http://localhost:4317 ' });
expect(otel.endpoint).toBe('http://localhost:4317');
});
test('falls back to default endpoint when blank', () => {
const otel = normalizeOpenTelemetrySettings({ enabled: true, endpoint: ' ' });
expect(otel.endpoint).toBe(DEFAULT_OTEL_ENDPOINT);
});
test('normalizeWorkspaceSettings preserves OpenTelemetry when present', () => {
const settings = normalizeWorkspaceSettings({
openTelemetry: { enabled: true, endpoint: 'http://jaeger:4317' },
});
expect(settings.openTelemetry).toEqual({ enabled: true, endpoint: 'http://jaeger:4317' });
});
test('normalizeWorkspaceSettings omits OpenTelemetry when absent', () => {
const settings = normalizeWorkspaceSettings({});
expect(settings.openTelemetry).toBeUndefined();
});
test('validates required MCP transport settings', () => {
const localServer: McpServerDefinition = {
id: 'mcp-local',