en-us/about_psf_message.help.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
TOPIC
    about_psf_message
     
SHORT DESCRIPTION
    Explains the PSFrameworks message & logging component
     
LONG DESCRIPTION
    #-------------------------------------------------------------------------#
    # Component Commands #
    #-------------------------------------------------------------------------#
 
    - Get-PSFMessage
    - Write-PSFHostColor
    - Write-PSFMessage
     
     
    #-------------------------------------------------------------------------#
    # Table of Contents #
    #-------------------------------------------------------------------------#
     
    - Introduction
    - The message architecture
    - Messaging Configuration
    - Advanced messaging functionality
    - The logging system
    -- The logging system's configuration
    - Logging: File System
    -- Functionality
    -- Configuration
     
     
    #-------------------------------------------------------------------------#
    # Introduction #
    #-------------------------------------------------------------------------#
     
    We often write messages in a module. Sometimes some verbose messages for
    debugging purposes, sometimes an info for the user and sometimes even a
    warning that something seriously went wrong.
    Also often it becomes necessary or desirable to create logfiles. Logging
    helps a lot with figuring out what went wrong, but often we only enable it
    after something broke, because those logs aren't much use when everything
    works as desired and logs nobody reads are of little use, right?
    Especially when you have to take care of those logs ...
     
    The messaging system unifies the entire process into a single command:
     
      Write-PSFMessage
     
    By the simple act of using this command, not only do you write the message
    to the channels chosen, but also add them to the logging system. That system
    will not only create log files, but also take care to clean up old or too
    large files.
    Example usage:
     
      Write-PSFMessage -Level Host -Message "Writing something the user sees"
     
    There are three basic levels available:
    - Host: Visible to the user by default
    - Verbose: Written via Write-Verbose, not visible to the user by default
    - Warning: Writes a warning message.
     
    It will automatically add a timestamp and the function that was calling it.
    While details on how to configure the system are covered in subsequent
    chapters, the logging path can be read with this command:
     
      Get-PSFConfigValue -FullName "psframework.logging.filesystem.logpath"
     
    However all recently written messages can also be found still in memory, by
    running:
     
      Get-PSFMessage
     
    That command can also show any errors that were logged:
     
      Get-PSFMessage -Errors
     
     
    #-------------------------------------------------------------------------#
    # The message architecture #
    #-------------------------------------------------------------------------#
     
    The PowerShell system has multiple streams where information can go, in
    addition to straight to the host. The Verbose one is probably the best
    known one, but there are more:
    - Information
    - Verbose
    - Debug
    - Warning
    - Error
    The parameter '-Level' controls, how this message will be written. Each
    level has a numeric representation (a level). On the other hand, what level
    is to which stream is controlled by the configuration system. Each level and
    the <default> settings are shown below:
     
    Information:
      Critical (1), Important / Output / Host (2), Significant (3)
      This is what is usually shown to the end user, printed to the screen.
      Starting PowerShell v5, Write-Host is also written to the information
      stream, hence it is also available on that.
     
    Verbose:
      VeryVerbose (4), Verbose (5), SomewhatVerbose (6)
      Verbose messages are shown when a command is run with the automatic
      '-Verbose' parameter. They generally help in showing the current progress.
       
    Debug:
      Critical (1), Important / Output / Host (2), Significant (3),
      VeryVerbose (4), Verbose (5), SomewhatVerbose (6), System (7), Debug (8),
      InternalComment (9), Warning (666)
      Debug-only message (level range 7-9 by default) are generally designed to
      provide debugging information to the developer and are of lesser interest
      to regular users.
     
    Warning:
      Warning (666)
      Warnings signal that something went wrong. They are a way to signal a user
      that something went wrong without turning them off with too much confusing
      information as red exceptions tend to. Warnings cannot seriously be turned
      off short of:
      - Globally disabling verbose output
      - Enabling Exception and specifying an exception.
        (More details on that in "Advanced messaging functionality")
     
    Error:
      Errors are the system's way to tell other code something went wrong. Those
      exceptions are great for debugging but tend to discourage users. There is
      no Level for exceptions. You write to the error stream by passing the
      ErrorRecord(s) you caught to the '-ErrorRecord' parameter.
     
    Once the streams to communicate with have been settled, the command will
    then pass it to the logging system. For more details on the logging system
    see below in the chapter "The logging system"
     
     
    #-------------------------------------------------------------------------#
    # Messaging Configuration #
    #-------------------------------------------------------------------------#
     
    This section assumes that general understanding of the configuration system
    has already been achieved. Run this to read up on that component:
      Get-Help about_psf_configuration
       
    The messaging system supports several settings that control its behavior:
     
    'PSFramework.message.info.minimum' (Default: 1)
    'PSFramework.message.info.maximum' (Default: 3)
    The level range at which messages are sent to host/information
    Set to 0 to disable.
     
    'PSFramework.message.verbose.minimum' (Default: 4)
    'PSFramework.message.verbose.maximum' (Default: 6)
    The level range at which messages are sent to verbose
    Set to 0 to disable.
     
    'PSFramework.message.debug.minimum' (Default: 1)
    'PSFramework.message.debug.maximum' (Default: 9)
    The level range at which messages are sent to debug
    Set to 0 to disable.
     
    'PSFramework.message.info.color' (Default: Cyan)
    The color regular messages are printed to the host.
     
    'PSFramework.message.info.color.emphasis' (Default: Green)
    The color emphasized text in messages is printed to the host.
     
    'PSFramework.message.info.color.subtle' (Default: Gray)
    The color subtle text in messages is printed to the host.
     
    'PSFramework.developer.mode.enable' (Default: False)
    The developer mode is designed to help in debugging commands that implement
    the PSFramework. All messages are shown and messages contain a lot more meta
    information than usual. Messages that are shown that would be invisible to
    regular users are highlighted in a different color.
     
    'PSFramework.message.developercolor' (Default: Gray)
    The color messages are shown in, that would not have been shown, but are
    being shown in developer mode (which shows all messages, see above).
     
    'PSFramework.message.consoleoutput.disable' (Default: False)
    This is the master switch that will disable all Information Level output,
    as well as all warnings. Basically, this enables silent mode that will
    suppress all output to screen except for uncaught exceptions.
     
     
    #-------------------------------------------------------------------------#
    # Advanced messaging functionality #
    #-------------------------------------------------------------------------#
     
    After having scratched the surface of Write-PSFMessage, there's more to be
    had. From the more advanced parameters until debugging with Get-PSFMessage
     
    # Parameters
    #--------------------------------------------------------------------------
     
    Beyond the two basic parameters '-Level' and '-Message' there are quite a
    few additional parameters, allowing access to more complex features:
     
    -FunctionName
    This parameter automatically detects the name of the function calling it, so
    in most cases it is not necessary to specify it. However, if you have an
    intermediary function and want to pass on the original function name, here
    you can explicitly choose the name.
    This name becomes part of the log and thus useful for troubleshooting.
     
    -ErrorRecord
    This allows you to attach one or several exceptions to the message written.
    When you do, pass the entire errorrecord(s), not merely the exception object
    Using this parameter has several consequences:
    - It will add an error entry in the in-memory log
    - It will add an error entry in the logging queue
    - It will automatically add the message of the first exception to the
      message written (if it isn't there yet)
    - It will write the exception to the error stream
    - It will add the error record to the $error variable
    A very simple example on how to use it:
     
      try { $null.ToString() }
      catch { Write-PSFMessage -Level Warning -ErrorRecord $_ -Message "Failed to do the impossible!" }
     
    What this will NOT do by itself is print the error to screen. In case of
    need there is the full error object still in memory and logged to xml
     
    -EnableException
    Setting this parameter to $true will cause the function to write the
    exception more publicly to the screen (just passing -ErrorRecord will not do
    so). By itself of not critical value, it conforms itself to the Flow Control
    components behavior, allowing for uniformity in handling exceptions.
    It is a boolean type, since it is designed to be passed through by the
    calling function (The calling function would implement a switch parameter
    named '-EnableException' and pass that value straight through to
    Write-PSFMessage and Stop-PSFFunction.
     
    -Target
    Adds the object that was being processed to the message. This has no effect
    on any messages shown on the screen, however will be part of the in-memory
    log as well as log file. NEVER ADD SENSITIVE DATA such as clear Passwords.
    This allows following an object in the logs as it passes through commands,
    enabling object-based tracing.
    Also handy to extract the failing input when processing many items, only
    some of which failed.
     
    -Once
    Write a specific message once only. This allows easily sending warnings such
    as deprecation warnings without spamming the user in them.
    This parameter must be passed a string in order to uniquely identify it. It
    also uses the function name, so it must only be unique per function.
    Example:
       
      Write-PSFMessage -Level Warning -Once "1" -Message "The parameter '-Example' has been deprecated and will be removed in future versions. Its functionality has become part of the baseline."
     
     
    # Level Concept
    #--------------------------------------------------------------------------
     
    The levels were introduced, in order to be able to more smoothly control
    verbosity levels. For a simple implementation, levels 2 and 5 more than
    suffice. However when it comes to user comfort, the user is able to choose
    the level at which he will be directly informed, at which point a scaling
    use of levels allows the user the level of detail he is confronted with.
     
    Example:
    A function accepts computers as input and for each does a complex procedure
    consisting of 3 major steps and lots of sub-steps. At this point the message
    distribution could be like this:
    Starting to process computer n: Level 4
    - Starting Step 1: Level 5
    -- Substep X: Level 6
    -- Substep Y: Level 6
    -- Substep Z: Level 6
    - Starting Step 2: Level 5
    -- Substep X: Level 6
    -- Substep Y: Level 6
    -- Substep Z: Level 6
    - Starting Step 2: Level 5
    -- Substep X: Level 6
    -- Substep Y: Level 6
    -- Substep Z: Level 6
    By default, the user will not see a thing while this function proceeds. If
    he increases the maximum level for information messages to 4 however:
     
      Set-PSFConfig -Name 'psframework.message.info.maximum' -Value 4
     
    He will now be shown the computer that is currently being processed. Still
    impatient, he then increases it to '5' and will suddenly see each of the
    main steps being logged to screen.
     
    The level will also be printed to the log, allowing another level of
    filtering. If the message structure as shown is respected, the log itself
    allows tracing the rough architecture if the function using Write-PSFMessage
     
     
    # Troubleshooting with Get-PSFMessage
    #--------------------------------------------------------------------------
     
    Get-PSFMessage will return the messages written straight from memory, it
    doesn't touch the logfiles itself. However, what it allows is filtering for
    information, since the logged entries contain a lot more meta-data than just
    the line of text.
    By filtering by the TargetObject property, it becomes possible to search for
    all messages (shown or not shown. They ALL are logged and available)
    relating to an object that was processed (Assuming the above described
    '-Target' parameter was used and properly filled).
    Of course, it is also possible to filter by function that wrote the message.
     
    Combining the two, it becomes fairly simple to retrieve all objects passed
    to the implementing function whose processing failed.
     
    Get-PSFMessage also contains a parameter '-Errors', which allows retrieving
    the logged exceptions (which will also contain information such as function,
    timestamp and targetobject). This deals with one of the steadily escalating
    issues that even with try/catch, errors get added to the $error variable,
    which has led to that variable having lost significant usefulness in
    troubleshooting non-trivial issues.
     
     
    # Bringing color to your screen
    #--------------------------------------------------------------------------
     
    Messages can provide write information for the user to see on the screen.
    However, information is easier to interpret if the essentials can be read by
    scanning, rather than detail reading. One of the boost helps with that is
    color. The human eye is drawn to these words that have a different color.
     
    All messages in the PSFramework support a html-style tag syntax in order to
    do inline color definition. Example:
     
      Write-PSFMessage -Level VeryVerbose -Message "Connecting to <c='em'>$computer</c>"
     
    This will print the specified line with color highlighting IF the user has
    his maximum information level to 4 or higher. The color tags are stripped
    from the message before being logged, so the logs or not impaired by them.
     
    The following colors are supported:
    - All legal console colors
    - em: Emphasis. The color configured under
           'PSFramework.message.info.color.emphasis'
    - sub: Subtle. The color configured under
           'PSFramework.message.info.color.subtle'
    Warning: Generally, it is recommended to restrict yourself to the specially
    configured colors 'em' and 'sub'. While static colors are supported, console
    color layouts may vary and what looks good for one user may not look good
    for the other. By using the configuration system, it becomes possible to
    give a user a choice in the color scheme.
     
    Illegal colors will be stripped without comment.
     
    For the purpose of building menus or head messages (which arguably aren't
    messages, since they do not contain information that needs to be logged),
    there is another command available:
     
      Write-PSFHostColor
     
    Which is basically the function used by Write-PSFMessage for its final
    colorful output.
     
     
    #-------------------------------------------------------------------------#
    # The logging system #
    #-------------------------------------------------------------------------#
     
    The logging system consists of the following components:
    - The in-memory queue
    - The logging queue
    - The logging script
     
    | The in-memory queue |
    #---------------------#
    All messages are kept in a queue in memory. It is self-limiting in that once
    its capacity has been exceeded, the oldest entry will be removed.
    The same hodls true for the exceptions that are logged.
    All messages and exceptions are tagged by runspace ID, when parallel
    processing, parallel runspaces log to the same queues. This allows
    troubleshooting not only the primary runspace but all of them. Keeping the
    runspace ID allows filtering by runspace.
    This is the information retrieved by the Get-PSFMessage function.
     
    | The logging queue |
    #--------------------#
    All messages and exceptions are also added to a set of queues that are
    collected by the logging script. These too have a (more generous) maximum
    capacity to prevent memory flood.
    These queues should never accumulate much data as the logging script should
    collect them frequently.
     
    | The logging script |
    #--------------------#
    The logging script gathers the info from the logging queue and logs them.
    Currently, only the filesystem logging is implemented, however additional
    logging providers will soon become available, providing a wider choice of
    logging options. Filesystem however will remain the default option.
    The script is operated by the modules own runspace component and can be
    controlled using its functions.
     
     
    # The logging system's configuration
    #--------------------------------------------------------------------------
     
    <Content Pending>
     
     
    #-------------------------------------------------------------------------#
    # Logging: File System #
    #-------------------------------------------------------------------------#
     
    <Content Pending>
     
     
    # Functionality
    #--------------------------------------------------------------------------
     
    <Content Pending>
     
     
    # Configuration
    #--------------------------------------------------------------------------
     
    <Content Pending>
     
     
KEYWORDS
    psframework message