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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « utils/pub/command_help.dart ('k') | utils/pub/pub.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Message logging.
6 library log;
7
8 import 'dart:io';
9 import 'io.dart';
10
11 typedef LogFn(Level level, message);
12 final Map<Level, LogFn> _loggers = new Map<Level, LogFn>();
13
14 /// The list of recorded log messages. Will only be recorded if
15 /// [recordTranscript()] is called.
16 List<Entry> _transcript;
17
18 /// An enum type for defining the different logging levels. By default, [ERROR]
19 /// and [WARNING] messages are printed to sterr. [MESSAGE] messages are printed
20 /// to stdout, and others are ignored.
21 class Level {
22 /// An error occurred and an operation could not be completed. Usually shown
23 /// to the user on stderr.
24 static const ERROR = const Level._("ERR ");
25
26 /// Something unexpected happened, but the program was able to continue,
27 /// though possibly in a degraded fashion.
28 static const WARNING = const Level._("WARN");
29
30 /// A message intended specifically to be shown to the user.
31 static const MESSAGE = const Level._("MSG ");
32
33 /// Some interaction with the external world occurred, such as a network
34 /// operation, process spawning, or file IO.
35 static const IO = const Level._("IO ");
36
37 /// Fine-grained and verbose additional information. Can be used to provide
38 /// program state context for other logs (such as what pub was doing when an
39 /// IO operation occurred) or just more detail for an operation.
40 static const FINE = const Level._("FINE");
41
42 const Level._(this.name);
43 final String name;
44
45 String toString() => name;
46 int get hashCode => name.hashCode;
47 }
48
49 /// A single log entry.
50 class Entry {
51 final Level level;
52 final String message;
53
54 Entry(this.level, this.message);
55 }
56
57 /// Logs [message] at [Level.ERROR].
58 void error(message) => write(Level.ERROR, message);
59
60 /// Logs [message] at [Level.WARNING].
61 void warning(message) => write(Level.WARNING, message);
62
63 /// Logs [message] at [Level.MESSAGE].
64 void message(message) => write(Level.MESSAGE, message);
65
66 /// Logs [message] at [Level.IO].
67 void io(message) => write(Level.IO, message);
68
69 /// Logs [message] at [Level.FINE].
70 void fine(message) => write(Level.FINE, message);
71
72 /// Logs [message] at [level].
73 void write(Level level, message) {
74 if (_loggers.isEmpty) showNormal();
75
76 var logFn = _loggers[level];
77 if (logFn != null) logFn(level, message);
78
79 if (_transcript != null) {
80 _transcript.add(new Entry(level, '$message'));
81 }
82 }
83
84 /// Logs an asynchronous IO operation. Logs [startMessage] before the operation
85 /// starts, then when [operation] completes, invokes [endMessage] with the
86 /// completion value and logs the result of that. Returns a future that
87 /// completes after the logging is done.
88 ///
89 /// If [endMessage] is omitted, then logs "Begin [startMessage]" before the
90 /// operation and "End [startMessage]" after it.
91 Future ioAsync(String startMessage, Future operation,
92 [String endMessage(value)]) {
93 if (endMessage == null) {
94 io("Begin $startMessage.");
95 } else {
96 io(startMessage);
97 }
98
99 return operation.transform((result) {
100 if (endMessage == null) {
101 io("End $startMessage.");
102 } else {
103 io(endMessage(result));
104 }
105 return result;
106 });
107 }
108
109 /// Logs the spawning of an [executable] process with [arguments] at [IO]
110 /// level.
111 void process(String executable, List<String> arguments) {
112 io("Spawning $executable ${Strings.join(arguments, ' ')}");
113 }
114
115 /// Logs the results of running [executable].
116 void processResult(String executable, PubProcessResult result) {
117 // Log it all as one message so that it shows up as a single unit in the logs.
118 var buffer = new StringBuffer();
119 buffer.add("Finished $executable. Exit code ${result.exitCode}.");
120
121 dumpOutput(String name, List<String> output) {
122 if (output.length == 0) {
123 buffer.add("Nothing output on $name.");
124 } else {
125 buffer.add("$name:");
126 var numLines = 0;
127 for (var line in output) {
128 if (++numLines > 1000) {
129 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.
130 break;
131 }
132
133 buffer.add(line);
134 }
135 }
136 }
137
138 dumpOutput("stdout", result.stdout);
139 dumpOutput("stderr", result.stderr);
140
141 io(buffer.toString());
142 }
143
144 /// Enables recording of log entries.
145 void recordTranscript() {
146 _transcript = <Entry>[];
147 }
148
149 /// If [recordTranscript()] was called, then prints the previously recorded log
150 /// transcript to stderr.
151 void dumpTranscript() {
152 if (_transcript == null) return;
153
154 stderr.writeString('---- Log transcript ----\n');
155 for (var entry in _transcript) {
156 _logToStderrWithLabel(entry.level, entry.message);
157 }
158 stderr.writeString('---- End log transcript ----\n');
159 }
160
161 /// Sets the verbosity to "normal", which shows errors, warnings, and messages.
162 void showNormal() {
163 _loggers[Level.ERROR] = _logToStderr;
164 _loggers[Level.WARNING] = _logToStderr;
165 _loggers[Level.MESSAGE] = _logToStdout;
166 _loggers[Level.IO] = null;
167 _loggers[Level.FINE] = null;
168 }
169
170 /// Sets the verbosity to "io", which shows errors, warnings, messages, and IO
171 /// event logs.
172 void showIO() {
173 _loggers[Level.ERROR] = _logToStderrWithLabel;
174 _loggers[Level.WARNING] = _logToStderrWithLabel;
175 _loggers[Level.MESSAGE] = _logToStdoutWithLabel;
176 _loggers[Level.IO] = _logToStderrWithLabel;
177 _loggers[Level.FINE] = null;
178 }
179
180 /// Sets the verbosity to "all", which logs ALL the things.
181 void showAll() {
182 _loggers[Level.ERROR] = _logToStderrWithLabel;
183 _loggers[Level.WARNING] = _logToStderrWithLabel;
184 _loggers[Level.MESSAGE] = _logToStdoutWithLabel;
185 _loggers[Level.IO] = _logToStderrWithLabel;
186 _loggers[Level.FINE] = _logToStderrWithLabel;
187 }
188
189 /// Log function that prints the message to stdout.
190 void _logToStdout(Level level, message) {
191 print('$message');
192 }
193
194 /// Log function that prints the message to stdout with the level name.
195 void _logToStdoutWithLabel(Level level, message) {
196 print(_splitAndPrefix(level, message));
197 }
198
199 /// Log function that prints the message to stderr.
200 void _logToStderr(Level level, message) {
201 stderr.writeString('$message\n');
202 }
203
204 /// Log function that prints the message to stderr with the level name.
205 void _logToStderrWithLabel(Level level, message) {
206 stderr.writeString(_splitAndPrefix(level, message));
207 stderr.writeString('\n');
208 }
209
210 /// Add the level prefix to the first line of [message] and prefix subsequent
211 /// lines with "|".
212 String _splitAndPrefix(Level level, message) {
213 // TODO(rnystrom): We're doing lots of splitting and joining in here. If that
214 // becomes a performance problem, we can optimize this to write directly to
215 // stdout/stderr a line at a time.
216 return "$level: ${Strings.join(message.toString().split('\n'), '\n | ')}";
217 }
OLDNEW
« 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