Add Windows local node launch logs
This commit is contained in:
@@ -47,6 +47,14 @@ class AppPaths {
|
||||
return File(p.join((await appSupportDir()).path, 'peyad.pid'));
|
||||
}
|
||||
|
||||
static Future<File> localNodeLogFile() async {
|
||||
return File(p.join((await appSupportDir()).path, 'peyad.log'));
|
||||
}
|
||||
|
||||
static Future<File> localNodeLauncherLogFile() async {
|
||||
return File(p.join((await appSupportDir()).path, 'peyad-launcher.log'));
|
||||
}
|
||||
|
||||
static Future<List<File>> legacyConfigFiles() async {
|
||||
final targetRoot = Directory(_targetAppSupportPath());
|
||||
final legacyRoot = Directory(_legacyAppSupportPath());
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:logger/logger.dart';
|
||||
@@ -86,6 +87,10 @@ class WindowsLocalNodeService implements LocalNodeService {
|
||||
return false;
|
||||
}
|
||||
final pidFile = await _pidFilePath();
|
||||
final daemonLogFile = await AppPaths.localNodeLogFile();
|
||||
final launcherLogFile = await AppPaths.localNodeLauncherLogFile();
|
||||
await launcherLogFile.parent.create(recursive: true);
|
||||
final workingDirectory = p.dirname(binary);
|
||||
final args = <String>[
|
||||
'--non-interactive',
|
||||
'--rpc-bind-ip',
|
||||
@@ -94,15 +99,30 @@ class WindowsLocalNodeService implements LocalNodeService {
|
||||
config.rpcPort.toString(),
|
||||
'--pidfile',
|
||||
pidFile,
|
||||
'--log-file',
|
||||
daemonLogFile.path,
|
||||
...config.extraArgs,
|
||||
];
|
||||
try {
|
||||
await Process.start(
|
||||
final process = await Process.start(
|
||||
binary,
|
||||
args,
|
||||
workingDirectory: Directory.current.path,
|
||||
mode: ProcessStartMode.detached,
|
||||
workingDirectory: workingDirectory,
|
||||
mode: ProcessStartMode.detachedWithStdio,
|
||||
);
|
||||
_logger.i(
|
||||
'Starting local node: "$binary" ${args.join(' ')} '
|
||||
'(cwd=$workingDirectory, log=${daemonLogFile.path})',
|
||||
);
|
||||
unawaited(_pipeLauncherLogs(process, launcherLogFile));
|
||||
final earlyExitCode = await _waitForEarlyExit(process);
|
||||
if (earlyExitCode != null) {
|
||||
_logger.w(
|
||||
'Local node exited immediately with code $earlyExitCode. '
|
||||
'See ${launcherLogFile.path} and ${daemonLogFile.path}',
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
_logger.w('Failed to start local node: $error');
|
||||
return false;
|
||||
@@ -110,6 +130,39 @@ class WindowsLocalNodeService implements LocalNodeService {
|
||||
return _waitForRpc(config);
|
||||
}
|
||||
|
||||
Future<void> _pipeLauncherLogs(Process process, File logFile) async {
|
||||
final sink = logFile.openWrite(mode: FileMode.writeOnlyAppend);
|
||||
sink.writeln('=== ${DateTime.now().toIso8601String()} local node launch ===');
|
||||
unawaited(
|
||||
process.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.forEach((line) => sink.writeln('[stdout] $line')),
|
||||
);
|
||||
unawaited(
|
||||
process.stderr
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.forEach((line) => sink.writeln('[stderr] $line')),
|
||||
);
|
||||
unawaited(
|
||||
process.exitCode.then((code) async {
|
||||
sink.writeln('[exit] $code');
|
||||
await sink.flush();
|
||||
await sink.close();
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Future<int?> _waitForEarlyExit(Process process) async {
|
||||
const startupGrace = Duration(seconds: 2);
|
||||
final result = await Future.any<Object?>([
|
||||
process.exitCode,
|
||||
Future<Object?>.delayed(startupGrace, () => null),
|
||||
]);
|
||||
return result is int ? result : null;
|
||||
}
|
||||
|
||||
Future<bool> _waitForRpc(LocalNodeConfig config) async {
|
||||
const attempts = 20;
|
||||
for (var i = 0; i < attempts; i++) {
|
||||
|
||||
Reference in New Issue
Block a user