mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 08:22:16 +03:00
Use the logging package, and log from RPC.
This commit is contained in:
parent
d9b5cdc951
commit
064fb038e6
@ -1,14 +1,16 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer' as developer;
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
import '../../core/rpc.dart';
|
||||
import '../../core/state.dart';
|
||||
|
||||
import 'models.dart';
|
||||
|
||||
final log = Logger('app.state');
|
||||
|
||||
final attachedDevicesProvider =
|
||||
StateNotifierProvider<AttachedDeviceNotifier, List<DeviceNode>>(
|
||||
(ref) => AttachedDeviceNotifier(ref.watch(rpcProvider)));
|
||||
@ -32,8 +34,7 @@ class AttachedDeviceNotifier extends StateNotifier<List<DeviceNode>> {
|
||||
|
||||
if (_usbState != scan['state']) {
|
||||
var usbResult = await _rpc.command('get', ['usb']);
|
||||
developer.log('USB state change',
|
||||
name: 'controller', error: jsonEncode(usbResult));
|
||||
log.info('USB state change', jsonEncode(usbResult));
|
||||
|
||||
_usbState = usbResult['data']['state'];
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:developer' as developer;
|
||||
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:async/async.dart';
|
||||
|
||||
import 'models.dart';
|
||||
|
||||
final log = Logger('rpc');
|
||||
|
||||
class Signaler {
|
||||
final _send = StreamController<String>();
|
||||
final _recv = StreamController<Signal>();
|
||||
@ -40,6 +42,21 @@ class _Request {
|
||||
};
|
||||
}
|
||||
|
||||
Level _forPythonName(String name) {
|
||||
switch (name) {
|
||||
case 'DEBUG':
|
||||
return Level.CONFIG;
|
||||
case 'INFO':
|
||||
return Level.INFO;
|
||||
case 'WARNING':
|
||||
return Level.WARNING;
|
||||
case 'ERROR':
|
||||
return Level.SEVERE;
|
||||
default:
|
||||
return Level.INFO;
|
||||
}
|
||||
}
|
||||
|
||||
class RpcSession {
|
||||
final Process _process;
|
||||
final StreamController<_Request> _requests = StreamController();
|
||||
@ -50,8 +67,18 @@ class RpcSession {
|
||||
.transform(const Utf8Decoder())
|
||||
.transform(const LineSplitter())
|
||||
.map((event) => RpcResponse.fromJson(jsonDecode(event)))) {
|
||||
stderr.addStream(_process.stderr);
|
||||
developer.log('Launched ykman subprocess...', name: 'rpc');
|
||||
_process.stderr
|
||||
.transform(const Utf8Decoder())
|
||||
.transform(const LineSplitter())
|
||||
.map((event) => jsonDecode(event))
|
||||
.listen((event) {
|
||||
Logger('rpc.${event['name']}').log(
|
||||
_forPythonName(event['level']),
|
||||
event['message'],
|
||||
//time: DateTime.fromMillisecondsSinceEpoch(event['time'] * 1000),
|
||||
);
|
||||
});
|
||||
log.info('Launched ykman subprocess...');
|
||||
_pump();
|
||||
}
|
||||
|
||||
@ -68,8 +95,24 @@ class RpcSession {
|
||||
return request.completer.future;
|
||||
}
|
||||
|
||||
setLogLevel(Level level) {
|
||||
String pyLevel;
|
||||
if (level.value <= Level.CONFIG.value) {
|
||||
pyLevel = 'debug';
|
||||
} else if (level.value <= Level.INFO.value) {
|
||||
pyLevel = 'info';
|
||||
} else if (level.value <= Level.WARNING.value) {
|
||||
pyLevel = 'warning';
|
||||
} else if (level.value <= Level.SEVERE.value) {
|
||||
pyLevel = 'error';
|
||||
} else {
|
||||
pyLevel = 'critical';
|
||||
}
|
||||
command('logging', [], params: {'level': pyLevel});
|
||||
}
|
||||
|
||||
void _send(Map data) {
|
||||
developer.log('SEND', name: 'rpc', error: jsonEncode(data));
|
||||
log.fine('SEND', jsonEncode(data));
|
||||
_process.stdin.writeln(jsonEncode(data));
|
||||
_process.stdin.flush();
|
||||
}
|
||||
@ -85,7 +128,7 @@ class RpcSession {
|
||||
bool completed = false;
|
||||
while (!completed) {
|
||||
final response = await _responses.next;
|
||||
developer.log('RECV', name: 'rpc', error: jsonEncode(response));
|
||||
log.fine('RECV', jsonEncode(response));
|
||||
response.map(
|
||||
signal: (signal) {
|
||||
request.signal?._recv.sink.add(signal);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:developer' as developer;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
import 'app.dart';
|
||||
import 'core/rpc.dart';
|
||||
@ -13,6 +13,8 @@ import 'core/state.dart';
|
||||
import 'app/main_page.dart';
|
||||
import 'error_page.dart';
|
||||
|
||||
final log = Logger('main');
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
@ -35,14 +37,16 @@ void main() async {
|
||||
prefProvider.overrideWithValue(await SharedPreferences.getInstance())
|
||||
];
|
||||
|
||||
developer.log('Starting subprocess: $exe', name: 'main');
|
||||
log.info('Starting subprocess: $exe');
|
||||
try {
|
||||
var rpc = await RpcSession.launch(exe!);
|
||||
developer.log('ykman process started', name: 'main');
|
||||
// Enable logging TODO: Make this configurable
|
||||
_initLogging(Level.INFO, rpc);
|
||||
log.info('ykman process started', exe);
|
||||
overrides.add(rpcProvider.overrideWithValue(rpc));
|
||||
page = const MainPage();
|
||||
} catch (e) {
|
||||
developer.log('ykman process failed: $e', name: 'main');
|
||||
log.warning('ykman process failed: $e');
|
||||
page = ErrorPage(error: e.toString());
|
||||
}
|
||||
|
||||
@ -52,6 +56,22 @@ void main() async {
|
||||
));
|
||||
}
|
||||
|
||||
void _initLogging(Level level, RpcSession rpc) {
|
||||
//TODO: Add support for logging to stderr and file
|
||||
Logger.root.onRecord.listen((record) {
|
||||
developer.log(
|
||||
'${record.level} ${record.message}',
|
||||
error: record.error,
|
||||
name: record.loggerName,
|
||||
time: record.time,
|
||||
level: record.level.value,
|
||||
);
|
||||
});
|
||||
|
||||
Logger.root.level = level;
|
||||
rpc.setLogLevel(level);
|
||||
}
|
||||
|
||||
//TODO: Remove below this
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
|
@ -1,15 +1,17 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer' as developer;
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
import '../core/state.dart';
|
||||
import 'models.dart';
|
||||
|
||||
final log = Logger('oath.state');
|
||||
|
||||
final _sessionProvider =
|
||||
Provider.autoDispose.family<RpcNodeSession, List<String>>(
|
||||
(ref, devicePath) => RpcNodeSession(
|
||||
@ -34,8 +36,7 @@ class OathStateNotifier extends StateNotifier<OathState?> {
|
||||
|
||||
refresh() async {
|
||||
var result = await _session.command('get');
|
||||
developer.log('application status',
|
||||
name: 'oath', error: jsonEncode(result));
|
||||
log.config('application status', jsonEncode(result));
|
||||
if (mounted) {
|
||||
state = OathState.fromJson(result['data']);
|
||||
}
|
||||
@ -47,7 +48,7 @@ class OathStateNotifier extends StateNotifier<OathState?> {
|
||||
var key = result['key'];
|
||||
await _session.command('validate', params: {'key': key});
|
||||
if (mounted) {
|
||||
developer.log('UNLOCKED');
|
||||
log.config('applet unlocked');
|
||||
state = state?.copyWith(locked: false);
|
||||
}
|
||||
return true;
|
||||
@ -117,7 +118,7 @@ class CredentialListNotifier extends StateNotifier<List<OathPair>?> {
|
||||
await _session.command('code', target: ['accounts', credential.id]);
|
||||
code = OathCode.fromJson(result);
|
||||
}
|
||||
developer.log('Calculate', name: 'oath', error: jsonEncode(code));
|
||||
log.config('Calculate', jsonEncode(code));
|
||||
if (mounted) {
|
||||
final creds = state!.toList();
|
||||
final i = creds.indexWhere((e) => e.credential.id == credential.id);
|
||||
@ -143,9 +144,9 @@ class CredentialListNotifier extends StateNotifier<List<OathPair>?> {
|
||||
|
||||
refresh() async {
|
||||
if (_locked) return;
|
||||
developer.log('refreshing credentials...', name: 'oath');
|
||||
log.config('refreshing credentials...');
|
||||
var result = await _session.command('calculate_all', target: ['accounts']);
|
||||
developer.log('Entries', name: 'oath', error: jsonEncode(result));
|
||||
log.config('Entries', jsonEncode(result));
|
||||
|
||||
if (mounted) {
|
||||
var current = state?.toList() ?? [];
|
||||
|
@ -304,7 +304,7 @@ packages:
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -36,6 +36,7 @@ dependencies:
|
||||
# cupertino_icons: ^1.0.2
|
||||
|
||||
async: ^2.8.2
|
||||
logging: ^1.0.2
|
||||
shared_preferences: ^2.0.8
|
||||
flutter_riverpod: ^1.0.0
|
||||
json_annotation: ^4.3.0
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 739f3122a43adfcd2549374bc4cd11e88a483a8d
|
||||
Subproject commit 318b0981d545950a45a8c9b9e17de9332e1f64b5
|
Loading…
Reference in New Issue
Block a user