redact error too

create log file if it doesn't exist first
This commit is contained in:
austinried 2023-05-15 07:07:19 +09:00
parent c2733482e5
commit 53d284ace4
2 changed files with 56 additions and 32 deletions

View File

@ -15,33 +15,17 @@ class SubtracksHttpClient extends BaseClient {
@override @override
Future<StreamedResponse> send(BaseRequest request) { Future<StreamedResponse> send(BaseRequest request) {
request.headers.addAll(subtracksHeaders); request.headers.addAll(subtracksHeaders);
log.info('${request.method} ${_redactUri(request.url)}'); log.info('${request.method} ${request.url}');
try { try {
return request.send(); return request.send();
} catch (e, st) { } catch (e, st) {
log.severe( log.severe('HTTP client: ${request.method} ${request.url}', e, st);
'HTTP client: ${request.method} ${_redactUri(request.url)}', e, st);
rethrow; rethrow;
} }
} }
} }
String _redactUri(Uri uri) {
var redacted = uri.toString();
redacted = _redactParam(redacted, 'u');
redacted = _redactParam(redacted, 'p');
redacted = _redactParam(redacted, 's');
redacted = _redactParam(redacted, 't');
return redacted.toString();
}
RegExp _queryReplace(String key) => RegExp('$key=([^&|\\n|\\t\\s]+)');
String _redactParam(String url, String key) =>
url.replaceFirst(_queryReplace(key), '$key=REDACTED');
@Riverpod(keepAlive: true) @Riverpod(keepAlive: true)
BaseClient httpClient(HttpClientRef ref) { BaseClient httpClient(HttpClientRef ref) {
return SubtracksHttpClient(); return SubtracksHttpClient();

View File

@ -88,6 +88,7 @@ String _format(
bool color = false, bool color = false,
bool time = true, bool time = true,
bool level = true, bool level = true,
bool redact = true,
}) { }) {
var message = ''; var message = '';
if (time) message += '${event.time.toIso8601String()} '; if (time) message += '${event.time.toIso8601String()} ';
@ -107,6 +108,11 @@ String _format(
if (event.error != null) { if (event.error != null) {
message += '\n${event.error}'; message += '\n${event.error}';
} }
if (redact) {
message = _redactUrl(message);
}
if (event.stackTrace != null) { if (event.stackTrace != null) {
message += '\n${event.stackTrace}'; message += '\n${event.stackTrace}';
} }
@ -116,17 +122,24 @@ String _format(
: message; : message;
} }
Future<void> _printFile(String event, String dir) async { String _redactUrl(String message) {
final now = DateTime.now(); if (!_queryReplace('u').hasMatch(message)) {
final file = File(p.join(dir, '${now.year}-${now.month}-${now.day}.txt')); return message;
if (!event.endsWith('\n')) {
event += '\n';
} }
await file.writeAsString(event, mode: FileMode.writeOnlyAppend, flush: true); message = _redactParam(message, 'u');
message = _redactParam(message, 'p');
message = _redactParam(message, 's');
message = _redactParam(message, 't');
return message;
} }
RegExp _queryReplace(String key) => RegExp('$key=([^&|\\n|\\t\\s]+)');
String _redactParam(String url, String key) =>
url.replaceAll(_queryReplace(key), '$key=REDACTED');
Future<Directory> logDirectory() async { Future<Directory> logDirectory() async {
return Directory( return Directory(
p.join((await getApplicationDocumentsDirectory()).path, 'logs'), p.join((await getApplicationDocumentsDirectory()).path, 'logs'),
@ -141,11 +154,43 @@ Future<List<File>> logFiles() async {
); );
} }
File _currentLogFile(String logDir) {
final now = DateTime.now();
return File(p.join(logDir, '${now.year}-${now.month}-${now.day}.txt'));
}
Future<void> _printFile(String event, String logDir) async {
final file = _currentLogFile(logDir);
if (!event.endsWith('\n')) {
event += '\n';
}
await file.writeAsString(event, mode: FileMode.writeOnlyAppend, flush: true);
}
void _printDebug(LogRecord event) {
// ignore: avoid_print
print(_format(event, color: true, time: false, level: false, redact: false));
}
Future<void> _printRelease(LogRecord event, String logDir) async {
await _printFile(
_format(event, color: false, time: true, level: true, redact: true),
logDir,
);
}
final log = Logger('default'); final log = Logger('default');
Future<void> initLogging() async { Future<void> initLogging() async {
final dir = (await logDirectory())..create(); final dir = (await logDirectory())..create();
final file = _currentLogFile(dir.path);
if (!(await file.exists())) {
await file.create();
}
final files = await logFiles(); final files = await logFiles();
if (files.length > 7) { if (files.length > 7) {
for (var file in files.slice(7)) { for (var file in files.slice(7)) {
@ -156,14 +201,9 @@ Future<void> initLogging() async {
Logger.root.level = kDebugMode ? Level.ALL : Level.INFO; Logger.root.level = kDebugMode ? Level.ALL : Level.INFO;
Logger.root.onRecord.asyncMap((event) async { Logger.root.onRecord.asyncMap((event) async {
if (kDebugMode) { if (kDebugMode) {
print(_format(event, color: true, time: false, level: false)); _printDebug(event);
} else { } else {
await _printFile( await _printRelease(event, dir.path);
_format(event, color: false, time: true, level: true),
dir.path,
);
} }
}).listen((_) {}, cancelOnError: false); }).listen((_) {}, cancelOnError: false);
log.info('start');
} }