feat(app): Debug-Logs-an-Bridge Toggle (Settings → Protokoll, default aus)
Stefan: "haben wir einen Menupunkt logging? sonst muellen wir uns dicht wenns funktioniert und wir das logging im moment nicht brauchen" Stimmt. reportAppDebug() schickt aktuell IMMER an Bridge, auch wenn gar nicht debuggt wird. Bei armed Wake-Word + Pipeline-Logs sind das schnell ein Dutzend Eintraege pro Wake-Trigger. Loesung: separater Settings-Toggle "Debug-Logs an Bridge" mit eigenem AsyncStorage-Key (aria_debug_logs_to_bridge), Default AUS. - logger.ts: _debugLogsToBridge flag + isDebugLogsToBridge() / setDebugLogsToBridge(). initLogger() laedt den Wert. reportAppDebug() prueft das Flag und schickt nur wenn AN. - SettingsScreen: neuer Toggle direkt unter Verbose-Logging, orange (#FF9500) damit er als "Power-User-Option" erkennbar ist, mit Erklaerungs-Hinweis dass nur Info-Logs gefiltert werden, Crash-Reports (Errors via reportAppError) gehen weiterhin IMMER. Workflow: - Default-User: Toggle aus, kein Traffic, kein Disk-Schreiben - Stefan beim Debuggen: Toggle an, testet die App, schaut Logs via curl /api/app-log?lines=N, schaltet wieder aus APK neu bauen erforderlich. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,7 +62,7 @@ import MemoryBrowser from '../components/MemoryBrowser';
|
|||||||
import TriggerBrowser from '../components/TriggerBrowser';
|
import TriggerBrowser from '../components/TriggerBrowser';
|
||||||
import SkillBrowser from '../components/SkillBrowser';
|
import SkillBrowser from '../components/SkillBrowser';
|
||||||
import OAuthBrowser from '../components/OAuthBrowser';
|
import OAuthBrowser from '../components/OAuthBrowser';
|
||||||
import { isVerboseLogging, setVerboseLogging } from '../services/logger';
|
import { isVerboseLogging, setVerboseLogging, isDebugLogsToBridge, setDebugLogsToBridge } from '../services/logger';
|
||||||
import {
|
import {
|
||||||
isWakeReadySoundEnabled,
|
isWakeReadySoundEnabled,
|
||||||
setWakeReadySoundEnabled,
|
setWakeReadySoundEnabled,
|
||||||
@@ -160,6 +160,7 @@ const SettingsScreen: React.FC = () => {
|
|||||||
const [apkCacheInfo, setApkCacheInfo] = useState<{count: number, totalMB: number} | null>(null);
|
const [apkCacheInfo, setApkCacheInfo] = useState<{count: number, totalMB: number} | null>(null);
|
||||||
const [ttsCacheInfo, setTtsCacheInfo] = useState<{count: number, totalMB: number} | null>(null);
|
const [ttsCacheInfo, setTtsCacheInfo] = useState<{count: number, totalMB: number} | null>(null);
|
||||||
const [verboseLogging, setVerboseLoggingState] = useState<boolean>(isVerboseLogging());
|
const [verboseLogging, setVerboseLoggingState] = useState<boolean>(isVerboseLogging());
|
||||||
|
const [debugLogsToBridge, setDebugLogsToBridgeState] = useState<boolean>(isDebugLogsToBridge());
|
||||||
const [ttsSpeed, setTtsSpeed] = useState<number>(TTS_SPEED_DEFAULT);
|
const [ttsSpeed, setTtsSpeed] = useState<number>(TTS_SPEED_DEFAULT);
|
||||||
const [wakeKeyword, setWakeKeyword] = useState<string>(DEFAULT_KEYWORD);
|
const [wakeKeyword, setWakeKeyword] = useState<string>(DEFAULT_KEYWORD);
|
||||||
const [wakeStatus, setWakeStatus] = useState<string>('');
|
const [wakeStatus, setWakeStatus] = useState<string>('');
|
||||||
@@ -1916,6 +1917,27 @@ const SettingsScreen: React.FC = () => {
|
|||||||
Warnungen und Fehler bleiben immer aktiv. Bei Bedarf einschalten zum
|
Warnungen und Fehler bleiben immer aktiv. Bei Bedarf einschalten zum
|
||||||
Debuggen via adb logcat.
|
Debuggen via adb logcat.
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
{/* Debug-Logs an Bridge: scharf nur wenn aktiv gebraucht */}
|
||||||
|
<View style={[styles.toggleRow, {marginTop: 12, borderTopWidth: 1, borderTopColor: '#1E1E2E', paddingTop: 12}]}>
|
||||||
|
<Text style={styles.toggleLabel}>Debug-Logs an Bridge</Text>
|
||||||
|
<Switch
|
||||||
|
value={debugLogsToBridge}
|
||||||
|
onValueChange={(v) => {
|
||||||
|
setDebugLogsToBridge(v);
|
||||||
|
setDebugLogsToBridgeState(v);
|
||||||
|
}}
|
||||||
|
trackColor={{ false: '#3A3A52', true: '#FF9500' }}
|
||||||
|
thumbColor={debugLogsToBridge ? '#FFFFFF' : '#666680'}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.toggleHint}>
|
||||||
|
Schickt detaillierte Diagnose-Logs (Wake-Word-Pipeline, Audio-Focus,
|
||||||
|
Background-Service) per RVS an die Bridge — abrufbar via
|
||||||
|
`curl /api/app-log?lines=N` ohne ADB. Default AUS damit kein
|
||||||
|
unnoetiger Traffic + Disk-Schreiben. Crash-Reports (Errors) gehen
|
||||||
|
IMMER, dieser Toggle betrifft nur Info-Logs.
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.card}>
|
<View style={styles.card}>
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import { Platform } from 'react-native';
|
|||||||
import rvs from './rvs';
|
import rvs from './rvs';
|
||||||
|
|
||||||
export const VERBOSE_LOGGING_KEY = 'aria_verbose_logging';
|
export const VERBOSE_LOGGING_KEY = 'aria_verbose_logging';
|
||||||
|
// Eigener Toggle fuer Debug-Logs die ueber RVS an die Bridge gehen
|
||||||
|
// (/shared/logs/app.log → Diagnostic /api/app-log). Damit der Default-User
|
||||||
|
// nicht stuendlich Traffic + Disk-Schreiben hat, dieser ist DEFAULT AUS.
|
||||||
|
// Stefan schaltet's nur ein wenn er ein konkretes Problem debuggen muss.
|
||||||
|
export const DEBUG_LOGS_TO_BRIDGE_KEY = 'aria_debug_logs_to_bridge';
|
||||||
|
|
||||||
// Original-console.log retten, damit wir die Wrapper jederzeit wieder
|
// Original-console.log retten, damit wir die Wrapper jederzeit wieder
|
||||||
// "scharf" stellen koennen (sonst waere ein Toggle-an nach -aus tot).
|
// "scharf" stellen koennen (sonst waere ein Toggle-an nach -aus tot).
|
||||||
@@ -18,6 +23,7 @@ const originalLog = console.log.bind(console);
|
|||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
|
|
||||||
let _verbose = true;
|
let _verbose = true;
|
||||||
|
let _debugLogsToBridge = false;
|
||||||
|
|
||||||
function applyState(): void {
|
function applyState(): void {
|
||||||
console.log = _verbose ? originalLog : noop;
|
console.log = _verbose ? originalLog : noop;
|
||||||
@@ -29,6 +35,10 @@ export async function initLogger(): Promise<void> {
|
|||||||
const v = await AsyncStorage.getItem(VERBOSE_LOGGING_KEY);
|
const v = await AsyncStorage.getItem(VERBOSE_LOGGING_KEY);
|
||||||
_verbose = v !== 'false'; // default: true
|
_verbose = v !== 'false'; // default: true
|
||||||
} catch {}
|
} catch {}
|
||||||
|
try {
|
||||||
|
const d = await AsyncStorage.getItem(DEBUG_LOGS_TO_BRIDGE_KEY);
|
||||||
|
_debugLogsToBridge = d === 'true'; // default: false
|
||||||
|
} catch {}
|
||||||
applyState();
|
applyState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +52,15 @@ export function setVerboseLogging(verbose: boolean): void {
|
|||||||
AsyncStorage.setItem(VERBOSE_LOGGING_KEY, String(verbose)).catch(() => {});
|
AsyncStorage.setItem(VERBOSE_LOGGING_KEY, String(verbose)).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isDebugLogsToBridge(): boolean {
|
||||||
|
return _debugLogsToBridge;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setDebugLogsToBridge(enabled: boolean): void {
|
||||||
|
_debugLogsToBridge = enabled;
|
||||||
|
AsyncStorage.setItem(DEBUG_LOGS_TO_BRIDGE_KEY, String(enabled)).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
// ─── App-Crash-Reporting via RVS ────────────────────────────────────
|
// ─── App-Crash-Reporting via RVS ────────────────────────────────────
|
||||||
//
|
//
|
||||||
// Wenn die App crasht — egal ob React-Render-Fehler (ErrorBoundary) oder
|
// Wenn die App crasht — egal ob React-Render-Fehler (ErrorBoundary) oder
|
||||||
@@ -81,8 +100,13 @@ export function reportAppError(ev: AppErrorEvent): void {
|
|||||||
/** Schickt eine Debug-/Info-Message via RVS an die Bridge. Landet ebenfalls
|
/** Schickt eine Debug-/Info-Message via RVS an die Bridge. Landet ebenfalls
|
||||||
* in /shared/logs/app.log — abrufbar via `curl /api/app-log?lines=N`.
|
* in /shared/logs/app.log — abrufbar via `curl /api/app-log?lines=N`.
|
||||||
* Im Gegensatz zu reportAppError: keine Stacktrace, level=info, kein
|
* Im Gegensatz zu reportAppError: keine Stacktrace, level=info, kein
|
||||||
* console.error. Fuer Live-Diagnose im Hintergrund wenn ADB nicht da ist. */
|
* console.error. Fuer Live-Diagnose im Hintergrund wenn ADB nicht da ist.
|
||||||
|
*
|
||||||
|
* Nur aktiv wenn Settings → Protokoll → Debug-Logs an Bridge AN ist.
|
||||||
|
* Default aus damit Mama-Modus keine Disk-Schreiblast hat. Error-Reports
|
||||||
|
* (reportAppError) gehen weiterhin IMMER durch. */
|
||||||
export function reportAppDebug(scope: string, message: string): void {
|
export function reportAppDebug(scope: string, message: string): void {
|
||||||
|
if (!_debugLogsToBridge) return;
|
||||||
try {
|
try {
|
||||||
rvs.send('app_log' as any, {
|
rvs.send('app_log' as any, {
|
||||||
ts: Date.now(),
|
ts: Date.now(),
|
||||||
|
|||||||
Reference in New Issue
Block a user