Closed martinsellergren closed 1 month ago
Hi, as you haven't specified a specific printer, I am assuming you are using the default PrettyPrinter
.
Have you tried the methodCount
(or the errorMethodCount
) parameter?
Yes, PrettyPrinter
is my preferred printer.
Yep, I've tried methodCount and errorMethodCount but it's not precisely what I want.
I think the problem is when you log with a stack trace provided. Then you don't get the path of the log statement, since the stack trace describes something else. But if you don't provide a stack trace the PrettyPrinter uses StackTrace.current
, and log path is shown, it seems, at least if you increase methodCount
, errorMethodCount
. But, what I'd like is for the path of log statement to always show.
Suppose you could manipulate a stack trace yourself, e.g using stack_trace package, and take the last trace from Trace.current
and put it somewhere in the log output.
I feel like that's a very specific requirement, and I am having trouble imagining it as a useful general addition to the PrettyPrinter as the format of the output is often very opinionated.
I would recommend that you add it for yourself and if you feel like it would be a good addition you can open a PR with it.
Sounds good. I'll experiment with it then get back with any findings or pr.
I wanted the file name and line number in all logs except exceptions due to it being in the stack trace. I didn't have time to look into adding this feature to the package, so I've just configured it for my app. It's hacky, but works in a pinch (I am new to this package). You'll need to add the stack_trace
dependency and import it:
class CustomPrinter extends LogPrinter {
final PrettyPrinter _prettyPrinter;
CustomPrinter({
int methodCount = 0,
int errorMethodCount = 8,
int lineLength = 120,
bool colors = true,
bool printEmojis = true,
bool printTime = false,
}) : _prettyPrinter = PrettyPrinter(
methodCount: methodCount,
errorMethodCount: errorMethodCount,
lineLength: lineLength,
colors: colors,
printEmojis: printEmojis,
printTime: printTime,
);
@override
List<String> log(LogEvent event) {
final trace = Trace.current(2);
final frames = trace.frames;
final callerFrame =
frames[1].location.contains('main') ? frames[2] : frames[1];
final filePath = callerFrame.uri.pathSegments.last;
final location = '$filePath:${callerFrame.line}';
final color = PrettyPrinter.defaultLevelColors[event.level]!;
final emoji = PrettyPrinter.defaultLevelEmojis[event.level]!;
if (event.level == Level.error) {
return _prettyPrinter.log(event); // I don't need the file name for errors since the stack trace will contain it. You can add it here if you like.
} else {
return [color('$emoji ${event.message} - $location')];
}
}
}
final Logger logger = Logger(
printer: CustomPrinter(methodCount: 20, errorMethodCount: 20),
);
I only wanted the file name. If you want the full path, change location to this: final location = '${callerFrame.uri.path}:${callerFrame.line}';
This is fairly hacky, so will explain: final callerFrame = frames[1].location.contains('main') ? frames[2] : frames[1];
If the logger.d
came directly from your codebase, the callerFrame
will be at frames[1]
, but if it was intercepted by your main file, E.g you have an exception handler in main.dart that calls logger.e
that catches what you didn't catch in your code base or you have debugPrint = (message, {wrapWidth}) {
which calls logger.d
in your main file, it will be at frames[2]
.
Nice one, Benji. I ended up with this, seems enough for my use case:
import 'package:logger/logger.dart';
import 'package:stack_trace/stack_trace.dart';
final logger = MyLogger();
class MyLogger extends Logger {
MyLogger() : super(printer: PrettyPrinter(errorMethodCount: 50));
@override
void log(Level level, message,
{DateTime? time, Object? error, StackTrace? stackTrace}) {
final currentLine = _currentLine();
message = [
if (currentLine != null) 'at: $currentLine',
message.toString(),
].join('\n');
super.log(level, message, time: time, error: error, stackTrace: stackTrace);
}
String? _currentLine() {
final trace = Trace.current(3);
return trace.frames.firstOrNull.toString();
}
}
To each log output, I'd like to see the line where the corresponding log statement is.
Before: ⛔ Error listening on stream
After (something like): ⛔ Error listening on stream [hello_world/my_logger.dart 58:5]
, where
hello_world/my_logger.dart 58:5
is where logger.e(...) call happened. Is it possible?