0
# Message System
1
2
AutoRest Core provides a comprehensive event-driven messaging system for structured logging, error reporting, and multi-channel communication throughout the code generation process. This system enables detailed monitoring, debugging, and integration with external tools.
3
4
## Capabilities
5
6
### Message Structure
7
8
Core message interface for all communication within AutoRest.
9
10
```typescript { .api }
11
/**
12
* Represents a message generated during AutoRest processing
13
*/
14
interface Message {
15
/** The channel/severity level of the message */
16
Channel: Channel;
17
/** The main message text */
18
Text: string;
19
/** Message key for categorization (optional) */
20
Key?: Iterable<string>;
21
/** Additional details or context (optional) */
22
Details?: any;
23
/** Source location information (optional) */
24
Source?: Array<SourceLocation>;
25
/** Text range information (optional) */
26
Range?: Iterable<Range>;
27
/** Plugin that generated the message (optional) */
28
Plugin?: string;
29
/** Pre-formatted message text (optional) */
30
FormattedMessage?: string;
31
}
32
```
33
34
### Message Channels
35
36
Enumeration of all available message channels for categorizing messages by severity and type.
37
38
```typescript { .api }
39
/**
40
* Available message channels for categorizing messages
41
*/
42
enum Channel {
43
/** General information messages */
44
Information = "information",
45
/** Warning messages that don't stop processing */
46
Warning = "warning",
47
/** Error messages indicating processing failures */
48
Error = "error",
49
/** Debug messages for troubleshooting */
50
Debug = "debug",
51
/** Verbose output for detailed logging */
52
Verbose = "verbose",
53
/** Fatal errors that stop processing */
54
Fatal = "fatal",
55
/** Hints and suggestions for improvement */
56
Hint = "hint",
57
/** File-related messages */
58
File = "file",
59
/** Configuration-related messages */
60
Configuration = "configuration"
61
}
62
```
63
64
**Usage Examples:**
65
66
```typescript
67
import { AutoRest, Channel } from "@microsoft.azure/autorest-core";
68
69
const autorest = new AutoRest();
70
71
// Listen to all messages
72
autorest.Message.Subscribe((sender, message) => {
73
const timestamp = new Date().toISOString();
74
const prefix = `[${timestamp}] ${message.Channel.toUpperCase()}:`;
75
76
switch (message.Channel) {
77
case Channel.Error:
78
case Channel.Fatal:
79
console.error(`${prefix} ${message.Text}`);
80
if (message.Details) {
81
console.error("Details:", message.Details);
82
}
83
break;
84
85
case Channel.Warning:
86
console.warn(`${prefix} ${message.Text}`);
87
break;
88
89
case Channel.Information:
90
console.log(`${prefix} ${message.Text}`);
91
break;
92
93
case Channel.Debug:
94
case Channel.Verbose:
95
if (process.env.DEBUG) {
96
console.log(`${prefix} ${message.Text}`);
97
}
98
break;
99
100
case Channel.Hint:
101
console.log(`π‘ ${prefix} ${message.Text}`);
102
break;
103
104
case Channel.File:
105
console.log(`π ${prefix} ${message.Text}`);
106
break;
107
108
case Channel.Configuration:
109
console.log(`βοΈ ${prefix} ${message.Text}`);
110
break;
111
}
112
113
// Log source location if available
114
if (message.Source && message.Source.length > 0) {
115
message.Source.forEach(source => {
116
console.log(` at ${source.document}:${source.Position.line}:${source.Position.column}`);
117
});
118
}
119
});
120
```
121
122
### Artifact Information
123
124
Interface for generated file artifacts.
125
126
```typescript { .api }
127
/**
128
* Represents a generated file artifact
129
*/
130
interface Artifact {
131
/** URI of the generated file */
132
uri: string;
133
/** Type/category of the generated file */
134
type: string;
135
/** Content of the generated file */
136
content: string;
137
}
138
139
/**
140
* Message specific to file artifacts with source mapping information
141
*/
142
interface ArtifactMessage extends Message {
143
/** Artifact details with optional source map */
144
Details: Artifact & {
145
/** Source map for generated content (optional) */
146
sourceMap?: Mappings | RawSourceMap
147
};
148
}
149
```
150
151
**Usage Examples:**
152
153
```typescript
154
import { AutoRest } from "@microsoft.azure/autorest-core";
155
156
const autorest = new AutoRest();
157
158
// Track generated files
159
const generatedFiles: Map<string, Artifact> = new Map();
160
161
autorest.GeneratedFile.Subscribe((sender, artifact) => {
162
generatedFiles.set(artifact.uri, artifact);
163
164
console.log(`Generated ${artifact.type}: ${artifact.uri}`);
165
console.log(`Content size: ${artifact.content.length} bytes`);
166
167
// Save file if needed
168
if (artifact.type === "client") {
169
const fileName = artifact.uri.split('/').pop();
170
console.log(`Main client file: ${fileName}`);
171
}
172
});
173
174
// Monitor all outputs after processing
175
autorest.Finished.Subscribe((sender, result) => {
176
console.log(`\nGeneration Summary:`);
177
console.log(`Total files generated: ${generatedFiles.size}`);
178
179
const typeCount = new Map<string, number>();
180
generatedFiles.forEach(artifact => {
181
const count = typeCount.get(artifact.type) || 0;
182
typeCount.set(artifact.type, count + 1);
183
});
184
185
typeCount.forEach((count, type) => {
186
console.log(` ${type}: ${count} files`);
187
});
188
});
189
```
190
191
### Source Location Information
192
193
Interfaces for tracking source locations and ranges in messages.
194
195
```typescript { .api }
196
/**
197
* Represents a location in a source document
198
*/
199
interface SourceLocation {
200
/** The source document identifier */
201
document: string;
202
/** Enhanced position within the document with additional metadata */
203
Position: EnhancedPosition;
204
}
205
206
/**
207
* Represents a text range in a document
208
*/
209
interface Range {
210
/** The source document identifier */
211
document: string;
212
/** Start position of the range */
213
start: Position;
214
/** End position of the range */
215
end: Position;
216
}
217
218
/**
219
* Represents a position in a text document (from source-map library)
220
*/
221
interface Position {
222
/** Line number (1-based) */
223
line: number;
224
/** Column number (0-based) */
225
column: number;
226
}
227
228
/**
229
* Enhanced position with additional metadata
230
*/
231
type EnhancedPosition = Position & {
232
/** JSONPath to the element */
233
path?: JsonPath;
234
/** Length of the element */
235
length?: number;
236
/** Offset to the value within the element */
237
valueOffset?: number;
238
/** Length of the value */
239
valueLength?: number;
240
}
241
```
242
243
**Usage Example:**
244
245
```typescript
246
// Example of how source location information appears in messages
247
autorest.Message.Subscribe((sender, message) => {
248
if (message.Channel === Channel.Error && message.Source) {
249
console.error(`Error: ${message.Text}`);
250
251
message.Source.forEach(location => {
252
console.error(` in ${location.document} at line ${location.Position.line}, column ${location.Position.column}`);
253
});
254
255
if (message.Range) {
256
for (const range of message.Range) {
257
console.error(` Range: ${range.start.line}:${range.start.column} - ${range.end.line}:${range.end.column}`);
258
}
259
}
260
}
261
});
262
```
263
264
## Message Filtering and Processing
265
266
### Custom Message Handlers
267
268
You can create sophisticated message handling logic:
269
270
```typescript
271
import { AutoRest, Channel, Message } from "@microsoft.azure/autorest-core";
272
273
class MessageProcessor {
274
private errorCount = 0;
275
private warningCount = 0;
276
private debugMessages: Message[] = [];
277
278
constructor(private autorest: AutoRest) {
279
this.autorest.Message.Subscribe(this.handleMessage.bind(this));
280
}
281
282
private handleMessage(sender: AutoRest, message: Message): void {
283
// Count messages by type
284
switch (message.Channel) {
285
case Channel.Error:
286
case Channel.Fatal:
287
this.errorCount++;
288
this.logError(message);
289
break;
290
case Channel.Warning:
291
this.warningCount++;
292
this.logWarning(message);
293
break;
294
case Channel.Debug:
295
this.debugMessages.push(message);
296
break;
297
}
298
}
299
300
private logError(message: Message): void {
301
console.error(`β Error: ${message.Text}`);
302
if (message.Details) {
303
console.error("Details:", JSON.stringify(message.Details, null, 2));
304
}
305
}
306
307
private logWarning(message: Message): void {
308
console.warn(`β οΈ Warning: ${message.Text}`);
309
}
310
311
getSummary(): { errors: number; warnings: number; debugCount: number } {
312
return {
313
errors: this.errorCount,
314
warnings: this.warningCount,
315
debugCount: this.debugMessages.length
316
};
317
}
318
319
exportDebugLog(): string {
320
return this.debugMessages
321
.map(msg => `[${msg.Channel}] ${msg.Text}`)
322
.join('\n');
323
}
324
}
325
326
// Usage
327
const autorest = new AutoRest();
328
const processor = new MessageProcessor(autorest);
329
330
// ... configure and run autorest ...
331
332
const summary = processor.getSummary();
333
console.log(`Processing completed with ${summary.errors} errors and ${summary.warnings} warnings`);
334
```
335
336
### Integration with External Tools
337
338
The message system can be integrated with external logging and monitoring tools:
339
340
```typescript
341
import { AutoRest, Channel, Message } from "@microsoft.azure/autorest-core";
342
343
interface LogEntry {
344
timestamp: string;
345
level: string;
346
message: string;
347
source?: string;
348
details?: any;
349
}
350
351
class StructuredLogger {
352
private logs: LogEntry[] = [];
353
354
constructor(autorest: AutoRest) {
355
autorest.Message.Subscribe(this.logMessage.bind(this));
356
}
357
358
private logMessage(sender: AutoRest, message: Message): void {
359
const entry: LogEntry = {
360
timestamp: new Date().toISOString(),
361
level: this.mapChannelToLevel(message.Channel),
362
message: message.Text
363
};
364
365
if (message.Source && message.Source.length > 0) {
366
entry.source = `${message.Source[0].document}:${message.Source[0].Position.line}`;
367
}
368
369
if (message.Details) {
370
entry.details = message.Details;
371
}
372
373
this.logs.push(entry);
374
375
// Send to external logging service
376
this.sendToExternalLogger(entry);
377
}
378
379
private mapChannelToLevel(channel: Channel): string {
380
switch (channel) {
381
case Channel.Fatal:
382
case Channel.Error:
383
return "error";
384
case Channel.Warning:
385
return "warn";
386
case Channel.Information:
387
return "info";
388
case Channel.Debug:
389
case Channel.Verbose:
390
return "debug";
391
default:
392
return "info";
393
}
394
}
395
396
private sendToExternalLogger(entry: LogEntry): void {
397
// Integration with external logging service
398
// e.g., send to Elasticsearch, CloudWatch, etc.
399
}
400
401
exportLogs(): LogEntry[] {
402
return [...this.logs];
403
}
404
}
405
```