Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(495)

Unified Diff: utils/pub/log.dart

Issue 11470023: Add in basic logging system. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « utils/pub/command_help.dart ('k') | utils/pub/pub.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils/pub/log.dart
diff --git a/utils/pub/log.dart b/utils/pub/log.dart
new file mode 100644
index 0000000000000000000000000000000000000000..ca85037de33a37ac8d8660027f96e0cecea354e8
--- /dev/null
+++ b/utils/pub/log.dart
@@ -0,0 +1,217 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Message logging.
+library log;
+
+import 'dart:io';
+import 'io.dart';
+
+typedef LogFn(Level level, message);
+final Map<Level, LogFn> _loggers = new Map<Level, LogFn>();
+
+/// The list of recorded log messages. Will only be recorded if
+/// [recordTranscript()] is called.
+List<Entry> _transcript;
+
+/// An enum type for defining the different logging levels. By default, [ERROR]
+/// and [WARNING] messages are printed to sterr. [MESSAGE] messages are printed
+/// to stdout, and others are ignored.
+class Level {
+ /// An error occurred and an operation could not be completed. Usually shown
+ /// to the user on stderr.
+ static const ERROR = const Level._("ERR ");
+
+ /// Something unexpected happened, but the program was able to continue,
+ /// though possibly in a degraded fashion.
+ static const WARNING = const Level._("WARN");
+
+ /// A message intended specifically to be shown to the user.
+ static const MESSAGE = const Level._("MSG ");
+
+ /// Some interaction with the external world occurred, such as a network
+ /// operation, process spawning, or file IO.
+ static const IO = const Level._("IO ");
+
+ /// Fine-grained and verbose additional information. Can be used to provide
+ /// program state context for other logs (such as what pub was doing when an
+ /// IO operation occurred) or just more detail for an operation.
+ static const FINE = const Level._("FINE");
+
+ const Level._(this.name);
+ final String name;
+
+ String toString() => name;
+ int get hashCode => name.hashCode;
+}
+
+/// A single log entry.
+class Entry {
+ final Level level;
+ final String message;
+
+ Entry(this.level, this.message);
+}
+
+/// Logs [message] at [Level.ERROR].
+void error(message) => write(Level.ERROR, message);
+
+/// Logs [message] at [Level.WARNING].
+void warning(message) => write(Level.WARNING, message);
+
+/// Logs [message] at [Level.MESSAGE].
+void message(message) => write(Level.MESSAGE, message);
+
+/// Logs [message] at [Level.IO].
+void io(message) => write(Level.IO, message);
+
+/// Logs [message] at [Level.FINE].
+void fine(message) => write(Level.FINE, message);
+
+/// Logs [message] at [level].
+void write(Level level, message) {
+ if (_loggers.isEmpty) showNormal();
+
+ var logFn = _loggers[level];
+ if (logFn != null) logFn(level, message);
+
+ if (_transcript != null) {
+ _transcript.add(new Entry(level, '$message'));
+ }
+}
+
+/// Logs an asynchronous IO operation. Logs [startMessage] before the operation
+/// starts, then when [operation] completes, invokes [endMessage] with the
+/// completion value and logs the result of that. Returns a future that
+/// completes after the logging is done.
+///
+/// If [endMessage] is omitted, then logs "Begin [startMessage]" before the
+/// operation and "End [startMessage]" after it.
+Future ioAsync(String startMessage, Future operation,
+ [String endMessage(value)]) {
+ if (endMessage == null) {
+ io("Begin $startMessage.");
+ } else {
+ io(startMessage);
+ }
+
+ return operation.transform((result) {
+ if (endMessage == null) {
+ io("End $startMessage.");
+ } else {
+ io(endMessage(result));
+ }
+ return result;
+ });
+}
+
+/// Logs the spawning of an [executable] process with [arguments] at [IO]
+/// level.
+void process(String executable, List<String> arguments) {
+ io("Spawning $executable ${Strings.join(arguments, ' ')}");
+}
+
+/// Logs the results of running [executable].
+void processResult(String executable, PubProcessResult result) {
+ // Log it all as one message so that it shows up as a single unit in the logs.
+ var buffer = new StringBuffer();
+ buffer.add("Finished $executable. Exit code ${result.exitCode}.");
+
+ dumpOutput(String name, List<String> output) {
+ if (output.length == 0) {
+ buffer.add("Nothing output on $name.");
+ } else {
+ buffer.add("$name:");
+ var numLines = 0;
+ for (var line in output) {
+ if (++numLines > 1000) {
+ buffer.add('[${output.length - 1000}] more lines of output truncated...]');
nweiz 2012/12/07 21:47:06 Long line.
Bob Nystrom 2012/12/07 22:19:56 Done.
+ break;
+ }
+
+ buffer.add(line);
+ }
+ }
+ }
+
+ dumpOutput("stdout", result.stdout);
+ dumpOutput("stderr", result.stderr);
+
+ io(buffer.toString());
+}
+
+/// Enables recording of log entries.
+void recordTranscript() {
+ _transcript = <Entry>[];
+}
+
+/// If [recordTranscript()] was called, then prints the previously recorded log
+/// transcript to stderr.
+void dumpTranscript() {
+ if (_transcript == null) return;
+
+ stderr.writeString('---- Log transcript ----\n');
+ for (var entry in _transcript) {
+ _logToStderrWithLabel(entry.level, entry.message);
+ }
+ stderr.writeString('---- End log transcript ----\n');
+}
+
+/// Sets the verbosity to "normal", which shows errors, warnings, and messages.
+void showNormal() {
+ _loggers[Level.ERROR] = _logToStderr;
+ _loggers[Level.WARNING] = _logToStderr;
+ _loggers[Level.MESSAGE] = _logToStdout;
+ _loggers[Level.IO] = null;
+ _loggers[Level.FINE] = null;
+}
+
+/// Sets the verbosity to "io", which shows errors, warnings, messages, and IO
+/// event logs.
+void showIO() {
+ _loggers[Level.ERROR] = _logToStderrWithLabel;
+ _loggers[Level.WARNING] = _logToStderrWithLabel;
+ _loggers[Level.MESSAGE] = _logToStdoutWithLabel;
+ _loggers[Level.IO] = _logToStderrWithLabel;
+ _loggers[Level.FINE] = null;
+}
+
+/// Sets the verbosity to "all", which logs ALL the things.
+void showAll() {
+ _loggers[Level.ERROR] = _logToStderrWithLabel;
+ _loggers[Level.WARNING] = _logToStderrWithLabel;
+ _loggers[Level.MESSAGE] = _logToStdoutWithLabel;
+ _loggers[Level.IO] = _logToStderrWithLabel;
+ _loggers[Level.FINE] = _logToStderrWithLabel;
+}
+
+/// Log function that prints the message to stdout.
+void _logToStdout(Level level, message) {
+ print('$message');
+}
+
+/// Log function that prints the message to stdout with the level name.
+void _logToStdoutWithLabel(Level level, message) {
+ print(_splitAndPrefix(level, message));
+}
+
+/// Log function that prints the message to stderr.
+void _logToStderr(Level level, message) {
+ stderr.writeString('$message\n');
+}
+
+/// Log function that prints the message to stderr with the level name.
+void _logToStderrWithLabel(Level level, message) {
+ stderr.writeString(_splitAndPrefix(level, message));
+ stderr.writeString('\n');
+}
+
+/// Add the level prefix to the first line of [message] and prefix subsequent
+/// lines with "|".
+String _splitAndPrefix(Level level, message) {
+ // TODO(rnystrom): We're doing lots of splitting and joining in here. If that
+ // becomes a performance problem, we can optimize this to write directly to
+ // stdout/stderr a line at a time.
+ return "$level: ${Strings.join(message.toString().split('\n'), '\n | ')}";
+}
« no previous file with comments | « utils/pub/command_help.dart ('k') | utils/pub/pub.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698